以编程方式更改带有选项卡的片段的选项卡索引

7

当我试图在片段内以编程方式切换选项卡布局时,出现了空指针异常。

我的主要活动有一个选项卡布局(4个选项卡),每个选项卡都有一个视图页控件,包含一个片段,每个这些片段都有一个选项卡布局(x 个选项卡)和一个视图页控件,我可以从任何片段切换主要活动选项卡布局的选项卡,如下所示:

TabLayout tabLayout = MainActivity.tabLayout;
TabLayout.Tab tab = tabLayout.getTabAt(2);
tab.select();

但是,如果我尝试以同样的方式更改其中一个片段的标签,我会收到一个空指针异常

TabLayout tabLayout2 = tabFragOne.tabLayout;
TabLayout.Tab tab2 = tabLayout2.getTabAt(2);
tab2.select();

只有在应用程序首次打开时单击所涉及的按钮才会发生这种情况,这表明原因是片段尚未附加或创建,
例如,如果我滚动到要切换到的片段选项卡,然后返回到主活动并按下所涉及的按钮,它将起作用。有人知道修复此问题的最佳方法吗?
好的,我已经找到了这个问题的一半关键是我正在使用一个视图分页适配器,一个问题在这里阐明了我的问题。

你能贴出堆栈跟踪吗? - nshmura
你有一个 FragmentPagerAdapter 吗? - Robin Dijkhof
是的,我会的,抱歉我还没有在这里更新,今晚我会提供一个堆栈跟踪和如何将片段附加到片段页适配器以及为什么我正在收到空指针异常的原因。抱歉我一直没有更新@Robin Dijkhof。 - Martin Seal
7个回答

4
正确设置选中的Tab的方法是,我们应该从Pager中设置选中的索引。
final ViewPager pager = (ViewPager) findViewById(R.id.pager);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);

tabLayout.setupWithViewPager(pager);
pager.setCurrentItem(0);//selected position

这是我的XML布局设计:

<android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="#ffffff"
            android:background="@color/al_white"
            android:elevation="0dp" />

       <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            app:tabTextColor="#494a43"
            app:tabSelectedTextColor="#494a43"
            app:tabIndicatorColor="#494a43"
            app:tabIndicatorHeight="2dp"
            app:tabMode="fixed"
            app:tabGravity="fill" />
</android.support.design.widget.AppBarLayout>

当我使用这个时,文本没有像应该一样突出显示,也不像使用getTabAt那样突出显示。 - Martin Seal
@MartinSeal,我不确定你的情况,但我认为你的xml中的TabLayout设计缺少一些配置。我已经添加了我的TabLayout在xml设计中的示例,请检查。 - THANN Phearum

1
TabLayout tabhost = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabhost.getTabAt(2).select();

我在片段的创建函数中使用它,效果非常好。 R.id.tabLayout 是您主活动布局中的选项卡布局ID。

0

自动滚动到第一页的简单示例。注意:我在第一个和最后一个位置添加了一个虚拟片段。

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (position == 0) {
                    viewPager.setCurrentItem(viewPagerAdapter.getCount() - 2);
                } else if (position == viewPagerAdapter.getCount() - 1) {
                    viewPager.setCurrentItem(1);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

这看起来很酷,谢谢。我尝试实现它,但由于需要在哪里调用它,我无法从静态上下文中获取viewPagerAdapter.getCount()。 - Martin Seal

0

使用视图翻页器,它的工作非常简单和良好。

public class ViewPagerAdapter  extends FragmentStatePagerAdapter {

CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs;
String mode;
AllDeals deals;     
MyDeals myDeals;    those are my fragments


public ViewPagerAdapter(FragmentManager fm, int mNumbOfTabsumb, String moe) {
    super(fm);
    this.NumbOfTabs = mNumbOfTabsumb;
    mode=moe;
}

@Override
public Fragment getItem(int position) {

    switch (position) {
        case 0:
            if(mode.equals("Deals")){
                 deals=new AllDeals();
                return deals;
            } 
            break;

        case 1:

            if(mode.equals("Deals")){
                myDeals=new MyDeals();
                return myDeals;
            } 

           break;
        default:
            break;

    }
    return null;
}



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

将以下行添加到您的Activity中。
  containerViewone.setVisibility(View.VISIBLE);
   tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_all_deals)));
                    tabLayout.addTab(tabLayout.newTab().setText(getResources().getString(R.string.title_my_deals)));
                    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
                    tabLayout.setTabTextColors(getResources().getColor(R.color.tabunselect), getResources().getColor(R.color.black));
                    viewpagerad = new ViewPagerAdapter(getSupportFragmentManager(), Numboftabs, "Deals");
                     pager.setAdapter(viewpagerad);
                    pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

0

试试这个:

 TabLayout tablayout;
      @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main); //your activity layout
            tabLayout =(TabLayout)findViewById(R.id.tablayout); //your tab layout id
            tabLayout.getTabAt(0).select(); //your tab index;
    }

这是我目前的做法,但由于持有另一个选项卡布局的片段尚未附加,因此在尝试更改其选项卡位置时会得到空指针,我可以轻松移动主活动选项卡。 - Martin Seal

0

你可以在ViewPager中使用setCurrentItem(Position)方法,例如:

tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
// tabLayout.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(4);

0
在 Kotlin 中: 使用 TabLayout 和 ViewPager2 对我很有效:
binding.tablayout.getTabAt(1)!!.select()

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