2012-05-07 101 views
9

我有一個FragmentStatePageAdapter(我用作ViewPager的適配器)和操作欄中的菜單項的問題。FragmentStatePageAdapter重複ActionBar菜單項

當我啓動應用程序時,一切都很好。如果我將任務移動到背景(例如,按HOME按鈕),我開始做些事情直到活動結束,然後當我回到我的應用程序(通過啓動器或創建的通知)時,一切都很好,除了有複製操作欄中的菜單項。

重要的細節是唯一重複的項目是在ViewPager中使用的每個片段的onCreateOptionsMenu()中創建的項目。

如果我用FragmentPageAdapter替換FragmentStatePageAdapter,項目不會重複,但片段不會在ViewPager中顯示(getItem()函數從適配器永遠不會調用,因此它不會返回任何片段)。

任何想法?一種避免FragmentStatePageAdapter重複菜單項的方法?也許使用FragmentPageAdapter,但修改後顯示片段?我的片段中的修改?

下面是我的一些應用程序的代碼片段...

如何片段內創建菜單項:

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    /* Create play button */ 
    final MenuItem mPlay = menu.add(R.string.play_all); 

    mPlay.setIcon(R.drawable.ic_play_all); 
    mPlay.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

    mPlay.setOnMenuItemClickListener(new OnMenuItemClickListener() { 
     @Override 
     public boolean onMenuItemClick(MenuItem item) { 
      final List<Song> songs = getSongs(); 

      if (songs.size() == 0) { 
       /* Show message */ 
       Toast.makeText(mContext, R.string.no_song_list, Toast.LENGTH_LONG).show(); 
      } else { 
       /* Play song list */ 
       try { PlayManager.getService().playList(songs); } catch (Exception e) {} 
      } 

      return false; 
     } 
    }); 

    /* Create menu */ 
    super.onCreateOptionsMenu(menu, inflater); 
} 

如何片段在ViewPager適配器

被實例化
@Override 
public Fragment getItem(int position) { 
    final Class<?> cls = mTabs.get(position); 

    /* No tab */ 
    if (cls == null) 
     return null; 

    /* Instantiate fragment */ 
    final Fragment fragment = Fragment.instantiate(mContext, cls.getName(), null); 

    /* Add to list */ 
    mFragments.put(position, fragment); 

    /* Return fragment */ 
    return fragment; 
} 

謝謝!我嘗試將activity的launchMode更改爲「singleTop」,並且我還嘗試在getItem()中返回之前創建的片段(但這沒用,因爲getItem()在返回到應用程序時從不會調用,如我之前所說)。

+0

你好,米格爾!你找到解決方案嗎? – HighFlyer

+0

是的。我剛剛發佈了我使用的解決方案。這不是一個真正的解決方法,而是一種解決方法。 –

回答

3

在發佈我的問題幾天後,我發現我的問題的解決方案。我很抱歉這麼晚了。

下面的代碼固定我的問題:

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    outState.remove("android:support:fragments"); 
} 

就這麼簡單編寫的代碼在我實例化並使用所述片段的活性。

我希望這有助於:)

+0

太棒了! :)另一種解決方案:在尋呼機的片段上調用setRetainInstance(true)。 – HighFlyer

+0

我將不得不嘗試一個:) –

+0

經過一些實驗後,似乎outState.remove不能與屏幕旋轉一起工作,因爲FragmentStatePageAdapter在狀態恢復時使用此信息。 setRetainInstance(true)也不適用於從後臺啓動應用程序。 – HighFlyer

2

我認爲問題在於每次滑動時FragmentStatePagerAdapter都會創建一個新的Fragment。因此,爲每個創建的Fragment調用onCreateOptionsMenu()。

還有,我認爲,兩種解決方案:

  1. 採取的操作杆操縱出來的片段。不要爲片段內的菜單項設置onclick,而是從Activity中向當前片段發送消息。

  2. 使用Menu.findItem()來查看另一個Fragment是否已經添加了你想要的MenuItem,如果是的話,將當前的Fragment附加到它(在onPrepareOptionsMenu())。

+0

這不是原因。我第一次啓動應用程序,當我刷卡時,它完美的工作。當我滑動時,從我移動的片段創建的項目將被刪除,並且我移動到的片段中的項目將被添加。只有當活動在後臺關閉時我纔會再次啓動它。 –

3

在片段中ViewPager內膨脹的選項菜單之前,檢查片段實例是否可見,以防止重複菜單項:

// This should be in your Fragment implementation 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
{ 
    if(isVisible()) 
    { 
     inflater.inflate(R.menu.menu_fragment, menu); 
    } 
    super.onCreateOptionsMenu(menu, inflater); 
} 
+0

你的代碼可以幫助我克服重複的問題,但它不會改變片段。 – Roon13

0

我找到了一些解決方案嘗試也可能是工作

在您的重複菜單片段 之前充氣菜單文件添加menu.clear()onCreateOptionsMenu(Menu menu, MenuInflater inflater)

@Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     menu.clear(); 
     inflater.inflate(R.menu.main,menu); 
    }