spa*_*ist 12 navigation android android-fragments navigation-drawer onbackpressed
什么是在按下后处理导航抽屉的选定状态的正确方法?
我有一个带有n个条目的导航抽屉(在列表视图中),就像Android Studio中的SDK示例一样.当我点击导航抽屉条目时,我希望它们被添加到后台堆栈,所以我可以回到它们.
在onNavigationDrawerItemSelected(int pos)我有
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (position == 0) {
transaction.replace(R.id.container, new FragmentA());
} else if (position == 1) {
transaction.replace(R.id.container, new FragmentB());
} else {
transaction.replace(R.id.container, new FragmentC());
}
transaction.addToBackStack(null);
transaction.commit();
Run Code Online (Sandbox Code Playgroud)
当我点击抽屉中的第二个条目时,B被选中并替换A.如果我之后单击后退按钮,片段A将再次显示,但仍然在导航抽屉中选择了B.
如何在按下后更新抽屉的选择状态?
不知怎的,我需要调用mDrawerListView.setItemChecked(position,true); 或NavigationDrawerFragment.selectItem(int position).但到了哪个位置?我怎么记得呢?
拦截onBackPressed?
@Override
public void onBackPressed() {}
Run Code Online (Sandbox Code Playgroud)
但我怎么知道哪个片段再次活跃?它对应于哪个位置.
有一些简单的解决方案我是盲目的看到的吗?似乎与导航抽屉结合使用并更新选择状态是标准模式.
"正确返回导航"文档的" 实现碎片的后退导航"部分中描述了此模式.
如果您的应用程序更新其他用户界面元素以反映片段的当前状态(例如操作栏),请记住在提交事务时更新UI.除了提交事务之外,您应该在后台堆栈更改后更新用户界面.您可以
FragmentTransaction通过设置以下内容来监听 恢复时间FragmentManager.OnBackStackChangedListener:
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
// Update your UI here.
}
});
Run Code Online (Sandbox Code Playgroud)
这将是刷新导航抽屉中当前选项的适当位置.
小智 6
今天我也有同样的挣扎。我通过FragmentToActivity在每个片段以及我唯一的MainActivity中实现一个接口来解决它。
接口:
public interface FragmentToActivity {
public void SetNavState(int id);
}
Run Code Online (Sandbox Code Playgroud)
片段:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
((FragmentToActivity) getActivity()).SetNavState(R.id.nav_myitemid); //just add this line
}
Run Code Online (Sandbox Code Playgroud)
主要活动:
@Override
public void SetNavState(int id) {
NavigationView nav = (NavigationView) findViewById(R.id.nav_view);
nav.setCheckedItem(id);
}
Run Code Online (Sandbox Code Playgroud)
如果您不知道它的R.id.nav_myitemid来源,这里是我的activity_main_drawer.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_myitemid"
android:title="@string/home" />
</group>
</menu>
Run Code Online (Sandbox Code Playgroud)
小智 5
我试图找出这个问题的解决方案有很多麻烦,我最终使用的解决方案在我看来并不"好",但它确实有效.
在我的应用程序中,当我将片段添加到backstack时,我最终在导航抽屉中添加了片段位置.这样我可以使用onBackStackChanged()中的位置调用setItemChecked.基本上我做的是这样的:
@Override
public void onBackStackChanged() {
FragmentManager fm = getFragmentManager();
String name = fm.getBackStackEntryAt(fm.getBackStackEntryCount()-1).getName();
mDrawerList.setItemChecked(Integer.parseInt(name),true);
}
public class DrawerItemClickListener implements android.widget.AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment;
switch (position) {
case 0: // Home
fragment = new ContentFragment();
break;
case 1: // Another
fragment = new AnotherFragment();
break;
default: // Logout
{
finish();
Intent intent = new Intent(this, StartupActivity.class);
startActivity(intent);
return;
}
}
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack(Integer.toString(position))
.commit();
mDrawerList.setItemChecked(position, true);
setTitle(mNavigationItems[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Run Code Online (Sandbox Code Playgroud)