具有从Drawerlayout过渡的Android导航组件 [英] Android Navigation Component with Transition from Drawerlayout
问题描述
是否可以使用android导航组件从抽屉布局中打开片段来更改过渡效果. android文档中什么都没有.
Is it possible to change the transition effect from opening a fragment from a drawerlayout with the android navigation component. There is nothing in the android docs.
推荐答案
萨拉!对的,这是可能的.您可以添加自定义侦听器来处理导航项的选择,并在其中添加动画.为了其他目的,我不得不添加一个自己,但这绝对适合您的任务.
Sarah! Yes, it is possible. You can add your custom listener to handle navigation item selection and add animation there. I had to add one myself, for other purposes, but it definitely fits as a solution for your task.
- 添加带抽屉的布局.示例:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Other views can be added here, or below -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/menu_for_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
- 通过ID查找
NavigationView
,并将其分配给活动中的变量private NavigationView navigationView
,您可以使用findViewById(R.id.nav_view)
进行提取.此步骤是可选的.您可能会发现视图和关联导航项选择侦听器而没有对NavigationView的引用; - 设置导航项选择侦听器:
- Find
NavigationView
by ID and assign it to a variableprivate NavigationView navigationView
in your activity, that you may extract by usingfindViewById(R.id.nav_view)
. This step is optional. You may find the view and assing naviation item selection listener without holding a reference to NavigationView; - Set navigation item selection listener:
navigationView.setNavigationItemSelectedListener(menuItem -> {
@IdRes
int id = menuItem.getItemId();
NavOptions.Builder optionsBuilder = new NavOptions.Builder();
switch (id) {
case R.id.first_menu_item_id: {
// Lets assume for the first menu item navigation is default
optionsBuilder
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim);
}
break;
case R.id.second_menu_item_id: {
// Lets assume for the second menu item navigation is missing
// empty here
}
break;
case R.id.thrid_menu_item_id: {
// Lets assume for the third menu item navigation is custom
optionsBuilder
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right);
}
break;
}
navController.navigate(id, null, optionsBuilder.build());
// Do not forget to close the drawer
// drawer.closeDrawers();
return true;
});
这应该有所帮助!任何想法和问题都欢迎!
This should help! Any thoughts and questions are welcome!
如果您对示例中提到的动画感兴趣:
In case you are interested in animations mentioned in example:
-
slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
-
slide_in_right.xml
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
-
slide_out_left.xml
slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
-
slide_out_right.xml
slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="300"/>
</set>
更新(2020年3月28日)
如果此解决方案不适用于抽屉菜单",请尝试通过以下代码 使用它.
请注意,由于NavigationUI
函数有时设置它自己的监听器,因此我将setNavigationItemSelectedListener
调用放置在方法的末尾.那也可能是问题的原因.
Note that I placed setNavigationItemSelectedListener
call at the end of the method due to NavigationUI
functions sometimes settings it's own listener. That could also be the cause of problem.
NavigationUI
函数后面有很多事情,如果某些方法不起作用,请检查您使用的函数的实现.
There is a lot going on behind NavigationUI
functions and if something doesn't work right check out implementation of the functions you use.
private void setupNavigation() {
// Set custom toolbar as action bar
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
// Setup navigation with toolbar and drawer
NavController navController = Navigation.findNavController(this, R.id.main_nav_host_fragment);
/* The set of destinations by id considered at the top level
of your information hierarchy. The Up button will not be displayed
when on these destinations. */
Set<Integer> set = new HashSet<>(Arrays.asList(R.id.first_fragmentId_from_nav_graph, R.id.second_fragmentId_from_nav_graph, R.id.third_fragmentId_from_nav_graph));
/* Configuration options for {@link NavigationUI} methods that interact with implementations of the
app bar pattern */
AppBarConfiguration configuration = new AppBarConfiguration.Builder(set).setDrawerLayout(drawer).build();
NavigationUI.setupWithNavController(toolbar, navController, configuration);
NavigationUI.setupWithNavController(navigationView, navController);
NavigationUI.setupActionBarWithNavController(this, navController, configuration);
// And here you set the listener.
navigationView.setNavigationItemSelectedListener(...);
}
有多个对NavigationUI
函数(如setupWithNavController
和setupActionBarWithNavController
)的调用.原因是在每个导航器后面都添加了另一个目标更改的侦听器到导航控制器.有关更多信息,请参见 addOnDestinationChangedListener 关于收听者.
There are multiple calls to NavigationUI
functions like setupWithNavController
and setupActionBarWithNavController
. The reason is that behind each one of them is added one more destination changed listener to navigation controller. See addOnDestinationChangedListener for more information about the listener.
- 第一次通话会添加
new ToolbarOnDestinationChangedListener(toolbar, configuration)
; - 第二次调用添加了
NavController.OnDestinationChangedListener
的自定义实现,可正确更新抽屉中的导航视图; - 第三次通话添加
new ActionBarOnDestinationChangedListener(activity, configuration)
.
- First call adds
new ToolbarOnDestinationChangedListener(toolbar, configuration)
; - Second call adds custom implementation of
NavController.OnDestinationChangedListener
that updates your navigation view in drawer correctly; - Third call adds
new ActionBarOnDestinationChangedListener(activity, configuration)
.
此配置使我可以在具有Master-Detail模式的平板电脑上使用单个应用程序,而在手机上使用Drawer Menu则可以在电话上正常使用该应用程序.
This configuration allows me to use single application on a tablet with Master-Detail pattern and on the phone as usual application with Drawer Menu.
引用的字符串资源只是:
Referenced string resources are just:
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
但是可访问性是必需的.如果您支持多种语言,将它们翻译是非常好的.基本上,任何用于可访问性的东西通常都很好翻译.
But they are required for accessibility. It's very good to translate them if you support multiple languages. Basically anything used for accessibility is generally good to translate.
这篇关于具有从Drawerlayout过渡的Android导航组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!