Search code examples
androidandroid-viewpagerandroid-tablayout

TabLayout with ViewPager on new tab selection previous tab text disappers


I'm using TabLayout with ViewPager for showing data as requested. In tab layout, my requirement is, I've to set a different font for the selected item and a different one for others. I write the following code for this.

But I'm facing one issue. Suppose I've 4 items "One", "Two", "Three" and "Four". Initially "One" is default selected with Bold font, and others are with normal font. But when I click "Two" tab "One" tab disappears. When I click on "Three" tab "Two" tab disappears and "One" tab visible with normal font.

private void setupViewPager(CustomViewPager viewPager, TabLayout tabLayout, ArrayList<TipsInfo> mListTips) {
        adapter = new ViewPagerAdapter(getChildFragmentManager());

        for (int i = 0; i < mListTips.size(); i++) {
            if (!TextUtils.isEmpty(mListTips.get(i).getValue()))
                adapter.addFragment(TipsDetailFragment.newInstance(mListTips.get(i).getValue()), mListTips.get(i).getLabel());
        }
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);

        View tabContent = LayoutInflater.from(requireContext()).inflate(R.layout.item_tips_tablayout_selected, null);
        TextView selected = tabContent.findViewById(R.id.tv_tips_selected_tab);
        View tabContent1 = LayoutInflater.from(requireContext()).inflate(R.layout.item_tips_tablayout_unselected, null);
        TextView unselected = tabContent1.findViewById(R.id.tv_tips_unselected_tab);

        tabLayout.addOnTabSelectedListener(
                new TabLayout.OnTabSelectedListener() {
                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                        selected.setText(tab.getText());
                        tab.setCustomView(selected);
                    }

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

                        unselected.setText(tab.getText());
                        tab.setCustomView(unselected);
//
//                        for(int i=0; i<tabLayout.getTabCount(); i++){
//                            if(i != tabLayout.getSelectedTabPosition()){
//                                unselected.setText(tabLayout.getTabAt(i).getText());
//                                tabLayout.getTabAt(i).setCustomView(unselected);
//                            }
//                        }
                    }

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

    }

My ViewPaerAdapter is extended with FragmentStatePagerAdapter and its object is created with getChildFragmentManager. My XML code look's like this:

<com.google.android.material.tabs.TabLayout
            android:id="@+id/tl_tips"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorWhite"
            android:elevation="@dimen/v1dp"
            android:visibility="invisible"
            app:tabGravity="fill"
            android:gravity="start"
            app:tabMinWidth="@dimen/v100dp"
            android:textAlignment="viewStart"
            app:tabIndicatorFullWidth="false"
            app:tabIndicatorColor="@color/colorBannerNewDotSelected"
            app:tabMode="scrollable"
            android:layout_gravity="start"
            app:tabIndicatorHeight="@dimen/v3dp"
            app:tabSelectedTextColor="@color/colorBlackDark"
            app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
            app:tabTextColor="@color/colorServiceCount"
            />

item_tips_tablayout_selected and item_tips_tablayout_unselected contains only TextView with different fonts applied to it.

Screenshots:

  1. Initial

enter image description here

  1. When clicked on "Benefits", the font applied to it but "How to use" disappeared.

enter image description here

  1. When clicked on "Product Use", the font applied to it, "How to use" appeared with normal font, and "Benefits" tab disappeared.

enter image description here


Solution

  • It basically does what you wrote in your code.

    tabLayout.addOnTabSelectedListener(
                        new TabLayout.OnTabSelectedListener() {
                            @Override
                            //as tab 2 selected it set text to tab 2
                            public void onTabSelected(TabLayout.Tab tab) {
                                selected.setText(tab.getText());
                                tab.setCustomView(selected);
                            }
        
                            @Override
                            public void onTabUnselected(TabLayout.Tab tab) {
         //as tab 1 unselected it set NO text to tab 1 in it 
                                unselected.setText(tab.getText());
                                tab.setCustomView(unselected);
    

    Why to set CustomView every time when you just need to change the typeface?

    I have an Kotlin code that was converted to JAVA code, it looks like shit in JAVA, but it works:

     private void setTypefaceToTab(Context context, TabLayout tabLayout, TabLayout.Tab tab, int stylem) {
                if (tab != null && context != null) {
                    try {
                         View var10000 = ((ViewGroup)tabLayout.getChildAt(0)).getChildAt(tab.getPosition());
                        LinearLayout layout = (LinearLayout)var10000;
                        var10000 = layout.getChildAt(1);
                        TextView tabTextView = (TextView)var10000;
                        tabTextView.setTextSize (***Text Size***);
                        tabTextView.setTypeface(Typeface.create("sans-serif-condensed",stylem));
                    } catch (Exception var7) {
                        Log.d ("EXC",var7.toString ());
                    }
                }
            }
    

    Then just use it at tabselectedlistener and in onCreate to set typeface for the first selected tab:

    protected void onCreate(Bundle savedInstanceState) {
    ...
     setTypefaceToTab(context,tablayout, tablayout.getTabAt (tablayout.getSelectedTabPosition ()),Typeface.BOLD_ITALIC);
    ...
    }
    

    and in tabListener:

      private void tabListener(){
                tablayout.addOnTabSelectedListener (new TabLayout.OnTabSelectedListener () {
                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                                setTypefaceToTab(context,tablayout,tab,Typeface.BOLD_ITALIC);
                    }
        
                    @Override
                    public void onTabUnselected(TabLayout.Tab tab) {
                        setTypefaceToTab(context,tablayout,tab,Typeface.NORMAL);
                    }
        
                    @Override
                    public void onTabReselected(TabLayout.Tab tab) {
        
                    }
                });
            }
    

    Hope it is what you wanted