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

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


    <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. 效果如下
    在这里插入图片描述

添加动画

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

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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/10490.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

六个阶段形成CRM销售漏斗,优点有哪些

CRM销售漏斗是反映机会状态以及销售效率的重要的销售管理模型。对企业来说&#xff0c;CRM销售漏斗是一个必不可少的工具。通过销售漏斗&#xff0c;企业可以跟踪和分析客户旅程的每个阶段&#xff0c;并制定相应的销售战略。下面来说说&#xff0c;什么是CRM销售漏斗&#xff…

Nginx

文章目录一、目录结构二、多进程模型和请求基本流程三、基础配置3.1 最小配置文件3.2 servername的多种匹配方式3.2.1完整匹配3.2.2通配符匹配3.2.3通配符结束匹配3.2.4正则匹配四、反向代理4.1 反向代理到外网与内网主机的配置4.2 负载均衡配置五、动静分离六、URLRewrite 伪静…

C-关键字(下)

文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…

运行时内存数据区之虚拟机栈——动态链接、方法返回地址与一些附加信息

动态链接&#xff08;Dynamic Linking&#xff09;——指向运行时常量池的方法引用 每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(Dynamic Linking)。比如&#xff1a;invokedynamic指令。…

( “树” 之 DFS) 101. 对称二叉树 ——【Leetcode每日一题】

101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&#xff1a…

聚焦元宇宙赋能产业,打造数字世界,“OFweek2023广州元宇宙产业发展高峰论坛”圆满落幕!

2023年4月12日下午&#xff0c;由广东潮域科技有限公司、OFweek维科网共同主办&#xff0c;OFweek人工智能网承办的“OFweek 2023 广州元宇宙产业发展高峰论坛”在广州保利世贸博览馆1号馆盛大举办。 元宇宙产业相关技术及设备&#xff0c;包括VR&#xff0f;AR、虚拟现实、物联…

springboot配置跨域问题

近期自己搭建项目时&#xff0c;遇到一个跨域问题。我们以前项目解决跨域是在controller上加一个跨域注解CrossOrigin(allowCredentials "true")&#xff0c;很方便。但是在我自己搭建的项目中&#xff0c;启动时竟然报错了&#xff0c;错误如下&#xff1a; When …

不会写代码也能做自动化?推荐一款自动化测试神器

在软件测试这条道路上&#xff0c;大部分的职业技能发展道路都会是纯业务手工测试→自动化测试→性能测试→安全测试/测试开发。 但是却有着一部分人起初进入软件测试这一行看重的就是软件测试属于IT行业&#xff0c;门槛比较低&#xff0c;不需要代码基础。 这就导致了这一部…

第07章_面向对象编程(进阶)

第07章_面向对象编程(进阶) 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 关键字&#xff1a;this 1.1 this是什么&#xff1f; 在Java中&#xff0c;this关键字不算难理解…

<数据结构> 链表 - 单链表(c语言实现)

B.最简单结构的链表——不带哨兵位单链表的实现&#xff08;关于哨兵位结点&#xff09; 一、不带哨兵位单链表结点的创建1.1 typedef 链表的数据类型 1.2 结点的结构体创建 二、单链表要实现的功能 三、需要包含的头文件四、函数接口一览为什么有些函数参数传递的是二级指针&a…

【大数据之Hadoop】十一、MapReduce之Shuffle、MapTask、ReduceTask工作机制

1 Shuffle机制 对于排序而言分为两个阶段&#xff0c;MapTask后和ReduceTask前。 2 MapTask工作机制 MapTask并行度由切片个数决定&#xff1b;切片个数由切片大小&#xff08;切片大小取决于块大小、maxsize&#xff08;Long的最大值&#xff09;和minsize&#xff08;默认为…

设计模式之模板模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、模板模式是什么&#xff1f; 模板模式是一种行为型的软件设计模式&#xff0c;在父类中定义了一个模板算法&#xff0c;只实现…

Android---MVC/MVP/MVVM的演进

目录 一个文件打天下 一个文件--->MVC MVC--->MVP MVP--->MVVM 6大设计原则 完整demo 我们通过"#字棋"游戏来展现MVC-->MVP-->MVVM 之间的演进 一个文件打天下 数据、视图以及逻辑都放在一个 class 里面。而一个 class 里最多 500 行代码&…

GPT-4 和ChatGPT API的定价分析

OpenAI发布了他们的ChatGPT新机器学习模型GPT-4。GPT-4是GPT-3的一大进步&#xff0c;GPT-3是当前ChatGPT免费版本(GPT 3.5 Turbo)所运行的模型的基础&#xff0c;今天我们也来凑个热点&#xff0c;研究一下它们的定价 GPT-4新的功能 GPT-4可以在对话中使用图像&#xff0c;并…

Mybatis(七)Mybatis的日志体系

在介绍Mybatis日志实现前&#xff0c;我们先了解下java的日志体系以及日志框架的发展&#xff0c;目前比较常用的日志框架有下面几个&#xff1a; 而JCL和SLF4J属于日志接口&#xff08;没有日志具体实现&#xff09;&#xff0c;提供统一的日志操作规范&#xff0c;而日志的实…

NumPy 秘籍中文第二版:四、将 NumPy 与世界的其他地方连接

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍以下秘籍&#xff1a; 使用缓冲区协议使用数组接口与 MATLAB 和 Octave 交换数据安装 RPy2与 R 交互安装 JPype将 NumPy 数组发送到 J…

什么是Lambda表达式?

什么是Lambda表达式 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式&#xff1a;它没有名称&#xff0c;但它有参数列表、函数主体、返回类型&#xff0c;可能还有一个可以抛出的异常列表。 匿名&#xff1a;它不像普通的方法那样有一个明确的名称&#xff1…

GPT 任务指令 = 定义角色 + 背景信息 + 任务目标 + 输出要求

GPT 任务指令 定义角色 背景信息 任务目标 输出要求 环境 GPT-4 0. 你是一名专业的导游&#xff0c;负责为我生成旅游计划&#xff0c;现在我来北京旅游&#xff0c;需要你为我生成一份 3天2晚的北京旅游规划。我的要求是&#xff1a;1.地点包括故宫、军播和环球影城。 2…

pytorch搭建ResNet50实现鸟类识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客 &#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第J1周&#xff1a;ResNet-50算法实战与解析 &#x1f356; 作者&#xff1a;K同学啊 理论知识储备 深度残差网络ResNet&#xff08;dee…

OceanBase 4.1 发版 | 一个面向开发者的里程碑版本

欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 2022 年 8 月&#xff0c;OceanBase发布了 4.0 版本&#xff08;小鱼&#xff09;&#xff0c;作为业内首个单机分布式一体化架构&#xff0c;兼顾了分布式架构的扩展性和集中式架构的性能优势&…