使用“Fragments”在“AppCompatActivity”中向上导航
Up navigation in `AppCompatActivity` with `Fragments`
我正在尝试在我的应用程序中设置正确的导航,它取代了主要内容区域中的 Fragment
,因此我只有一个 Activity
。我有一个主 Fragment
和几个子 Fragments
,例如一个 Fragment
用于偏好设置。使用后退按钮时一切正常,但除此之外我还想实现包括图标在内的向上导航。我正在使用通过 Activity.getSupportActionBar()
获取的 ActionBar
以及来自 appcompat 的 Toolbar
和 ActionBarDrawerToggle
.
我一开始就按照 this tutorial 设置 Drawer
。
当前行为:
当我启动应用程序时,list/drawer 图标显示在 ActionBar
的左侧。单击此按钮时,Drawer
打开,我可以 select 项。子 Fragment
被替换到我的内容中,后退按钮弹出堆栈,带我回到之前的 Fragment
。
缺失行为:
左上角的 list/drawer 图标永远不会被后退箭头图标取代,我不知道如何正确实现它。 Drawer
总是 在单击 list/drawer 图标时被拉出,无论我在哪个 Fragment
。
我尝试了什么:
- 我尝试按照 this 回答。它有点工作,这意味着后退箭头图标设置在子
Fragment
中,但单击后退箭头仍会打开 Drawer
而不是提供向上导航。此外,当使用后退按钮转到 "up" 时,list/drawer 图标将被替换为任何内容。
- 我也试过按照 this 回答。这里,想要的
ActionBar
behavior/look是在各个Fragment
的onCreate()
方法中实现的。使用这个我可以让后退箭头向上,但点击箭头时 Drawer
仍然被拉动。
- 其他各种小事和技巧。
我的问题:
- 我下面的代码有什么问题?
- 是否correct/normal使用组合
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);
}
抽屉片段class
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
class 中完成。它只是将内容区域替换为其他 Fragment
s,使用 FragmentTransaction
s.
@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 class
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>
如果您的应用使用 material 设计,那么您应该使用 Toolbar
替换 activity 中的 Actionbar
。您仍将保持 ActionBarDrawerToggle
并且功能将保持不变。
至于你的片段,只要它们是'housed'同一个活动(即activity与抽屉),改变片段不会导致抽屉切换改变后退箭头.它只会在您导航到新的 activity 时发生变化。只有这样,主要的 activity 才会被视为主页,而其他活动将有一个后退箭头可以返回
我正在尝试在我的应用程序中设置正确的导航,它取代了主要内容区域中的 Fragment
,因此我只有一个 Activity
。我有一个主 Fragment
和几个子 Fragments
,例如一个 Fragment
用于偏好设置。使用后退按钮时一切正常,但除此之外我还想实现包括图标在内的向上导航。我正在使用通过 Activity.getSupportActionBar()
获取的 ActionBar
以及来自 appcompat 的 Toolbar
和 ActionBarDrawerToggle
.
我一开始就按照 this tutorial 设置 Drawer
。
当前行为:
当我启动应用程序时,list/drawer 图标显示在 ActionBar
的左侧。单击此按钮时,Drawer
打开,我可以 select 项。子 Fragment
被替换到我的内容中,后退按钮弹出堆栈,带我回到之前的 Fragment
。
缺失行为:
左上角的 list/drawer 图标永远不会被后退箭头图标取代,我不知道如何正确实现它。 Drawer
总是 在单击 list/drawer 图标时被拉出,无论我在哪个 Fragment
。
我尝试了什么:
- 我尝试按照 this 回答。它有点工作,这意味着后退箭头图标设置在子
Fragment
中,但单击后退箭头仍会打开Drawer
而不是提供向上导航。此外,当使用后退按钮转到 "up" 时,list/drawer 图标将被替换为任何内容。 - 我也试过按照 this 回答。这里,想要的
ActionBar
behavior/look是在各个Fragment
的onCreate()
方法中实现的。使用这个我可以让后退箭头向上,但点击箭头时Drawer
仍然被拉动。 - 其他各种小事和技巧。
我的问题:
- 我下面的代码有什么问题?
- 是否correct/normal使用组合
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);
}
抽屉片段class
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
class 中完成。它只是将内容区域替换为其他 Fragment
s,使用 FragmentTransaction
s.
@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 class
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>
如果您的应用使用 material 设计,那么您应该使用 Toolbar
替换 activity 中的 Actionbar
。您仍将保持 ActionBarDrawerToggle
并且功能将保持不变。
至于你的片段,只要它们是'housed'同一个活动(即activity与抽屉),改变片段不会导致抽屉切换改变后退箭头.它只会在您导航到新的 activity 时发生变化。只有这样,主要的 activity 才会被视为主页,而其他活动将有一个后退箭头可以返回