Simian
Simian

Reputation: 1640

Stop ViewPagers inside ListView from resetting

I have a ListView that contains rows of ViewPagers. When a ViewPager is scrolled off screen, I want to save its page position. When the user scrolls to the ViewPager again, I then want to restore its last saved page position.

I'm trying to accomplish this with the following code:

public class MyBaseAdapter extends BaseAdapter {

    // Row ids that will come from server-side, uniquely identifies each
    // ViewPager
    private List<String> mIds = new ArrayList<String>();
    private Map<String, Integer> mPagerPositions = new HashMap<String, Integer>();

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String id = mIds.get(position);

        View rootView = convertView;
        if (rootView == null) {
            rootView = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.row, null);
        }

        ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.pager);
        Integer pagerPosition = mPagerPositions.get(id);
        if (pagerPosition != null) {
            viewPager.setCurrentItem(pagerPosition);
        }
        viewPager.setOnPageChangeListener(new MyPageChangeListener(id));

        return rootView;
    }

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

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    private class MyPageChangeListener extends
            ViewPager.SimpleOnPageChangeListener {

        private String mId;

        public MyPageChangeListener(String id) {
            mId = id;
        }

        @Override
        public void onPageSelected(int position) {
            mPagerPositions.put(mId, position);
        }
    }
}

The page position gets saved on the first invocation of setPagerPosition(). Afterwards, when the ViewPager goes off-screen, onPageSelected() is called with the first page position that was saved — overwriting any previous onPageSelected() calls that occurred when the ViewPager was still visible.

What's the right way to do this?

Upvotes: 6

Views: 862

Answers (2)

Simian
Simian

Reputation: 1640

The solution was to not overwrite the pager position when the ViewPager is not visible. There appears to be a bug in Android where onPageSelected is called when the ViewPager goes off screen when scrolling through the ListView.

@Override
public void onPageSelected(int position) {
    if (viewPager.isShown()) {
        mTopicPositions.put(mId, position);
    }
}

Upvotes: 3

Manoj Kumar
Manoj Kumar

Reputation: 1520

I think you can get the current displayed position by indexOfChild(viewPager.getFocusedChild()) and store it in a shared preference, and can retrieve it whenever required. Hope this helps

Upvotes: 0

Related Questions