1

I have an Android TabLayout, defined like this.

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/now_playing_queues_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.tabs.TabItem
            android:id="@+id/now_playing_tab_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Now Playing"
            android:icon="@color/purple_700"/>

        <com.google.android.material.tabs.TabItem
            android:id="@+id/queues_tab_item"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Queues"/>

    </com.google.android.material.tabs.TabLayout>

I then add listeners in Java like this:

        TabLayout nowPlayingQueuesTabs;

        nowPlayingQueuesTabs = findViewById(R.id.now_playing_queues_tabs);

        nowPlayingQueuesTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                System.out.println(tab.getText());
                if(tab.getText() == "Now Playing") {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.replace(R.id.now_playing_tab_item, new NowPlayingFragment());
                    fragmentTransaction.commit();
                }
                else if(tab.getText() == "Queues") {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.replace(R.id.queues_tab_item, new QueuesFragment());
                    fragmentTransaction.commit();
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                // Your code here
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                System.out.println("Reselected.");
            }
        });

However, I don't see anything when I click on the tabs:
Screenshot of problem

How do I show the appropriate Fragment when a tab is clicked/pressed? Is this even the right way to do this? By the way, I also need to preserve the state of the Fragments so, for example, if there is a switch that the user turns on in one tab, they can switch to the other tab and back again and the switch will stay on.

I looked at this answer, but the code uses a lot of depreciated APIs and I can't make it work for me. Also, I can use a ViewPager, but can't allow swiping between tabs.

1 Answers1

0

First create this class:

class NowPlayingQueuesTabsPagerAdapter extends FragmentPagerAdapter {

    private final int numOfTabs;

    public NowPlayingQueuesTabsPagerAdapter(FragmentManager fm, int numOfTabs) {
        super(fm);
        this.numOfTabs = numOfTabs;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new NowPlayingFragment();
            case 1:
                return new QueuesFragment();
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        return numOfTabs;
    }
}

Next, create another class:

public class CustomViewPager extends ViewPager {
    private Boolean disable = false;
    public CustomViewPager(Context context) {
        super(context);
    }
    public CustomViewPager(Context context, AttributeSet attrs){
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !disable && super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !disable && super.onTouchEvent(event);
    }

    public void disableScroll(Boolean disable) {
        //When disable = true not work the scroll and when disable = false work the scroll
        this.disable = disable;
    }
}

Use this layout code:

    <net.formalsoftware.great_site.keeptrackv1.CustomViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/tab_layout"/>

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:layout_constraintTop_toBottomOf="@id/top_app_bar_layout" />

Finally, implement it like this:

        TabLayout tabLayout;
        CustomViewPager viewPager;

        viewPager = findViewById(R.id.view_pager);
        tabLayout = findViewById(R.id.tab_layout);

        // Add tabs.
        TabLayout.Tab nowPlayingTab = tabLayout.newTab();
        nowPlayingTab.setText("Now Playing");

        TabLayout.Tab queuesTab = tabLayout.newTab();
        queuesTab.setText("Queues");

        tabLayout.addTab(nowPlayingTab);
        tabLayout.addTab(queuesTab);

        // Set adapter for ViewPager.
        NowPlayingQueuesTabsPagerAdapter nowPlayingQueuesTabsPagerAdapter = new NowPlayingQueuesTabsPagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(nowPlayingQueuesTabsPagerAdapter);

        // Set listener for TabLayout.
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); }

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

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

        viewPager.disableScroll(true);

You should now have a working TabView that views multiple fragments and doesn't allow the user to swipe between tabs!

Ben the Coder
  • 539
  • 2
  • 5
  • 21
  • Work great, thanks! I will award the bounty as soon as possible (6 hours) and upvote when I have enough reputation. –  Jul 18 '23 at 13:06
  • ViewPager should be deprecated inclusively, [check this out](https://stackoverflow.com/questions/56778106/fragmentpageradapter-deprecated) – Zain Jul 18 '23 at 21:14