【发布时间】:2015-09-02 13:24:30
【问题描述】:
我正在尝试在我的应用程序中设置正确的导航,它替换了主要内容区域中的Fragments,所以我只有一个Activity。我有一个主要的Fragment 和几个子Fragments,例如一个Fragment 用于偏好。使用后退按钮时一切正常,但我想实现包括图标在内的向上导航。我正在使用通过Activity.getSupportActionBar() 获取的ActionBar 以及来自appcompat 的Toolbar 和ActionBarDrawerToggle。
一开始我在设置Drawer 时关注了this tutorial。
当前行为:
当我启动应用程序时,列表/抽屉图标显示在ActionBar 的左侧。当我单击它时,Drawer 打开,我可以选择项目。子Fragments 被替换到我的内容中,后退按钮弹出堆栈,带我回到之前的Fragment。
缺失行为:
左上角的列表/抽屉图标永远不会被后退箭头图标取代,我无法弄清楚如何正确实现这一点。在单击列表/抽屉图标时,Drawer总是被拉出,无论我在哪个Fragment。
我尝试了什么:
- 我尝试关注this 的回答。它有点工作,这意味着后退箭头图标设置在子
Fragments 中,但单击后退箭头仍会打开Drawer,而不是提供向上导航。此外,当使用后退按钮“向上”时,列表/抽屉图标被替换为空。 - 我也尝试关注this 的回答。在这里,所需的
ActionBar行为/外观在各种Fragments 的onCreate()方法中实现。使用这个我可以让后退箭头向上,但单击箭头时仍然会拉动Drawer。 - 其他各种小事和小技巧。
我的问题:
- 下面的代码有什么问题?
- 使用
ActionBar、Toolbar和ActionBarDrawerToggle的组合来实现Drawer导航和向上导航是否正确/正常?
MyActivity.onCreate():
@Override
protected void onCreate(Bundle savedInstanceState)
{
// Other stuff
// Setup drawer.
mDrawerFragment = (DrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.mm_navigation_drawer);
mDrawerFragment.initialize(this, (DrawerLayout)findViewById(R.id.mm_drawer_layout), toolbar);
}
DrawerFragment 类
public class DrawerFragment extends Fragment
{
private MyActivity mMyActivity;
private MyActionBarDrawerToggle mMyBarDrawerToggle;
private DrawerLayout mDrawerLayout;
private FragmentDrawerListener mFragmentDrawerListener;
private View mContainerView;
public void initialize(MyActivity myActivity, final DrawerLayout drawerLayout, final Toolbar toolbar)
{
mMyActivity = myActivity;
mFragmentDrawerListener = mMyActivity;
mContainerView = myActivity.findViewById(R.id.mm_navigation_drawer);
mMyActionBarDrawerToggle = new MyActionBarDrawerToggle(myActivity, drawerLayout, toolbar, R.string.mm_drawer_open, R.string.mm_drawer_close);
mDrawerLayout = drawerLayout;
mDrawerLayout.setDrawerListener(mMyActionBarDrawerToggle);
mDrawerLayout.post(new Runnable()
{
@Override
public void run()
{
mMyActionBarDrawerToggle.syncState();
}
});
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState)
{
// Not relevant, just create and return the View.
}
}
MyActivity.onDrawerItemSelected()
接口FragmentDrawerListener的实现在MyActivity类中完成。它只是将内容区域替换为其他Fragments,使用FragmentTransactions。
@Override
public void onDrawerItemSelected(View view, int postion)
{
switch (postion)
{
case DrawerAdapter.ITEM_FILTERED_RECIPES:
showFilteredRecipesFragment();
break;
case DrawerAdapter.ITEM_SELECTED_RECIPES:
showSelectedRecipesFragment();
break;
case DrawerAdapter.ITEM_SHOPPING_LIST:
showShoppingListFragment();
break;
case DrawerAdapter.ITEM_SETTINGS:
showSettingsFragment();
break;
case DrawerAdapter.ITEM_ABOUT:
showAboutFragment();
break;
}
}
MyActionBarDrawerToggle 类
public class MyActionBarDrawerToggle extends ActionBarDrawerToggle
{
private MyActivity mMyActivity;
private Toolbar mToolbar;
public MyActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes)
{
super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);
mMyActivity = (MyActivity) activity;
mToolbar = toolbar;
}
@Override
public void onDrawerOpened(View drawerView)
{
super.onDrawerOpened(drawerView);
mMyActivity.invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView)
{
super.onDrawerClosed(drawerView);
mMyActivity.invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset)
{
super.onDrawerSlide(drawerView, slideOffset);
mToolbar.setAlpha(1 - slideOffset / 2);
}
}
DrawerFragment 在主布局中使用简单的静态Fragment 实例进行膨胀,如下所示:
<fragment
android:id="@+id/my_navigation_drawer"
android:name="com.my.company.gui.drawer.DrawerFragment"
android:layout_width="@dimen/my_nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/my_drawer_navigation_fragment"
tools:layout="@layout/my_drawer_navigation_fragment">
</fragment>
【问题讨论】:
标签: android android-fragments navigation