duckduckgo
duckduckgo

Reputation: 1295

ViewPager utlizing single instance of view

This is a subjective question, is it possible to have the pager adaptor return the same instance of view which first got inflated from xml file (inside my custom Fragment), and because my views are very expensive and do not change except in few regions, I am trying to reuse it?

I tried to create a static member inside my Fragment class and return it if it is not already set, but it does not work, is it against the Fragment life-cycle? well I am ok with Fragment getting garbage collected but I need my view object remain there, is it possible at all?

Or should I add this view in activity with visibility=gone and return it by changing visibility?

Upvotes: 0

Views: 130

Answers (1)

Budius
Budius

Reputation: 39836

Yes it is possible, but probably not for fragments. Fragments you have to let them do their life-cycle thing and properly respect it.

But I'm pretty sure you'll be able to achieve view-recycling by using common View instead.

I'll show you some key parts as an example of what I'm using on my app and you can further developer from it to properly suit your needs.

Remember that is NOT a complete code, but should get you started.

public class ViewsAdapter extends PagerAdapter {

   // Here we gonna save items to be recycled
   private WeakHashMap<String, View> recycling
      = new WeakHashMap<String, View>();

   @Override
   public Object instantiateItem(ViewGroup container, int position) {
      // here you must return a valid initialised view

      View view;

      String[] keys = new String[recycling.size()];
      keys = recycling.keySet().toArray(keys);

      for (String key : keys) {
         View recycledView = recycling.get(key);
         if (recycledView == null) {
            // remove dead elements
            recycling.remove(key);
         } else if (img.getParent() == null) {
            // remove this object from recycling
            recycling.remove(recycledView);
            view = recycledView;
         }
      }

      // create new if necessary
      if (view == null)
         view = // inflate your view here

      // do any `position` based setup
      view.setPosition(position); // for example

      // add to the container
      container.addView(view, 0);

      return view;
   }

   @Override
   public void destroyItem(ViewGroup container, int position, Object object) {
      View view = (View) object;
      // cancel any possible running operation on that view
      view.cancelLoading(); // for example
      // remove from container
      container.removeView(View);
      // recycle
      recycling.put(Long.toString(random.nextLong() + System.currentTimeMillis()), View);
   }

   @Override
   public int getItemPosition(Object object) {
      return POSITION_NONE;
   }

   @Override
   public boolean isViewFromObject(View view, Object object) {
      return view.equals(object);
   }

}

ps.: side note. Reading through this code I'm pretty sure you can improve it by using some type of queue instead of a WeakHashMap, maybe a ArrayDeque.

Upvotes: 1

Related Questions