Search code examples
androidlistxamarin.androidandroid-viewpagerobservablecollection

How much memory efficient is list of imageviews


i am trying to make a imagevideoslider in xamarin.android, I was having some runtime view deletion and updation issues like findviewwithtag returning null and not view not getting deleted properly because of which after searching internet i got the idea from the answer of this thread to make a list of all views

dynamically add and remove view to viewpager

now suppose i have a 1000 list/observablecollection of imageviews or videoviews or mix. How much memory efficient is this approach? is it a bad practice?

e.g. i have a list of java.lang.object

 private ObservableCollection<Java.Lang.Object> _views = new ObservableCollection<Java.Lang.Object>();

this code is called everytime a new dynamic item is added in list

        View view = new View(_context);
        if (con.MediaType.ToLower().Contains(Common.TYPE_IMAGE)) 
         //MediaType.Image
        {
            view = new ImageView(_context);

            ((Activity)_context).RunOnUiThread(() =>
            {
                SetScaleType(ref view, con.ScaleType);
                try
                {
                    //implement ifileprovider
                    ((ImageView)view).SetImageURI(Uri.Parse(con.LocalPath));
                }
                catch (Exception ex)
                {
                }
            });
        }
        _views.add(view);

instantiate item method

    public override Object InstantiateItem(ViewGroup container, int position)
    {
        try
        {
            ((Activity)_context).RunOnUiThread(() =>
            {
                container.AddView((View)_views[position], 0);
                if (position == 0)
                {
                    OnPageSelected(0);
                }
            });
        }
        catch (Exception ex)
        {

        }
        return _views[position];
    }

destroyitem method

    public override void DestroyItem(ViewGroup container, int position, 
    Object @object)
    {
        try
        {
            ((Activity)_context).RunOnUiThread(() =>
            {
                View view = (View)@object;
                ((ViewPager)container).RemoveView(view);
                view = null;
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            });
        }
        catch (Exception ex)
        {
        }
    }

again! is it a bad approach to keep a list of all views in your code then refer views from that list?


Solution

  • It's a bad approach to keep all your views in an ObservableCollection. You should think about the problem if you have 10000 views or 100000 views? The system will kill the app if it receives memory warning.

    From the RecyclerView document, RecyclerView offers two compelling features::

    It has a flexible architecture that lets you modify its behavior by plugging in your preferred components.

    It is efficient with large collections because it reuses item views and requires the use of view holders to cache view references.

    The RecyclerView will reuse the view by default and you do not need to create so many views at run time.

    I was having some runtime view deletion and updation issues like findviewwithtag returning null and not view not getting deleted properly

    The right way is load the view when needed instead of loading them at the same time. Add the data of Views in the ObservableCollection, and modify the data in the list instead find/modify the views. After change the data, then refresh the RecycleView.

    For example, if you want to remove a view, you can remove the corresponding data in the ObservableCollection and then refresh the RecycleView, the corresponding view will also be removed.