How to add programmatically Tabs in TabLayout on Android

Jongle picture Jongle · Jul 12, 2017 · Viewed 14.4k times · Source

In my application I want create dynamically tabs in tabLayout and I want when get data from server and this data count > 0 then create tab.
For TabLayout I use this library : https://github.com/egemenmede/etiyabadgetab

For this job I write below codes:

        FullSearchSendData sendData = new FullSearchSendData();
    sendData.setKey(fullSearchText);
    sendData.setLoadImages(true);
    sendData.setSearchInCelebrities(true);
    sendData.setSearchInMovies(true);
    sendData.setSearchInSeries(true);
    sendData.setSearchInEpisodes(true);
    sendData.setSearchInUsers(true);
    sendData.setPageIndex(1);
    sendData.setPageSize(10);
    sendData.setMaxDistance(1);

    fullSearch_LoadLay.setVisibility(View.VISIBLE);

    InterfaceApi api = ApiClient.getClient().create(InterfaceApi.class);
    Call<FullSearchResponse> call = api.getFullSearch(sendData);

    call.enqueue(new Callback<FullSearchResponse>() {
        @Override
        public void onResponse(Call<FullSearchResponse> call, Response<FullSearchResponse> response) {
            FullSearchResponse searchResponse = response.body();
            if (searchResponse.getData().getCelebritiesCount() > 0) {
                celebritiesCount = searchResponse.getData().getCelebritiesCount();
                celebrityList.clear();
                celebrityList.addAll(searchResponse.getData().getCelebrities());
            }
            if (searchResponse.getData().getMoviesCount() > 0) {
                movieCount = searchResponse.getData().getMoviesCount();
                movieList.clear();
                movieList.addAll(searchResponse.getData().getMovies());
            }
            if (searchResponse.getData().getSeriesCount() > 0) {
                serieCount = searchResponse.getData().getSeriesCount();
                seriesList.clear();
                seriesList.addAll(searchResponse.getData().getSeries());
            }
            if (searchResponse.getData().getUsersCount() > 0) {
                usersCount = searchResponse.getData().getUsersCount();
                userList.clear();
                userList.addAll(searchResponse.getData().getUsers());
            }

            setupViewPager(fullSearch_ViewPager);
            setupTabs();

            fullSearch_LoadLay.setVisibility(View.GONE);

            //fullSearch_Swipe.setRefreshing(false);
        }

        @Override
        public void onFailure(Call<FullSearchResponse> call, Throwable t) {
            fullSearch_LoadLay.setVisibility(View.GONE);
            fullSearch_ReloadLay.setVisibility(View.VISIBLE);
        }
    });
}

private void setupTabs() {
    if (celebritiesCount > 0) {
        fullSearch_tabLayout.addTab(new TabLayout(context).newTab());
        fullSearch_tabLayout.selectEtiyaBadgeTab(0)
                .tabTitle("Celebrities")
                .tabTitleColor(R.color.white)
                .tabBadge(true)
                .tabBadgeCount(celebritiesCount)
                .tabBadgeCountMore(false)
                .tabBadgeBgColor(R.color.colorAccent)
                .tabBadgeTextColor(R.color.white)
                .tabBadgeStroke(2, R.color.white)
                .tabBadgeCornerRadius(15)
                .createEtiyaBadgeTab();
    }
    if (movieCount > 0) {
        fullSearch_tabLayout.addTab(new TabLayout(context).newTab());
        fullSearch_tabLayout.selectEtiyaBadgeTab(1)
                .tabTitle("Movies")
                .tabTitleColor(R.color.white)
                .tabBadge(true)
                .tabBadgeCount(movieCount)
                .tabBadgeCountMore(false)
                .tabBadgeBgColor(R.color.colorAccent)
                .tabBadgeTextColor(R.color.white)
                .tabBadgeStroke(2, R.color.white)
                .tabBadgeCornerRadius(15)
                .createEtiyaBadgeTab();
    }
    if (serieCount > 0) {
        fullSearch_tabLayout.addTab(new TabLayout(context).newTab());
        fullSearch_tabLayout.selectEtiyaBadgeTab(2)
                .tabTitle("Series")
                .tabTitleColor(R.color.white)
                .tabBadge(true)
                .tabBadgeCount(serieCount)
                .tabBadgeCountMore(false)
                .tabBadgeBgColor(R.color.colorAccent)
                .tabBadgeTextColor(R.color.white)
                .tabBadgeStroke(2, R.color.white)
                .tabBadgeCornerRadius(15)
                .createEtiyaBadgeTab();
    }
    if (usersCount > 0) {
        fullSearch_tabLayout.addTab(new TabLayout(context).newTab());
        fullSearch_tabLayout.selectEtiyaBadgeTab(3)
                .tabTitle("Users")
                .tabTitleColor(R.color.white)
                .tabBadge(true)
                .tabBadgeCount(usersCount)
                .tabBadgeCountMore(false)
                .tabBadgeBgColor(R.color.colorAccent)
                .tabBadgeTextColor(R.color.white)
                .tabBadgeStroke(2, R.color.white)
                .tabBadgeCornerRadius(15)
                .createEtiyaBadgeTab();
    }
}

private void setupViewPager(ViewPager viewPager) {

    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    if (celebritiesCount > 0) {
        adapter.addFrag(FullSearchCelebritiesFragment.getInstance(celebrityList, celebritiesCount, fullSearchText), "Celebrities");
    }
    if (movieCount > 0) {
        adapter.addFrag(FullSearchMovieFragment.getInstance(movieList, movieCount, fullSearchText), "Movies");
    }
    if (serieCount > 0) {
        adapter.addFrag(FullSearchSeriesFragment.getInstance(seriesList, serieCount, fullSearchText), "Series");
    }
    if (usersCount > 0) {
        adapter.addFrag(FullSearchUsersFragment.getInstance(userList, usersCount, fullSearchText), "Users");
    }
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

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

    public void addFrag(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

But when run application show me this error :

Process: com.test.example, PID: 3804
                                                                   java.lang.IllegalArgumentException: Tab belongs to a different TabLayout.
                                                                       at android.support.design.widget.TabLayout.addTab(TabLayout.java:476)
                                                                       at android.support.design.widget.TabLayout.addTab(TabLayout.java:464)
                                                                       at android.support.design.widget.TabLayout.addTab(TabLayout.java:443)
                                                                       at com.test.example.Activities.FullSearch.setupTabs(FullSearch.java:173)
                                                                       at com.test.example.Activities.FullSearch.access$900(FullSearch.java:44)
                                                                       at com.test.example.Activities.FullSearch$1.onResponse(FullSearch.java:156)
                                                                       at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
                                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:135)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5349)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)

When click on first link in error message, go to this code :

fullSearch_tabLayout.addTab(new TabLayout(context).newTab());

How can I fix this and create dynamically tabs in tabLayout ?

Please help me, i really need your helps. Thanks all <3

Answer

Josef Adamcik picture Josef Adamcik · Jul 12, 2017

Call newTab() funtion on your TabLayout instance. 'new' keyword is the problem because you are creating new instance of TabLayout for each new tab and trying to add it to an existing instance.

fullSearch_tabLayout.addTab(fullSearch_tabLayout.newTab());