JetPack-Navigation(二)

一、使用safe args传递参数

1.1 、常见的参数传递

  //跳转到第二个Fragment
        mBtnToSecondFragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设置动画
                NavOptions options = new NavOptions.Builder()
                        .setEnterAnim(android.R.anim.fade_in)
                        .setExitAnim(android.R.anim.fade_out)
                        .setPopEnterAnim(android.R.anim.fade_in)
                        .setPopExitAnim(android.R.anim.fade_out)
                        .build();
                //传递参数
                Bundle bundle = new Bundle();
                bundle.putString("name","android");
                bundle.putInt("age",30);
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_secondFragment,bundle,options);
            }
        });

参数接收:

    private void initData() {
        //接收参数
        Bundle bundle = getArguments();
        if (bundle != null) {
            String name = bundle.getString("name");
            int age = bundle.getInt("age");
            Log.e(TAG, "Name is :" + name);
        }

    }

1.2、使用safe args传递参数

(1)、添加插件的依赖(在Project的build gradle)中添加依赖

def nav = "2.3.0-alpha01"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav"

(2)、在app的build gradle添加对safe args的依赖

plugins {
    id 'com.android.application'
    id 'androidx.navigation.safeargs'
}

(3)、在导航图中添加标签

   <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.navigationdemo.MainFragment"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_secondFragment"
            app:destination="@id/secondFragment"/>

<--  添加参数 -->
        <argument
            android:name="user_name"
            android:defaultValue="unknow"
            app:argType="string" />
        <argument
            android:name="user_age"
            android:defaultValue="0"
            app:argType="integer" />
    </fragment>

(4)、在Fragment中传递参数

    //跳转到第二个Fragment
        mBtnToSecondFragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //设置动画
                NavOptions options = new NavOptions.Builder()
                        .setEnterAnim(android.R.anim.fade_in)
                        .setExitAnim(android.R.anim.fade_out)
                        .setPopEnterAnim(android.R.anim.fade_in)
                        .setPopExitAnim(android.R.anim.fade_out)
                        .build();
                Bundle bundle = new MainFragmentArgs.Builder()
                        .setUserName("android jetpack")
                        .setUserAge(22)
                        .build().toBundle();
                Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_secondFragment,bundle,options);
            }
        });

(5)、接收参数

   private void initData() {
        //接收参数
            String name = MainFragmentArgs.fromBundle(getArguments()).getUserName();
            int age = MainFragmentArgs.fromBundle(getArguments()).getUserAge();
            Log.e(TAG, "Name is :" + name);

    }

二、NavigationUI的使用方法

2.1、NavigationUI存在的意义

  导航图是Navigation组件中重要的一部分,它可以帮助我们快速了解页面之间的关系,再通过NavController完成页面的切换工作。而在页面切换过程中,通常还伴随App bar中menu菜单的变化,对于不同的界面,App bar中的menukennel是不一样的,App bar中的各种按钮和菜单,同样承担着页面切换工作。例如,当ActionBar左边的返回按钮被点击时,我们需要响应点击事件返回上一个页面。为了方便管理Navigation和App bar的页面切换事件,JetPack引入NavigationUI组件,使App bar中的按钮和菜单能够与导航图中的页面关联起来。

2.2、NavigationUI的使用

2.2.1、Case说明:

  在NavigationUIActivity中有两个Fragment(MainUiFragment和SettingFragment),我们在MainUiFragment右边有一个ActionBar去跳转到SettingFragment,在SettingFragment左侧有一个返回按钮,能够返回MainUiFragment。

2.2.2、目录结构

在这里插入图片描述

2.2.3、Case使用说明

(1)、新建navigation文件graph_navui_activity,并新建两个destination(MainUiFragment和SettingFragment),默认加载为MainUiFragment

<?xml version="1.0" encoding="utf-8"?>
<navigation 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/graph_navui_activity"
    app:startDestination="@id/mainUiFragment">

    <fragment
        android:id="@+id/mainUiFragment"
        android:name="com.example.navigationdemo.testnavigationui.MainUiFragment"
        android:label="fragment_main_ui"
        tools:layout="@layout/fragment_main_ui">

    </fragment>
    <fragment
        android:id="@+id/settingFragment"
        android:name="com.example.navigationdemo.testnavigationui.SettingFragment"
        android:label="fragment_setting"
        tools:layout="@layout/fragment_setting" />
</navigation>

(2)、新建菜单文件main_menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/settingFragment"
    android:icon="@mipmap/ic_launcher"
    android:title="设置" />
</menu>

ATTENTION
  这里要特别注意: 的id与导航图中(graph_navui_activity)的settingFragment的ID要保持一致。这表示,当被点击时,将会跳转到id对应的fragment。

(3)、在Activity中初始化菜单

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

(4)、使用NavigationUI响应菜单点击事件

public class NavigationUIActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;
    private NavController mNavController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigation_uiactivity);

        //用于页面的导航和切换
        mNavController = Navigation.findNavController(this, R.id.fragment_nav_ui_container);
        //用于App bar的配置
        mAppBarConfiguration = new AppBarConfiguration.Builder(mNavController.getGraph()).build();
        //将app bar与NavController绑定
        NavigationUI.setupActionBarWithNavController(this, mNavController, mAppBarConfiguration);

        mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(@NonNull  NavController controller, @NonNull  NavDestination destination,  Bundle arguments) {
                //收到切换事件
            }
        });

    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        return NavigationUI.onNavDestinationSelected(item,mNavController) || super.onOptionsItemSelected(item);
    }

   @Override
    public boolean onSupportNavigateUp() {
        return NavigationUI.navigateUp(mNavController,mAppBarConfiguration) || super.onSupportNavigateUp();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }
}

说明
(1)、由于在导航图和菜单的布局文件中,我们已经把settingFragment设置好了相同的id,因此,在onOptionsItemSelected() 方法中,通过NavigationUI可自动完成页面跳转。
(2)、覆盖onSupportNavigateUp()方法,当我们在settingFragment中单击ActionBar中的返回按钮,NavigationUI会自动返回MainFragment
(3)、AppBarConfiguration用于App bar的配置,NavController用于页面的导航和切换。再通过

NavigationUI.setupActionBarWithNavController(this, mNavController,
mAppBarConfiguration);

将App bar和NavController绑定起来。

(5)、去除settingFragment中的菜单

public class SettingFragment extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_setting, container, false);
    }

    @Override
    public void onCreateOptionsMenu(@NonNull  Menu menu, @NonNull  MenuInflater inflater) {
        menu.clear();
        super.onCreateOptionsMenu(menu, inflater);
    }
}

(6)、接收切换通知

NavigationUI在帮助我们完成页面的切换,我们希望能够在切换时得到通知,可通过OnDestinationChangedListener对页面切换事件进行监听

 mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(@NonNull  NavController controller, @NonNull  NavDestination destination,  Bundle arguments) {
                //收到切换事件
            }
        });

2.3、NavigationUI的配套使用

NavigationUI对3中类型的App Bar提供支持。

  • ActionBar
  • ToolBar
  • CollaspingToolbarLayout

除了常见的menu菜单,NavigationUI还可以配合另外两种菜单使用。

  • App bar左侧的抽屉菜单(DrawLayout+NavigationUI)
  • 底部菜单(BottomNavigationView)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值