【JetPack】Navigation知识点总结

ops/2024/12/26 0:22:59/

Navigation的主要元素:

1、Navigation 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"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/my_nav_graph"app:startDestination="@id/homeFragment"><fragmentandroid:id="@+id/homeFragment"android:name="com.example.navigation.HomeFragment"android:label="fragment_home"tools:layout="@layout/fragment_home" ><actionandroid:id="@+id/action_homeFragment_to_detailFragment"app:destination="@id/detailFragment" /></fragment><fragmentandroid:id="@+id/detailFragment"android:name="com.example.navigation.DetailFragment"android:label="fragment_detail"tools:layout="@layout/fragment_detail" ><actionandroid:id="@+id/action_detailFragment_to_homeFragment"app:destination="@id/homeFragment" /></fragment>
</navigation>

2、NavHostFragment:
一个特殊的Fragment,可以将它看作是其他Fragment的容器,Navigation Graph中的Fragment正是通过NavHostFragment进行展示的。
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/fragmentContainerView"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="409dp"android:layout_height="729dp"app:defaultNavHost="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/my_nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

3、NavController:
用于在代码中完成Navigation Graph中具体的页面切换工作。

MainActivity.java
public class MainActivity extends AppCompatActivity {NavController navController;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 这样写会报错// NavController navController = Navigation.findNavController(this, R.id.fragmentContainerView);// 需要先通过id获取到对应的NavHostFragment容器NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);if (navHostFragment != null) {// 如果不为空,再获取到的容器对应的NavControllernavController = navHostFragment.getNavController();} else {throw new RuntimeException("NavHostFragment not found");}// 该代码的主要目的是将 ActionBar(或 Toolbar)与 NavController 关联起来,以便在使用 Android 导航组件时,ActionBar 可以自动更新其显示内容NavigationUI.setupActionBarWithNavController(this, navController);}@Overridepublic boolean onSupportNavigateUp() {// header上返回按键好用return navController.navigateUp();}
}
HomeFragment.java
@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);Button button = getView().findViewById(R.id.button);button.setOnClickListener(view -> {// 由于最外层设置了NavController,所以这里可以通过容器中的view找到NavControllerNavController navController = Navigation.findNavController(view);// 通过NavController进行导航,确定目的地navController.navigate(R.id.action_homeFragment_to_detailFragment);});}
DetailFragment.java
@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);Button button = getView().findViewById(R.id.button2);button.setOnClickListener((v)->{// 由于最外层设置了NavController,所以这里可以通过容器中的view找到NavControllerNavController navController = Navigation.findNavController(v);// 通过NavController进行导航,确定目的地navController.navigate(R.id.action_detailFragment_to_homeFragment);});}

三者之间的关系
当你想切换Fragment时,使用NavController对象,告诉它你想要去Nlavigation Graph中的哪个Fragment,NavController会将你想去的Fragment展示NavHostFragment中
实现顺序
1.创建Fragment
2.创建navgation_graph,指定fragment切换逻辑
3.在Activity的页面中添加navHostFragmrnt容器进行界面显示
4.在Activity中通过navHostFragmrnt获取到navController,并设置bar和fragment的对应关系,以及bar上返回按键生效
5.在需要触发fragment切换的位置通过获取navController进行导航,设置对应的action,确认触发后目的地
添加页面切换动画
在这里插入图片描述

页面之间参数传递
方法一:直接传递bundle对象(接收数据时需要知道对应key值以及value类型,并且需要判空)

        Bundle bundle = new Bundle();bundle.putString("user_name", "Jay");NavController navController = Navigation.findNavController(view);navController.navigate(R.id.action_homeFragment_to_detailFragment, bundle);

接收bundle对象

		Bundle arguments = getArguments();String userName = null;if (arguments != null) {userName = arguments.getString("user_name");Log.d("userName", "" + userName);}

方法二:引入arg插件

		dependencies {// 添加 safe-arg 插件依赖classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.4.0")}plugins {id 'androidx.navigation.safeargs'}
        Bundle bundle = new HomeFragmentArgs.Builder().setUserName("Jay").setAge(20).build().toBundle();HomeFragmentArgs args = HomeFragmentArgs.fromBundle(getArguments());String username = args.getUserName();int age = args.getAge();Log.d("Test", "userName = " + userName + "age = " + age);

NavigationUI的使用场景
Fragment切换时,设计到AppBar上的内容显示,为了方便统一管理引入NavigationUI

public class MainActivity extends AppCompatActivity {private NavController navController;private AppBarConfiguration appBarConfiguration;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);if (navHostFragment != null) {navController = navHostFragment.getNavController();}appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();// 将Appbar与Navigation建立联系NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {super.onCreateOptionsMenu(menu);getMenuInflater().inflate(R.menu.menu_settings, menu);return true;}// 响应Meun的点击事件@Overridepublic boolean onOptionsItemSelected(@NonNull MenuItem item) {return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item);}// 响应AppBar的返回按键@Overridepublic boolean onSupportNavigateUp() {return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp();}
}

跳转后的假面不显示meun

    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {setHasOptionsMenu(true);return inflater.inflate(R.layout.fragment_setting, container, false);}@Overridepublic void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {menu.clear();super.onCreateOptionsMenu(menu, inflater);}

监听页面切换完成的回调

        // 监听界面切换完成navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {@Overridepublic void onDestinationChanged(@NonNull NavController navController, @NonNull NavDestination navDestination, @Nullable Bundle bundle) {Log.d("test","onDestinationChanged");}});

深层链接DeepLink之PendingIntent

private void sendNotifycation() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel myChannel = new NotificationChannel(getActivity().getPackageName(), "MyChannel", NotificationManager.IMPORTANCE_DEFAULT);myChannel.setDescription("My NotificationChannel");NotificationManager notificationManager = getActivity().getSystemService(NotificationManager.class);notificationManager.createNotificationChannel(myChannel);}NotificationCompat.Builder builder = new NotificationCompat.Builder(getActivity(), getActivity().getPackageName()).setSmallIcon(R.drawable.ic_launcher_background).setContentTitle("Deep Link").setContentText("点我").setPriority(NotificationManager.IMPORTANCE_DEFAULT).setContentIntent(getPendingIntent());// 发送通知NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getActivity());if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling//    ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding//   public void onRequestPermissionsResult(int requestCode, String[] permissions,//                                          int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}notificationManager.notify(notifyId++, builder.build());}private PendingIntent getPendingIntent() {Bundle bundle = new Bundle();bundle.putString("name","Jay");return Navigation.findNavController(getActivity(),R.id.button).createDeepLink().setGraph(R.navigation.my_nav_graph).setDestination(R.id.detailFragment).setArguments(bundle).createPendingIntent();}

深层链接DeepLink之Url


http://www.ppmy.cn/ops/144972.html

相关文章

MySQL什么情况下会导致索引失效

MySQL什么情况下会导致索引失效 索引&#xff08;Index&#xff09;是数据库中一种用于快速查找和访问表中数据的结构&#xff0c;它类似于书的目录&#xff0c;通过索引可以快速定位到目标数据&#xff0c;而无需遍历整个表&#xff0c;索引的存在可以显著提高查询速度&#x…

[工具]GitHub Copilot 直接提供免费额度了

有福了&#xff01; GitHub Copilot 直接提供免费额度——每个月享 2000个代码提示完成额度&#xff08;每个工作日大约80个&#xff09;&#xff0c;以及 50个聊天请求。后台是访问 GPT-4o 和 Claude 3.5 Sonnet 模型。 插件支持VS Code、VS 2022、JetBrains、... 这下 Curs…

Java 重写(Override)与重载(Overload)

重写 (Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写&#xff01;返回值和形参都不能改变。即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于子类可以根据需要&#xff0c;定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。…

【漏洞复现】CVE-2021-45788 SQL Injection

漏洞信息 NVD - cve-2021-45788 Time-based SQL Injection vulnerabilities were found in Metersphere v1.15.4 via the “orders” parameter. Authenticated users can control the parameters in the “order by” statement, which causing SQL injection. API: /test…

前端对页面数据进行缓存

页面录入信息&#xff0c;退出且未提交状态下&#xff0c;前端对页面数据进行存储 前端做缓存&#xff0c;一般放在local、session和cookies里面&#xff0c;但是都有大小限制&#xff0c;如果页面东西多&#xff0c;比如有上传的图片、视频&#xff0c;浏览器会抛出一个Quota…

【AIStarter:项目管理平台】Krita 5.2.6 + AI 1.29 + ComfyUI 插件:创作与效率的完美结合

引言 在数字艺术创作的世界里&#xff0c;工具的选择往往决定了作品的质量和创作的效率。对于追求高效与便捷的艺术家们来说&#xff0c;Krita 5.2.6、AI 1.29 和 ComfyUI 插件的组合无疑是一套理想的解决方案。这套集成了最新技术的软件套装&#xff0c;不仅提供了强大的绘图…

用友-友数聚科技CPAS审计管理系统V4 downPlugs存在任意文件下载漏洞

免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…

Odoo 免费开源 ERP:通过 JavaScript 创建对话框窗口的技术实践分享

作者 | 老杨 出品 | 上海开源智造软件有限公司&#xff08;OSCG&#xff09; 概述 在本文中&#xff0c;我们将深入研讨如何于 Odoo 18 中构建 JavaScript&#xff08;JS&#xff09;对话框或弹出窗口。对话框乃是展现重要讯息、确认用户操作以及警示用户留意警告或错误的行…