2014-08-30 92 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

相關問題