2015-06-02 66 views
3

我正在使用新的NavigationView,試圖將其實現爲DrawerLayout,並且我想將當前選定的菜單項保存在NavigationView的菜單中。 我知道我可以保存/恢復所選項目「手動」通過保存/恢復我的實例狀態:在導航視圖上保存狀態

public class MyActivity extends AppCompatActivity { 
    private static String STATE_SELECTED_POSITION = "state_selected_position"; 
    private int mCurrentSelectedPosition; 

    private NavigationView mNavigationView; 
    private FrameLayout mContentFrame; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mNavigationView = (NavigationView) findViewById(R.id.navigation_view); 
     mContentFrame = (FrameLayout) findViewById(R.id.content_frame); 

     mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { 
      @Override 
      public boolean onNavigationItemSelected(MenuItem menuItem) { 
       menuItem.setChecked(true); 

       switch(menuItem.getItemId()) { 
        case R.id.navigation_item_1: 
         Snackbar.make(contentFrame, "Item One", Snackbar.LENGTH_SHORT).show(); 
         mCurrentSelectedPosition = 0; 
         return true; 
        case R.id.navigation_item_2: 
         Snackbar.make(contentFrame, "Item Two", Snackbar.LENGTH_SHORT).show(); 
         mCurrentSelectedPosition = 1; 
         return true; 
        default: 
         return false; 
       } 
      } 
     }); 
    } 

    // Saving the currently selected menu item (index). 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition); 
    } 

    // Restoring selected menu item. 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 

     mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION, 0); 
     mNavigationView.getMenu().getItem(mCurrentSelectedPosition).setChecked(true); 
    } 

} 

我偶然發現了NavigationView.SavedState,希望這將是一個更好的解決辦法,但我有麻煩弄清楚如何在我的活動中實現這一點。 任何人都可以幫我弄清楚如何實現這個?謝謝。

回答

4

更新:作爲支持庫的22.2.1的問題已得到修復,並沒有更多的需要保存/低於


不要提到的解決方法恢復視圖狀態使用NavigationView.SavedState

NavigationViewsaveEnabled設置爲true的視圖。 這意味着SavedState應由視圖本身內部使用保存/自動恢復其狀態(例如:在設備旋轉) 不幸的是,視圖有一個確認的錯誤和狀態不保存/恢復正確: https://code.google.com/p/android/issues/detail?id=175224

here你會發現這個問題更一般的解決方法:

public void onSaveInstance(Bundle outState) { 
    ArrayList positions = findSelectedPosition(); 
    if(positions.size()>0) { 
     outState.putIntegerArrayList(STATE_SELECTED_POSITION, positions); 
    } 
} 

private ArrayList findSelectedPosition() { 
    Menu menu = navDrawerFirstPart.getMenu(); 
    int count = menu.size(); 
    ArrayList result = new ArrayList<>(); 
    for (int i = 0; i < count; i++) { 
     if(menu.getItem(i).isChecked()){ 
      result.add(i); 
     } 
    } 
    return result; 
} 

public void onRestoreInstanceState(Bundle savedInstanceState) { 
    if(savedInstanceState.containsKey(STATE_SELECTED_POSITION)){ 
     restoreSelectedPosition(savedInstanceState.getIntegerArrayList(STATE_SELECTED_POSITION)); 
    } 
} 

private void restoreSelectedPosition(ArrayList<Integer> positions) { 
    Menu menu = navDrawerFirstPart.getMenu(); 
    for(int i=0; i<positions.size(); i++){ 
     menu.getItem(positions.get(i)).setChecked(true); 
    } 
} 

使用NavigationView.SavedState將有超過這個解決方案沒有的優點,因爲存儲在它的狀態 ,這是一個簡單的捆綁的NavigationView S其中從這些項目中檢查出檢查狀態的SparseBooleanArray。 除此之外,也開始保存NavigationView內實例的所有過程中的作用是這樣的:

protected Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 
    NavigationView.SavedState state = new NavigationView.SavedState(superState); 
    state.menuState = new Bundle(); 
    this.mMenu.savePresenterStates(state.menuState); 
    return state; 
} 

注意savePresenterStates是一個內部類MenuBuider的一部分:是公共所以它是可見的,但隨後又因爲它是一個內部類,不應該在支持庫的包之外訪問。除此之外,來自該函數的臨時包是錯誤的,因爲它是問題的根源。