> 文章列表 > android jetpack Navigation的使用(java)

android jetpack Navigation的使用(java)

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
    在这里插入图片描述
    在这里插入图片描述
    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.FragmentContainerViewandroid: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 起始目的地,第一次进入看到的界面
    在这里插入图片描述

  2. 目的地建立联系
    拖住圆圈到目的fragment,自动建立联系。
    在这里插入图片描述
    建立联系后,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"><activityandroid:id="@+id/mainActivity"android:name="cn.jn.mytest.MainActivity"android:label="MainActivity" /><fragmentandroid:id="@+id/blankFragment"android:name="cn.jn.mytest.BlankFragment"android:label="fragment_blank"tools:layout="@layout/fragment_blank" ><actionandroid:id="@+id/action_blankFragment_to_cragment2"app:destination="@id/cragment" /></fragment><fragmentandroid: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 falseid 'com.android.library' version '7.4.2' apply falseid '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() {@Overridepublic void onClick(View v) {NavDirections action =BlankFragmentDirections.actionBlankFragmentToCragment();Navigation.findNavController(v).navigate(action);}});

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

    <fragmentandroid:id="@+id/blankFragment"android:name="cn.jn.mytest.BlankFragment"android:label="fragment_blank"tools:layout="@layout/fragment_blank"><actionandroid: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"><argumentandroid: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. 效果如下
    在这里插入图片描述

添加动画

动画文件自己创建
在这里插入图片描述

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">......<fragmentandroid: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;}@Overridepublic void onAttach(@NonNull Context context) {super.onAttach(context);activityResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)@Overridepublic void onActivityResult(Boolean result) {if (result) {Log.d("权限", "已授权");} else {Log.d("权限", "未授权");}}});}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_blank, container, false);}@Overridepublic 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() {@Overridepublic void onClick(View v) {//系统版本大于等于33if (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);}//要跳转的fragmentPendingIntent 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);}
}