Search code examples
androidandroid-fragmentsduplicatesandroid-tablayout

How to set page title on TabLayout's tabs with ViewPager


I'm trying to dynamically set tab's title from model class. For this, I have overriden the getPageTitle(int position) method then return the charsequence. However as the titles come from the model field, I'm getting duplicates. How can I only return unique field name as page title? Or what is the best way to achieve this.

For example I want to group all books from an author in one tab.

Well, this is how my adapter looks like, so simple:

 public class BooksListsAdapter extends FragmentPagerAdapter {
    private ArrayList<Books> listOfBooks= new ArrayList<>();

    public BooksListsAdapter (FragmentManager fragmentManager, ArrayList<Books> listOfBooks) {
        super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        this.listOfBooks= listOfBooks;
    }

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

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return BooksListFragment.newInstance(listOfBooks.get(position).getAuthor(), listOfBooks);
    }

    @Override
    public CharSequence getPageTitle(int position){
        return listOfBooks.get(position).getAuthor();// Would like this returns only individual author regardless how many books they have
    }
}

This works fine except tabs are created with duplicated titles,hence duplicated contents. However I already have contents grouped in corresponding fragments. I would just like to remove the duplicated tab (the one repeating the same author name).

Thanks for your time.


Solution

  • You can make a ViewPager base on the total number of authors you have. And for each page, you will display all the books of this author.

    public class BooksListsAdapter extends FragmentPagerAdapter {
        private List<String> authors = new ArrayList<>();
        private HashMap<String, List<Books>> booksMap = new HashMap<>(); // author is key, list of book of this author is value
    
        public BooksListsAdapter(FragmentManager fragmentManager, ArrayList<Books> listOfBooks) {
            super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
    
            setBooksWithAuthor(listOfBooks);
            // LOGIC to order tab go here. Tab order <=> authors list order
            // Example: Order tab by author name: Collections.sort(authors);
        }
    
        private void setBooksWithAuthor(ArrayList<Books> books) {
            for (Books book : books) {
                if (booksMap.containsKey(book.getAuthor())) {
                    booksMap.get(book.getAuthor()).add(book);
                } else {
                    booksMap.put(book.getAuthor(), new ArrayList<Books>() {{
                        add(book);
                    }});
                    authors.add(book.getAuthor());
                }
            }
        }
    
        @Override
        public int getCount() {
            return authors.size(); // total page = total author
        }
    
        @NonNull
        @Override
        public Fragment getItem(int position) {
            String author = authors.get(position);
            return BooksListFragment.newInstance(author, booksMap.get(author));
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return authors.get(position);
        }
    }
    

    Hope it help