TabLayout选项卡选择

我应该如何选择一个标签在TabLayout编程?

 TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
249212 次浏览

如果你知道你想要选择的标签的索引,你可以这样做:

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

即使你使用TabLayout本身而没有ViewPager(这是非典型的,可能是不好的做法,但我见过这样做),这种技术也是有效的。

这可能是不是最终的解决方案,和它要求你同时使用__ABC0和ViewPager,但这是我解决它的方法:

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

我测试了使用这段代码对性能的影响有多大,首先在Android Studio中运行该方法时查看CPU和内存监视器,然后将其与我自己在页面之间导航时(使用滑动手势)对CPU和内存的负载进行比较,结果发现差异并不大,所以至少这不是一个可怕的解决方案……

希望这能帮助到一些人!

我是这样解决的:

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

如果你不能使用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在选中和未选中的可绘制对象之间切换,或者类似地处理颜色和/或可绘制对象。

默认情况下,如果你选择一个选项卡,它将高亮显示。如果你想选择显式意味着使用给定的注释代码在onTabSelected(TabLayout。标签标签)与您指定的标签索引位置。这段代码将解释使用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);
}
}
}

用这个:

tabs.getTabAt(index).select();

请记住,如果currentTabIndex和index是相同的,那么这将发送您的流到onTabReselected而不是onTabSelected。

为你的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) {
}
});

//on处理程序,以防止crash outofmemory

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

试试这个

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

用这个:

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

请记住,如果currentTabIndex和index是相同的,那么这将发送您的流到onTabReselected而不是onTabSelected。

使用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对象的内存变量。我不使用滚动标签功能,所以我把它也删除了。

你可以试着用这个来解决:

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


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

这也有帮助

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

只要设置viewPager.setCurrentItem(index),相关的TabLayout就会选择相应的选项卡。

您可以使用以下函数设置TabLayout位置

public void setTab(){
tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true);
tabLayout.setSelected(true);
}

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

这是可行的,因为你实际上是在每个选项卡重新选择上替换片段。

如果您在理解上有困难,这段代码可以帮助您

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

试试这个方法。

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

如果你使用TabLayout没有viewPager,这有助于

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


}
});
有点晚了,但可能是一个有用的解决方案。 我直接在我的片段中使用我的TabLayout,并试图在片段的生命周期中选择一个选项卡。 对我来说有用的是等待TabLayout使用android.view.View#post方法完成它的子视图。即:< / p >
int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });

结合不同的答案可以得出:

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

你应该使用viewPager来使用viewpage . 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) {


}
});

对于材料组件库提供的TabLayout,只需使用< >强selectTab < / >强方法:

TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.selectTab(tabLayout.getTabAt(index));

enter image description here

它需要版本为1.1.0。

芬兰湾的科特林修复

: viewpage。currentItem = 0

tabs.setupWithViewPager (: viewpage)

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

这将选择标签作为视图分页器滑动页面

如果你正在使用TabLayout和viewPager,那么这有助于你。你可以在addOnpagelistener中使用ViewPager设置TabLayout。

如果你想直接设置TabLayout的位置(而不是单击Tab个人),请尝试下面的代码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) {


}
});

这将不工作的应用程序,有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();

芬兰湾的科特林用户:

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

这也将滚动你的标签布局,如果它需要滚动。

对于Viewpager2, Kotlin,其他答案都没有帮助,只有下面这个有用。位置是从片段结果监听器在我的情况下:

TabLayoutMediator(binding.tabLayout, binding.viewPager2) { _, _ ->
binding.viewPager2 = position
}.attach()

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

binding.tablayout.selectTab(binding.tablayout.getTabAt(tabPosisiton))

tabPosition从0开始