Viewpager2 and FragmentStateAdapter: getItemId()

51 Views Asked by At

I'm developing a Android java app to show some lists, with Tablayout, viewpager2 and fragments. In my simple example, at first I inizialize an arraylist of lists, then load the listpageradapter and connect it to the viewpager2. Well: if I don't override getItemId() method in my listpageradapter, after run and selecting various lists, sometimes I can't see all the items: if I switch from list 1 to list 3, items disappears. If I override getItemId() with an unique algorithm (I used a simple unique counter for each list: 1-2-3), I can see all the items, but if I go in landscape mode, I get a crash event selecting a second list: Design assumption violated. What's the problem? Thank you very much.

This is my Main Activity:

public class MainActivity extends AppCompatActivity {
    ArrayList<ItemList> itemListArrayList;
    TabLayout tabLayout;
    ViewPager2 viewPager;
    ListPagerAdapter listPagerAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itemListArrayList = initializeItemList();
        initializeGraphics();
        setupViewPager();
    }

    private void setupViewPager() {
        listPagerAdapter = new ListPagerAdapter(this, itemListArrayList);
        viewPager.setAdapter(listPagerAdapter);

        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> tab.setText(itemListArrayList.get(position).getName())
        ).attach();

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition(), true);
                updateList(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });
    }


    private ArrayList<ItemList> initializeItemList() {
        ArrayList<ItemList> itemListArrayList = new ArrayList<>();
        //itemListArrayList.clear();
        ItemList newList = new ItemList("First list", 1);
        newList.addItem(new Item("Item 1"));
        newList.addItem(new Item("Item 2"));
        newList.addItem(new Item("Item 3"));
        newList.addItem(new Item("Item 4"));
        itemListArrayList.add(newList);
        newList = new ItemList("Second list", 2);
        newList.addItem(new Item("Item 1"));
        newList.addItem(new Item("Item 2"));
        newList.addItem(new Item("Item 3"));
        itemListArrayList.add(newList);
        newList = new ItemList("Third list", 3);
        newList.addItem(new Item("Item 1"));
        newList.addItem(new Item("Item 2"));
        itemListArrayList.add(newList);
        return itemListArrayList;
    }

    private void initializeGraphics() {
        tabLayout = findViewById(R.id.tabLayout);
        viewPager = findViewById(R.id.viewPager);
    }

    private void updateList(int position) {
        ItemList currentItemList = itemListArrayList.get(position);

        Fragment fragment = getSupportFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem());

        if (fragment instanceof ListFragment) {
            ListFragment listFragment = (ListFragment) fragment;
            listFragment.updateItemList(currentItemList);
        }
    }

}

This is my FragmentStateAdapter:

public class ListPagerAdapter extends FragmentStateAdapter {

    private final ArrayList<ItemList> itemListArrayList;

    public ListPagerAdapter(FragmentActivity fragmentActivity, ArrayList<ItemList> itemListArrayList) {
        super(fragmentActivity);
        this.itemListArrayList = itemListArrayList;
    }
    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return ListFragment.newInstance(itemListArrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return itemListArrayList.size();
    }
/*
    @Override
    public long getItemId(int position) {
        // if I don't override this method, I can't see all items in lists
        // if I override this method, I got landscape problems
        return itemListArrayList.get(position).getUniqueId();

    }*/
}

This is my Fragment:

public class ListFragment extends Fragment {

    private static final String ARG_ITEM_LIST = "arg_item_list";

    private ItemList itemList;
    private RecyclerView recyclerView;

    public ListFragment() {
        // Required empty public constructor
    }

    public static ListFragment newInstance(ItemList itemList) {
        ListFragment fragment = new ListFragment();
        Bundle args = new Bundle();
        args.putSerializable(ARG_ITEM_LIST, itemList);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            itemList = (ItemList) getArguments().getSerializable(ARG_ITEM_LIST);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container, false);

        recyclerView = view.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        MyItemAdapter myItemAdapter = new MyItemAdapter(itemList.getMyItemList());
        recyclerView.setAdapter(myItemAdapter);

        return view;
    }

    public void updateItemList(ItemList itemList) {
        this.itemList = itemList;
        MyItemAdapter myItemAdapter = (MyItemAdapter) recyclerView.getAdapter();
        if (myItemAdapter != null) {
            myItemAdapter.updateData(itemList.getMyItemList());
        }
    }
}
0

There are 0 best solutions below