Android - ViewPager + FragmentStatePagerAdapter + PageTransformer

In my application, I am using a ViewPager in combination with a PageTransformer to display some list of data as a deck of cards. This list is updated occasionally and contains many elements in general, so I use a FragmentStatePagerAdapter with the required page limit:

public class PlaceListPagerAdapter extends FragmentStatePagerAdapter {

    private List<PlaceListData> items;

    public PlaceListPagerAdapter (FragmentManager manager) {
        super (manager);

        items = new ArrayList<>();
    }

    @Override
    public Fragment getItem(int position) {

        String id = items.get(position).getId();
        String name = items.get(position).getName();
        String address = items.get(position).getAddress();

        return PlaceFragment.newInstance(id, name, address);
    }

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

    @Override
    public int getItemPosition(Object object) {

        PlaceFragment frag = (PlaceFragment) object;
        String id = frag.getDataId();

        for (PlaceListData data : items) {
            if (id != null && id.equals(data.getId())) {
                return POSITION_UNCHANGED;
            }
        }

        return POSITION_NONE;
    }

    public void addItems(List<PlaceListData> items) {
        this.items.addAll(items);
        notifyDataSetChanged();
    }

    public void replaceItems(List<PlaceListData> items) {
        this.items.clear();
        addItems(items);
    }

    public void clearItems () {
        this.items.clear();
        notifyDataSetChanged();
    }
}

      

Nothing fancy - pojos list, overriden getItemPosition () and add / clear methods with notifyDataSetChanged (). The problem is that when I try to add / replace elements over the net, the transformPage (View view, float position) method of my transformer is called at position 0.0 for all new views and is stacked one above the other (transformation is broken).

After debugging the ViewPager class, I noticed that transformPage (View view, float position) is only called in one place in the onPageScrolled (..) method of the ViewPager, and the latter is called in onLayout (..) after the first layout pass.

notifyDataSetChanged () calls onPageScrolled (..) (and transformPage (View view, float position) respectively) and requestLayout () after that. The problem is that the first call to transformPage (View, float position) happens before the layout transition and the position parameter depends on View.left () which returns 0 as no child views are rendered. In the onLayout (..) that follows requestLayout () my transformPage (View, float position) is not called at all because yeap, the views are now styled, but this is not the first layout.

The issue was fixed by reloading the adapter (it sets the mFirstLayout flag in the ViewPager to "true") or calling any public ViewPager method that calls transformPage (View, float position) in this code, like scrollTo , fakeDrag , etc., but I I would like to know - is this all a feature of the ViewPager or is this a bug or am I doing something very wrong?

Sorry for my bad english and thanks in advance!

+3


source to share





All Articles