2014-08-30 89 views
4

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

我的问题是在还原状态下保存标签状态并且当前选定标签为1或更高时,因为ontab选择在0选项卡上默认调用,当恢复状态标签为1或更高时它将被再次调用。这使得选项卡0上的数据库查询无用。

如何配置Android的onTabSelected没有调用制表符或至少检测到这个调用是默认的,而不是用户触发?

@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被调用一次,并恢复状态调用onTabReselected被称为太当恢复选项卡也为0。


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

回答

10

所以审查从谷歌的Android网站上动作条的参考文档后,addTab方法是一个负责调用默认onTabSelected。

public abstract void addTab (ActionBar.Tab tab) 

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

参数
    标签          选项卡添加

顺便说一下,其他的重载方法存在不叫onTabSelected。

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

因此,我用这些替代方法,而不是修复问题。 但是,一旦显示选项卡,第一个选项卡可能会显示选中,即使它不是。点击它会调用onTabSelected而不是onTabReselected。

+0

我改变标签3的配置,它调用tab1然后tab3 !!! – mmlooloo 2014-08-30 10:21:02

+0

它的工作原理很明显,我们必须在ActionBar(创建阶段)中只设置一个选项卡。 onTabSelected将在setSelected设置为true的每个选项卡上触发。 – 2015-07-07 16:53:23

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您must query DB或如果isConfigChanged == false您必须查询数据库,因为它是第一次加载该应用程序。一个快速的游戏可能适合你想要的东西。

@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: ... 
    } 
    } 

删除OnRestore中

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

我认为你正在那里。但是,我做了更多的测试,问题比我想象的更复杂。例如,如果当前选项卡为0并且方向更改,则onTabSelected会被调用两次!一旦创建了选项卡,并且第二次在onRestoreState恢复选项卡0选择时。我喜欢你的想法,我将不得不为这个刚刚提到的增加的复杂性做出改进。 – 2014-08-30 02:09:06

+0

这是不难处理,如果你不能告诉我编辑我的答案! – mmlooloo 2014-08-30 02:11:12

+0

只是放置另一个标志并将其更改为'case 0:'的块,因此第二次将忽略。 – mmlooloo 2014-08-30 02:13:08

相关问题