2012-07-19 25 views
0

背景:如何防止雙重addtobackstack同時PreferencesFragment在android系統

我使用PreferencesFragment在我的Android應用程序來管理的喜好和我使用選項菜單來訪問這些首選項。

MainActivity類別重寫的方法:

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch(item.getItemId()){ 
    case R.id.menu_prefs: 
     PrefsFragment prefs = new PrefsFragment(); 
     getFragmentManager() 
      .beginTransaction() 
      .replace(R.id.main_container, prefs) 
      .addToBackStack(null) 
      .commit(); 
     break; 
    } 
    return true; 
} 

RES /菜單/ menu.xml文件:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android" > 

<item 
    android:id="@+id/menu_prefs" 
    android:icon="@android:drawable/ic_menu_preferences" 
    android:title="@string/menu_prefs_title" 
    android:showAsAction="ifRoom|withText"> 
</item> 

</menu> 

問題:

  • 當在主屏幕上,我點擊操作欄中的偏好圖標,PrefsFragment開始。
  • 雖然在PrefsFragment上,我單擊操作欄中的偏好圖標PrefsFragment開始再次(這是出現問題的地方)。
  • 我點擊後退按鈕,它恢復片段交易並返回PrefsFragment。 (它應該回到主屏幕)。

問: 有沒有什麼聰明的辦法禁止雙顯示PrefsFragment?

期望的結果: 單擊首選項在操作欄圖標,如果在主屏幕上顯示PrefsFragement,點擊操作欄的首選項圖標,而PrefsFragemnt可見什麼也不做,單擊後退按鈕,同時PrefsFragment一直追溯到主屏幕。

回答

1

好了,經過一些挖我這樣做:

我禁用操作欄/選項菜單,如果PrefsFragemnt是可見的(我在這裏可以添加不同的菜單,但禁用它在這工作正常案件 )。

PrefsFragment.java

import android.os.Bundle; 
import android.preference.PreferenceFragment; 

public class PrefsFragment extends PreferenceFragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.prefs); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     getActivity().invalidateOptionsMenu(); 
    } 
} 

MainActivity.java(重寫的方法):

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    PrefsFragment prefs = (PrefsFragment)getFragmentManager().findFragmentByTag("PREFS"); 
    if (prefs != null){ 
     if (prefs.isVisible()) { 
      return true; 
     } 
    } 

    getMenuInflater().inflate(R.menu.menu, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch(item.getItemId()){ 
    case R.id.menu_prefs: 
     PrefsFragment prefs = new PrefsFragment(); 
     FragmentManager manager = getFragmentManager(); 
     manager 
      .beginTransaction() 
      .replace(R.id.main_container, prefs, "PREFS") 
      .addToBackStack(null) 
      .commit(); 
     manager.executePendingTransactions(); 
     invalidateOptionsMenu(); 
     break; 
    } 
    return true; 
} 

最重要的部分是呼籲按鈕點擊manager.executePendingTransactions()invalidateOptionsMenu(),並呼籲invalidateOptionsMenu()停車時分段。這會導致菜單被刷新,當我們進入首選項並離開它們之後,會進行更新。

如果你有更好的解決方案,我會愛看到他們,因爲這一個感覺有點有點hackish給我。

+0

Grzegorz,不錯的工作:-)。對於這個非常常見的用例,shame android沒有任何「內置」的東西。 – Hector 2013-07-23 12:29:32