Android:为什么在创建选项卡时会调用onTabSelected?

时间:2014-08-30 00:21:19

标签: android android-activity tabs

当操作栏有标签时,我注意到当活动在屏幕上加载时会调用onTabSelected。每当发生方向改变时也会调用它。我的代码根据所选的选项卡查询数据库,并将查询结果显示给加载的布局。

我的问题是在恢复状态下保存选项卡状态,当前选中的选项卡为1或更高,因为默认情况下在0选项卡上调用onTabSelected,当恢复状态选项卡为1或更高时,将再次调用它。这使得选项卡0上的数据库查询无效。

如何配置安卓选项卡上没有调用onTabSelected的android,或者至少检测到此调用是默认的而不是用户触发的?

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    int tabPos = tab.getPosition();
    switch(tabPos) {
    case 0:
        // query database and display result
        break;
    case 1:
        // a different query and display result
        break;
    case 2: ...
    }
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    if(savedInstanceState.containsKey(STATE_SELECTED_TAB)) {
        getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_TAB));
    }
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putInt(STATE_SELECTED_TAB, getActionBar().getSelectedNavigationIndex());
    super.onSaveInstanceState(outState);
}

<击> 添加了并发症: 当前选定的选项卡为0且方向发生变化时,onTabSelected仍会被调用两次!一旦最初创建选项卡,第二次onRestoreState恢复保存的选项卡选择状态,即使它是0。

我最初的假设是onTabSelected被调用两次,但我错了。这是我的片段onCreateView被调用两次,片段事务中的一些错误在方向更改时添加了两次相同的片段。 onTabSelected被调用一次,当恢复的选项卡也为0时,也会调用onTabReselected的恢复状态调用。


在搜索SO和谷歌之后,我发现这个问题有类似的问题原因。 Creating ActionBar tab also calling its selectTab functions

3 个答案:

答案 0 :(得分:10)

因此,在从Google的Android网站上查看ActionBar上的参考文档后,addTab方法是负责默认调用onTabSelected的方法。

public abstract void addTab (ActionBar.Tab tab)

添加选项卡以在选项卡式导航模式中使用。该选项卡将添加到列表的末尾。如果这是第一个要添加的选项卡,它将成为选定的选项卡。

<强>参数
标签标签添加

顺便提一下,存在其他不调用onTabSelected的重载方法。

public abstract void addTab (ActionBar.Tab tab, boolean setSelected)

所以我使用了这些替代方法,并修复了问题。 但是,一旦显示选项卡,第一个选项卡可能会显示为选中,即使它不是。单击它将调用onTabSelected而不是onTabReselected。

答案 1 :(得分:1)

我以这种方式解决了:

setupWithViewPager之前致电tabLayout.addOnTabSelectedListener

tabLayout.setupWithViewPager(viewPager)

tabLayout.addOnTabSelectedListener(object :  TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {....}
.....
}
  

因为当您调用 setupWithViewPager 时,它将在内部调用    setOnTabSelectedListener(新   ViewPagerOnTabSelectedListener(viewPager));

因此最好在将tabSelect侦听器添加到tabLayout之前调用它

答案 2 :(得分:0)

我认为你可以这样做(并且请忽略任何拼写:-)):

public class MainActivity extends FragmentActivity {

boolean isConfigChanged;
int savedTabIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     if(savedInstanceState != null){
        if(savedInstanceState.containsKey(STATE_SELECTED_TAB)) {
            savedTabIndex = savedInstanceState.getInt(STATE_SELECTED_TAB);
          //getActionBar().setSelectedNavigationItem(savedTabIndex); actually you do not need this
        }
        isConfigChanged = true;
    }

   // here add actionbar tabs

//...}

并在:

下面的代码会检查configuration是否更改且用户选择的标签是not zero所以这是默认调用而忽略但是如果isConfigChanged == true且用户选择的标签为0,则{{1或者如果must query DB您必须查询数据库,因为它是第一次加载应用程序。快速游戏可能适合你想要的东西。

isConfigChanged == false

删除onRestore

   @Override
   public void onTabSelected(Tab tab, FragmentTransaction ft) {
    if(isConfigChanged && savedTabIndex != 0){
       isConfigChanged = false;
       return;
     }
    isConfigChanged = false;
    int tabPos = tab.getPosition();
    switch(tabPos) {
    case 0:
        // query database and display result
        break;
    case 1:
        // a different query and display result
        break;
    case 2: ...
    }
  }