android jetpack Navigation的使用(java)

简介

Navigation通过图形化的方式管理配置页面的切换。

基本使用

  1. 添加依赖
    implementation 'androidx.navigation:navigation-fragment:2.5.3'
    implementation 'androidx.navigation:navigation-ui:2.5.3'
  1. 创建xml文件(添加导航图)——nav_graph.xml
    android jetpack Navigation的使用(java)_第1张图片
    android jetpack Navigation的使用(java)_第2张图片
    nav_graph.xml
<?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"
             android:id="@+id/nav_graph">


</navigation>
  1. 向activity中添加NavHost
    通过activity的xml布局文件添加FragmentContainerView和NavHostFragment。
    app:navGraph 将NavHostFragment与导航图关联
    app:defaultNavHost=“true” 使得NavHostFragment 会响应系统的返回点击事件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

</LinearLayout>
  1. 在导航图中添加目的地
    这里添加了BlankFragment。
    app:startDestination 起始目的地,第一次进入看到的界面
    android jetpack Navigation的使用(java)_第3张图片

  2. 目的地建立联系
    拖住圆圈到目的fragment,自动建立联系。
    android jetpack Navigation的使用(java)_第4张图片
    建立联系后,xml变化如下

<?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/nav_graph"
    app:startDestination="@id/blankFragment">


    <activity
        android:id="@+id/mainActivity"
        android:name="cn.jn.mytest.MainActivity"
        android:label="MainActivity" />


    <fragment
        android:id="@+id/blankFragment"
        android:name="cn.jn.mytest.BlankFragment"
        android:label="fragment_blank"
        tools:layout="@layout/fragment_blank" >
        <action
            android:id="@+id/action_blankFragment_to_cragment2"
            app:destination="@id/cragment" />
    </fragment>

    <fragment
        android:id="@+id/cragment"
        android:name="cn.jn.mytest.Cragment"
        android:label="fragment_cragment"
        tools:layout="@layout/fragment_cragment" />
</navigation>
  1. 导航到目的地

6.1 在activity中使用NavController进行导航
nav_host_fragment为FragmentContainerView

        NavHostFragment navHostFragment =
                (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
        NavController navController = navHostFragment.getNavController();

6.2 使用插件Safe Args导航,在项目build.gradle文件中添加配置.

plugins {
    id 'com.android.application' version '7.4.2' apply false
    id 'com.android.library' version '7.4.2' apply false

    id 'androidx.navigation.safeargs' version '2.5.3' apply false
}

在app下的build.gradle文件中添加配置

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

android {
	........
}

配置好后,Safe Args会根据nav_graph.xml文件生成代码。生成的类的名称由源目的地类的名称和“Directions”一词组成。根据上面的设置,我要在BlankFragment跳转到cragment,生成类的名字就是BlankFragmentDirections,BlankFragmentDirections中的方法,名称组成:action开头+源目的地名称+to+目的地名称,我这边生成的方法名为actionBlankFragmentToCragment。通过BlankFragmentDirections获取NavDirections,再将其传到navigate中,就完成了跳转。

在BlankFragment中的跳转如下

        Button blank_but_jump = view.findViewById(R.id.blank_but_jump);

        blank_but_jump.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                NavDirections action =
                        BlankFragmentDirections.actionBlankFragmentToCragment();
                Navigation.findNavController(v).navigate(action);
            }
        });

6.3 带参数的Safe Args导航
在导航图中给blankFragment添加参数argument。

    <fragment
        android:id="@+id/blankFragment"
        android:name="cn.jn.mytest.BlankFragment"
        android:label="fragment_blank"
        tools:layout="@layout/fragment_blank">

        <action
            android:id="@+id/action_blankFragment_to_cragment"
            app:destination="@id/cragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popExitAnim="@anim/slide_out_right">

            <argument
                android:name="testA"
                android:defaultValue="0"
                app:argType="integer" />
        </action>

    </fragment>

跳转+参数

  BlankFragmentDirections.ActionBlankFragmentToCragment actionBlankFragmentToCragment = BlankFragmentDirections.actionBlankFragmentToCragment();
                actionBlankFragmentToCragment.setTestA(1);
                Navigation.findNavController(v).navigate(actionBlankFragmentToCragment);

接收

        Bundle bundle = getArguments();
        if (bundle != null) {

            int testA = bundle.getInt("testA");
            Log.d("aaaaaa", testA + "");
        }
  1. 效果如下
    android jetpack Navigation的使用(java)_第5张图片

添加动画

动画文件自己创建
android jetpack Navigation的使用(java)_第6张图片

deeklink

通过pendingIntent,跳转到应用程序的某个页面。

  1. 通过通知跳转fragmment
    在导航图中添加了一个fragment,当做点击通知时的跳转页面。
<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/nav_graph"
    app:startDestination="@id/blankFragment">
   
   ......
   
    <fragment
        android:id="@+id/notifyFragment"
        android:name="cn.jn.mytest.NotiFragment"
        android:label="fragment_notify"
        tools:layout="@layout/fragment_notify" />
</navigation>

在BlankFragment,创建Notification。如果项目的targetSdk =33,则需要声明和动态申请android.permission.POST_NOTIFICATIONS的权限。

public class BlankFragment extends Fragment {


    private ActivityResultLauncher<String> activityResultLauncher;

    public BlankFragment() {
        // Required empty public constructor
    }

    public static BlankFragment newInstance(String param1, String param2) {
        BlankFragment fragment = new BlankFragment();
        return fragment;
    }


    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        activityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
            @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
            @Override
            public void onActivityResult(Boolean result) {

                if (result) {

                    Log.d("权限", "已授权");
                } else {

                    Log.d("权限", "未授权");
                }
            }
        });
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        Button blank_but_jump = view.findViewById(R.id.blank_but_jump);

        blank_but_jump.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //系统版本大于等于33
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {

                    NotificationManager notificationManagerCompat = requireContext().getSystemService(NotificationManager.class);
                    //检测是否允许了权限
                    boolean b = notificationManagerCompat.areNotificationsEnabled();
                    if (!b) {
                        //请求权限
                        activityResultLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
                        return;
                    }
                }

                sendNotify();
            }
        });
    }


	/**
	*通知
	*/
    public void sendNotify() {

        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(requireContext());

        //创建通知通道
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel("MyChannel", "MyChannel", NotificationManager.IMPORTANCE_LOW);
            notificationManagerCompat.createNotificationChannel(notificationChannel);
        }
		//要跳转的fragment
        PendingIntent pendingIntent = new NavDeepLinkBuilder(requireActivity())
                .setGraph(R.navigation.nav_graph)
                .setDestination(R.id.notifyFragment)
                .createPendingIntent();

        Notification notificationCompat = new NotificationCompat.Builder(requireActivity().getApplicationContext(), "MyChannel")
                .setContentTitle("123456")
                .setContentInfo("跳转")
                .setContentIntent(pendingIntent)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setAutoCancel(true)
                .build();

        notificationManagerCompat.notify(1, notificationCompat);
    }
}

你可能感兴趣的:(android,android,jetpack,java)