具有从Drawerlayout过渡的Android导航组件 [英] Android Navigation Component with Transition from Drawerlayout

查看:142
本文介绍了具有从Drawerlayout过渡的Android导航组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用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.

  1. 添加带抽屉的布局.示例:

<?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>

  1. 通过ID查找NavigationView,并将其分配给活动中的变量private NavigationView navigationView,您可以使用findViewById(R.id.nav_view)进行提取.此步骤是可选的.您可能会发现视图和关联导航项选择侦听器而没有对NavigationView的引用;
  2. 设置导航项选择侦听器:
  1. Find NavigationView by ID and assign it to a variable private NavigationView navigationView in your activity, that you may extract by using findViewById(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;
  2. 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函数(如setupWithNavControllersetupActionBarWithNavController)的调用.原因是在每个导航器后面都添加了另一个目标更改的侦听器到导航控制器.有关更多信息,请参见 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.

              1. 第一次通话会添加new ToolbarOnDestinationChangedListener(toolbar, configuration);
              2. 第二次调用添加了NavController.OnDestinationChangedListener的自定义实现,可正确更新抽屉中的导航视图;
              3. 第三次通话添加new ActionBarOnDestinationChangedListener(activity, configuration).
              1. First call adds new ToolbarOnDestinationChangedListener(toolbar, configuration);
              2. Second call adds custom implementation of NavController.OnDestinationChangedListener that updates your navigation view in drawer correctly;
              3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆