选项卡布局(TabLayout)选项卡选择

309

我应该如何在TabLayout中以编程方式选择选项卡?

 TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
 tabLayout.setupWithViewPager(viewPager);
29个回答

8

最新的简单解决方案对我有效:

with(binding.tablayout) {
    selectTab(getTabAt(tabPosisiton))
}


从0开始的tabPosition

6

试试这个

    new Handler().postDelayed(
            new Runnable(){
                @Override
                public void run() {
                    if (i == 1){
                        tabLayout.getTabAt(0).select();
                    } else if (i == 2){
                        tabLayout.getTabAt(1).select();
                    }
                }
            }, 100);

谢谢,它对我有用。但是使用delayed是否是一种好的实践? - Harsh Shah
我猜在任何布局上运行线程都不好,因为如果假设您正在从后端服务器获取选项卡的文本,并且由于任何原因导致服务器延迟,那么此系统线程将不必要地消耗您的设备资源。 - cammando
如此丑陋的解决方案 - Lester
这对我不起作用。如果用户点击选项卡,如何延迟选项卡选择?我什么都试过了,但是没有任何效果。我尝试使用(mViewPager.getCurrentItem()==0)代替i==1,但它不起作用,其他方法也不行。 - iBEK

6

Kotlin 用户:

Handler(Looper.getMainLooper()).postDelayed(
            { tabLayout.getTabAt(position).select() }, 100
        )

如果需要滚动,这也会滚动您的选项卡布局。


4

不同答案的综合解决方案如下:

new Handler().postDelayed(() -> {
  myViewPager.setCurrentItem(position, true);
  myTabLayout.setScrollPosition(position, 0f, true);
},
100);

3

如果你要使用 viewPager.setCurrentItem() 方法,你需要先使用一个 viewPager。

 viewPager.setCurrentItem(n);
 tabLayout.setOnTabSelectedListener(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) {

            }
        });

2

我正在使用TabLayout来切换片段。 它基本上可以工作,但每当我尝试使用tab.select()以编程方式选择选项卡时,我的TabLayout.OnTabSelectedListener会触发onTabSelected(TabLayout.Tab tab),这会给我带来很多麻烦。 我正在寻找一种在不触发监听器的情况下进行编程选择的方法。

因此,我采用了@kenodoggy的答案并将其适应于我的用途。 我还面临着一个问题,即一些内部对象将返回null(因为它们尚未创建,因为我正在从我的片段回答onActivityResult(),如果活动是singleTasksingleInstance,则会在onCreate()之前发生),因此我编写了详细的if / else序列,它将报告错误并在没有触发NullPointerException的情况下进行掉落。 我使用Timber进行记录,如果您没有使用,请替换为Log.e()

void updateSelectedTabTo(int position) {
    if (tabLayout != null){
        int selected = tabLayout.getSelectedTabPosition();
        if (selected != -1){
            TabLayout.Tab oldTab = tabLayout.getTabAt(0);
            if (oldTab != null){
                View view = oldTab.getCustomView();
                if (view != null){
                    view.setSelected(false);
                }
                else {
                    Timber.e("oldTab customView is null");
                }
            }
            else {
                Timber.e("oldTab is null");
            }
        }
        else {
            Timber.e("selected is -1");
        }
        TabLayout.Tab newTab = tabLayout.getTabAt(position);
        if (newTab != null){
            View view = newTab.getCustomView();
            if (view != null){
                view.setSelected(false);
            }
            else {
                Timber.e("newTab customView is null");
            }
        }
        else {
            Timber.e("newTab is null");
        }
    }
    else {
        Timber.e("tablayout is null");
    }
}

这里,tabLayout是我内存变量,绑定了XML中的TabLayout对象。而且我不使用滚动选项卡功能,因此也将其删除。


2
如果您正在使用带有viewPager的TabLayout,则这将对您有所帮助。您可以在addOnPageListener中设置TabLayout与ViewPager。
如果您想直接设置TabLayout位置(而不是单击标签),请尝试以下代码:tabLayout.getTabAt(position_you_want_to_set).select()
   /* will be invoked whenever the page changes or is incrementally scrolled*/
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            tabLayout.getTabAt(position).select();
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

1
欢迎来到StackOverflow!虽然答案可能是正确的,但您应该解释提供的代码如何解决所声明的问题。 - xKobalt

2

这种方法不适用于已实现ViewPager2的应用,此时需要使用

viewPager2.setCurrentItem(position);

onConfigureTab中,当我们使用TabLayoutMediator时,如果找到了onConfigureTab

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(
                tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                switch (position){
                    case 0 : tab.setIcon(getResources().getDrawable(R.drawable.camera));
                            break;
                    case 1 : tab.setText("CHAT");
                            viewPager2.setCurrentItem(position); // when app starts this will be the selected tab
                            break;
                    case 2 : tab.setText("STATUS");
                            break;
                    case 3 : tab.setText("CALL");
                        break;
                }
            }
        }
        );
        tabLayoutMediator.attach();

1

添加到您的ViewPager中:

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                array.clear();
                switch (position) {
                    case 1:
                        //like a example
                        setViewPagerByIndex(0);
                        break;
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

//在处理程序中防止内存溢出导致崩溃

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}

1
"防止崩溃和内存不足" - 为什么我们需要单独的线程来选择当前项目? - AppiDevo

0
如果你的默认选项卡是第一个(0),并且你切换到一个片段,那么你必须手动替换片段。这是因为在监听器注册之前,选项卡已经被选中了。
private TabLayout mTabLayout;

...

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_tablayout, container, false);
    mTabLayout = view.findViewById(R.id.sliding_tabs);
    mTabLayout.addOnTabSelectedListener(mOnTabSelectedListener);

    getActivity().getSupportFragmentManager().beginTransaction()
        .replace(R.id.tabContent, MyFirstFragment.newInstance()).commit();
    return view;
}

或者,您可以考虑调用getTabAt(0).select()并覆盖onTabReselected,如下所示:

@Override
public void onTabReselected(TabLayout.Tab tab) {
    // Replace the corresponding tab fragment.
}

这将起作用,因为您实质上是在每次重新选择标签时替换片段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接