当前位置: 首页 > article >正文

【JetPack】Navigation知识点总结

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

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.navigation.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_detailFragment"
            app:destination="@id/detailFragment" />
    </fragment>
    <fragment
        android:id="@+id/detailFragment"
        android:name="com.example.navigation.DetailFragment"
        android:label="fragment_detail"
        tools:layout="@layout/fragment_detail" >
        <action
            android: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.FragmentContainerView
        android: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;
    @Override
    protected 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) {
       		 // 如果不为空,再获取到的容器对应的NavController
            navController = navHostFragment.getNavController();
        } else {
            throw new RuntimeException("NavHostFragment not found");
        }
        // 该代码的主要目的是将 ActionBar(或 Toolbar)与 NavController 关联起来,以便在使用 Android 导航组件时,ActionBar 可以自动更新其显示内容
        NavigationUI.setupActionBarWithNavController(this, navController);
    }
    
    @Override
    public boolean onSupportNavigateUp() {
        // header上返回按键好用
        return navController.navigateUp();
    }
}
HomeFragment.java
@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Button button = getView().findViewById(R.id.button);
        button.setOnClickListener(view -> {
        	// 由于最外层设置了NavController,所以这里可以通过容器中的view找到NavController
            NavController navController = Navigation.findNavController(view);
            // 通过NavController进行导航,确定目的地
            navController.navigate(R.id.action_homeFragment_to_detailFragment);
        });
    }
DetailFragment.java
@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Button button = getView().findViewById(R.id.button2);
        button.setOnClickListener((v)->{
            // 由于最外层设置了NavController,所以这里可以通过容器中的view找到NavController
            NavController 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;

    @Override
    protected 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);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_settings, menu);
        return true;
    }
    // 响应Meun的点击事件
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item);
    }
    // 响应AppBar的返回按键
    @Override
    public 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);
    }

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

监听页面切换完成的回调

        // 监听界面切换完成
        navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public 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.kler.cn/a/450579.html

相关文章:

  • 【C++】模板与泛型编程(一):定义模板,成员模板
  • ubuntu 网络管理
  • I.MX6U 启动方式详解
  • 项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”
  • 3.4 stm32系列:定时器(PWM、定时中断)
  • 24.12.23 注解
  • 【es6复习笔记】解构赋值(2)
  • 【算法】一维二维数组前缀和,以及计算二维矩阵中的子矩阵和
  • Docker-如何启动docker
  • 使用Python开发PPT图片提取与九宫格合并工具
  • 京东物流营销 Agent:智能驱动,物流新篇(13/30)
  • 面对小白的C语言学习方法
  • C++进阶(二)--面向对象--继承
  • 设计模式的主要分类是什么?请简要介绍每个分类的特点。
  • 服务器中了挖矿病毒-应急响应
  • 活着就好20241225
  • ctf相关总结
  • StartAI图生图局部重绘,让画面细节焕发新生!!
  • 基于单片机(如 51 单片机)实现十字路口交通灯控制电路的设计方案示例
  • 【Vue3+ts入门小试牛刀】
  • [机器学习]sklearn入门指南(2)
  • Elasticsearch介绍及安装部署
  • CentOs安装Nginx
  • Ubuntu系统部署程序:修改IP、部署docker、nginx、Redis、onlyoffice、java
  • git Force Push失败:unable to access解决方案
  • python web知识点梳理