TabLayout选项卡选择


Answers:


418

如果知道要选择的选项卡的索引,可以这样进行:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();

即使您单独使用不带ViewPager的TabLayout,此技术也可以工作(这是非典型的,并且可能是不好的做法,但我已经看到了)。


10
仅当选项卡已添加到操作栏中时,此解决方案才有效,但情况并非总是如此。在文档中TabLayout.Tab.select()“选择此选项卡。仅在选项卡已添加到操作栏中时才有效。”
丹尼尔·克维斯特

7
@DanielKvist,实际上文档本身是不正确的。源代码不言自明。该答案应该是被接受的答案。
杰森·斯帕克

@JasonSparc嗯,我记得上次尝试此解决方案时它对我不起作用,但是我会看看是否可以再次检查它对我的作用。你有没有尝试过?在某些情况下可能会起作用,而在其他情况下可能不会起作用?它可能取决于API级别或类似的内容?
Daniel Kvist

感谢您通过半熟的答案清除空气!因为这可能不适用于独立的TabLayout,可能是由于您所说的原因;它旨在与Actionbar中的Tabs一起使用!
sud007 '16

3
为什么在不使用ViewPager的情况下使用TabLayout应该被视为不良做法?
tomalf2

85

这是我解决的方法:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}

3
选择的答案对我没有用,但是这个答案有用。
Rafal Zawadzki

很好的解决方案!当我需要同时移回首页时,viewPager和TabView都对我来说很好
sashk0 2016年

49

用这个:

tabs.getTabAt(index).select();

谢谢,这对我来说是一个安全的解决方案
伊斯兰法里德

Objects.requireNonNull(tabs.getTabAt(position)).select();使用安全
Williaan Lopes

1
请记住,如果currentTabIndex和index相同,则这会将您的流发送到onTabReselected而不是onTabSelected。
Abhishek Kumar,

@WilliaanLopes,这不会保护您免受NPI的侵害,只会更早将其丢弃
Krzysztof Kubicki

33

用这个:

<android.support.design.widget.TabLayout
    android:id="@+id/patienthomescreen_tabs"
    android:layout_width="match_parent"
    android:layout_height="72sp"
    app:tabGravity="fill"
    app:tabMode="fixed"
    app:tabIndicatorColor="@android:color/white"
    app:tabSelectedTextColor="@color/green"/>

之后在OnClickListener中:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();

如果tabMode可滚动怎么办?
GvSharma

我认为相同,请先尝试一下。
Pravin Suthar '18

23

这可能不是最终的解决方案它要求您将和TabLayout一起使用ViewPager,但这是我解决的方法:

void selectPage(int pageIndex)
{
    viewPager.setCurrentItem(pageIndex);
    tabLayout.setupWithViewPager(viewPager);
}

我先通过在运行该方法的同时查看Android Studio中的CPU和内存监视器,然后将其与在页面之间导航时所施加的CPU和内存负载进行比较,来测试使用此代码会对性能产生多大的影响我自己(使用滑动手势),并且差异并不大,因此至少这不是一个可怕的解决方案...

希望这对某人有帮助!


1
当我执行dap的解决方案(tabLayout.setScrollPosition(pageIndex,0f,true);)时,当我单击右侧的选项卡时,它没有更新ViewPager的页面(我不知道为什么)。最后,只需单击左选项卡,然后再次单击右选项卡,最终将更新页面以具有右选项卡的页面,这非常容易出错。但是此解决方案没有任何故障。
Rock Lee

12

如果您不能使用tab.select()并且不想使用ViewPager,您仍然可以通过编程方式选择一个标签。如果您正在使用自定义视图TabLayout.Tab setCustomView(android.view.View view),则更为简单。这是双向的方法。

// if you've set a custom view
void updateTabSelection(int position) {
    // get the position of the currently selected tab and set selected to false
    mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(false);
    // set selected to true on the desired tab
    mTabLayout.getTabAt(position).getCustomView().setSelected(true);
    // move the selection indicator
    mTabLayout.setScrollPosition(position, 0, true);

    // ... your logic to swap out your fragments
}

如果您不使用自定义视图,则可以这样做

// if you are not using a custom view
void updateTabSelection(int position) {
    // get a reference to the tabs container view
    LinearLayout ll = (LinearLayout) mTabLayout.getChildAt(0);
    // get the child view at the position of the currently selected tab and set selected to false
    ll.getChildAt(mTabLayout.getSelectedTabPosition()).setSelected(false);
    // get the child view at the new selected position and set selected to true
    ll.getChildAt(position).setSelected(true);
    // move the selection indicator
    mTabLayout.setScrollPosition(position, 0, true);

    // ... your logic to swap out your fragments
}

使用StateListDrawable在选定的和未选定的可绘制对象之间切换,或者使用类似的方法对颜色和/或可绘制对象进行所需的操作。



7

您可以尝试解决此问题:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);

TabLayout.Tab tab = tabLayout.getTabAt(pos);
if (tab != null) {
    tab.select();
}

5

试试这个

    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);

谢谢。它为我工作。但是,延迟使用是一种好习惯吗?
夏沙(Harsh Shah)

我猜想在任何布局原因上运行线程都是不好的,如果假设您是从后端服务器获取tab的文本,并且如果服务器出于某种原因延迟了b'coz,那么此系统线程将不必要地消耗您的设备资源。
cammando

如此丑陋的解决方案
Lester

这对我不起作用。如果用户单击选项卡,然后延迟该选项卡的选择,我该如何做呢?我什么都不能工作。我尝试了如果我== 1来使用(mViewPager.getCurrentItem()== 0),但是它不起作用,也没有任何其他作用。
iBEK

5

有点晚了,但可能是一个有用的解决方案。我直接在Fragment中使用TabLayout,并试图在Fragment的生命周期的早期选择一个选项卡。对我有用的是等到TabLayout使用android.view.View#post方法完成绘制其子视图为止 。即:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });

正确的答案对我有用,但有些延迟会带来很好的效果 new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham

3

正在使用TabLayout切换片段。它在大多数情况下都有效,除非每当我尝试通过编程方式选择一个选项卡时tab.select(),我TabLayout.OnTabSelectedListener都会触发onTabSelected(TabLayout.Tab tab),这会给我带来很多麻烦。我一直在寻找一种无需触发监听器即可进行程序选择的方法。

因此,我调整了@kenodoggy的答案以适应我的使用。我还面临一个问题,其中一些内部对象将返回null(因为尚未创建,因为我是onActivityResult()从片段中回答的,所以onCreate()在活动为singleTaskor 之前发生singleInstance),所以我写了一个详细的if / else序列将报告错误并失败,而NullPointerException不会触发。如果您不使用Timber进行日志记录,则使用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是绑定到TabLayoutXML对象的内存变量。而且我不使用滚动标签功能,因此也将其删除。


3

您应该使用viewPager来使用viewPager.setCurrentItem()

 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

为您的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

2

来自不同答案的组合解决方案是:

new Handler().postDelayed(() -> {

  myViewPager.setCurrentItem(position, true);

  myTabLayout.setScrollPosition(position, 0f, true);
},
100);


1

默认情况下,如果您选择一个选项卡,它将突出显示。如果要显式选择,则意味着将onTabSelected(TabLayout.Tab选项卡)下的给定注释代码与指定的选项卡索引位置一起使用。此代码将说明有关使用viewpager在选项卡选定位置上的更改片段的信息。

public class GalleryFragment extends Fragment implements TabLayout.OnTabSelectedListener 
{
private ViewPager viewPager;public ViewPagerAdapter adapter;private TabLayout tabLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new PaymentCardFragment(), "PAYMENT CARDS");
adapter.addFragment(new LoyaltyCardFragment(), "LOYALTY CARDS");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setOnTabSelectedListener(this);
}

@Override
public void onTabSelected(TabLayout.Tab tab) {
    //This will be called 2nd when you select a tab or swipe using viewpager
    final int position = tab.getPosition();
    Log.i("card", "Tablayout pos: " + position);
    //TabLayout.Tab tabdata=tabLayout.getTabAt(position);
    //tabdata.select();
    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            if (position == 0) {
                PaymentCardFragment paymentCardFragment = getPaymentCardFragment();
                if (paymentCardFragment != null) {
                   VerticalViewpager vp = paymentCardFragment.mypager;
                    if(vp!=null)
                    {
                      //vp.setCurrentItem(position,true);
                      vp.setCurrentItem(vp.getAdapter().getCount()-1,true);
                    }
                  }
            }
            if (position == 1) {
               LoyaltyCardFragment loyaltyCardFragment = getLoyaltyCardFragment();
                if (loyaltyCardFragment != null) {
                   VerticalViewpager vp = loyaltyCardFragment.mypager;
                    if(vp!=null)
                    {
                        vp.setCurrentItem(position);
                    }
                  }
            }
        }
    });
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
 //This will be called 1st when you select a tab or swipe using viewpager
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
  //This will be called only when you select the already selected tab(Ex: selecting 3rd tab again and again)
}
 private PaymentCardFragment getLoyaltyCardFragment() {
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());

   if(f instanceof PaymentCardFragment)
   {
    return (PaymentCardFragment) f;
   }
   return null;
 }
private LoyaltyCardFragment getPaymentCardFragment() {
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
    if(f instanceof LoyaltyCardFragment)
   {
    return (LoyaltyCardFragment) f;
   }
   return null;
 }
  class ViewPagerAdapter extends FragmentPagerAdapter {
   public List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();
   public void addFragment(Fragment fragment, String title) {
   mFragmentList.add(fragment);
   mFragmentTitleList.add(title);
  }
 }
}

1

这也可以帮助

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int i, float v, int i1) {
    }

    @Override
    public void onPageSelected(int i) {
        tablayout.getTabAt(i).select();
    }

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

1

如果您的默认选项卡是第一个(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.
}

这将起作用,因为您实际上是在重新选择每个选项卡上替换片段。



0

如果您在理解上有困难,此代码可以为您提供帮助

private void MyTabLayout(){
    TabLayout.Tab myTab = myTabLayout.newTab(); // create a new tab
    myTabLayout.addTab(myTab); // add my new tab to myTabLayout
    myTab.setText("new tab"); 
    myTab.select(); // select the new tab
}

您也可以将其添加到代码中:

myTabLayout.setTabTextColors(getColor(R.color.colorNormalTab),getColor(R.color.colorSelectedTab));

0

尝试这种方式。

tabLayout.setTabTextColors(getResources().getColor(R.color.colorHintTextLight),
                           getResources().getColor(R.color.colorPrimaryTextLight));

0

如果您使用不带viewPager的TabLayout,则有帮助

 mTitles = getResources().getStringArray(R.array.tabItems);
    mIcons = getResources().obtainTypedArray(R.array.tabIcons);
    for (int i = 0; i < mTitles.length; i++) {

        tabs.addTab(tabs.newTab().setText(mTitles[i]).setIcon(mIcons.getDrawable(i)));
        if (i == 0) {
            /*For setting selected position 0 at start*/
            Objects.requireNonNull(Objects.requireNonNull(tabs.getTabAt(i)).getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
        }
    }

    tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.white), PorterDuff.Mode.SRC_IN);
        }

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

        }
    });


0
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));

这将选择选项卡作为查看寻呼机的滑动页面

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.