3

I have created a custom class extending PagerAdapterthat represents my adapter to a ViewPager in which I slide through Views (not Fragments).

What my problem really is, is that I don't know how to get the current View that I have add to the adapter earlier so that I can follow a certain procedure with it.

The PagerAdapter only provides instantiateItem(ViewGroup container, int position) method that returns an Object and with my implementation, it returns a View.

Is this the right method to call to get the View in the current position? And if Yes, what I pass as a container argument?

Thank you in advance!

References:

SequenceAdapter.java

public class SequenceAdapter extends PagerAdapter {

private List<View> mList;

public SequenceAdapter(){
    this.mList = new ArrayList<>();
}

public void add(View viewGroup){
    mList.add(mList.size(), viewGroup);
    notifyDataSetChanged();
}

@Override
public int getCount() {
    return mList.size();
}

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

@Override
public Object instantiateItem(ViewGroup container, int position) {
    View view = mList.get(position);
    container.addView(view, position);
    return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((View) object);
}

@Override
public CharSequence getPageTitle(int position) {
    return null;
}

1 Answers1

0

Your PagerAdapter subclass is modeling the views required by the ViewPager, so similar to a ListView, you call notifyDataSetChanged() on the adapter.

Here's where it gets weird, though: The ViewPager will then ask your adapter where all the current pages go. This is handled with the override to getItemPosition(). Returning POSITION_NONE will tell the ViewPager that the view at that page index is no longer valid, after which it will call instantiateItem() to get an updated view.

So rather than trying to get a view you already instantiated (which may not even exist if the user has swiped a couple pages away from it), just tell the ViewPager that the view isn't valid anymore and hand it the updated view.

Here's one thing you could do with your adapter:

public class SequenceAdapter extends PagerAdapter {

    private List<View> mList;

    /** List of all the views/positions that have changed since last update */
    private List<Integer> mChanged;

    public SequenceAdapter(){
        this.mList = new ArrayList<>();
        this.mChanged = new ArrayList<>();
    }

    public void add(View viewGroup){
        mList.add(mList.size(), viewGroup);
        notifyDataSetChanged();
    }

    public View get(int position) {
        return mList.get(position);
    }

    public void update(View view, int position) {
        mList.set(position, view);
        mChanged.add(position);
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mList.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        int position = (Integer) object;
        return view == mList.get(position);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = mList.get(position);
        container.addView(view, position);
        return new Integer(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return null;
    }

    @Override
    public int getItemPosition(Object object) {
        int position = (Integer) object;
        return mChanged.contains(position) ? POSITION_NONE : position;
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        mChanged.clear();
    }

}

Note that I changed your reference object to be an Integer with the position of the view, rather than the view itself. This makes things a little easier.

So with the get() method you can access the view, then update it with update(). Once you update a view, if it's currently in the ViewPager you should see getItemPosition() being called. If POSITION_NONE is returned, you should get an instantiateItem() call for that position. Because of the way ViewPager updates with multiple calls to the adapter, it has to tell you when it's finished, so you override finishUpdate() to clear the positions marked as changed.

kris larson
  • 30,387
  • 5
  • 62
  • 74
  • Right. So in terms of code..Can you give me a piece of example? –  Sep 07 '16 at 20:14
  • In order for me to post any code that would be at all useful, I would need to reference your existing code. Updating your question with your current code would be helpful. – kris larson Sep 07 '16 at 20:20
  • Which one? The Adapter reference? –  Sep 07 '16 at 20:21
  • Updated my answer. Not 100% sure it will work since I just typed it in without an IDE, but have a look and see if it works for you. – kris larson Sep 07 '16 at 20:58