我正在使用新的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,希望这是一个更好的解决方案,但我很难弄清楚如何将这个实现到我的活动中。 有谁可以帮我弄清楚如何实现这个?感谢。
答案 0 :(得分:4)
更新:从支持库的22.2.1开始,问题已修复,不再需要使用下面提到的解决方法保存/恢复视图状态
不要使用NavigationView.SavedState
NavigationView
是saveEnabled
设置为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
存储来自项目的检查状态的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
的一部分:是公开的,因此它是可见的,但是因为它是内部类,所以不应该在包外访问的支持库。除此之外,来自该功能的捆绑包是错误的,因为它是问题的根源。