Jetpack之Navgation和Fragment

本文介绍了Jetpack中的Navgation组件,旨在解决Fragment开发中的回退栈和参数传递问题。Navgation包括导航图、NavHost和NavController三大核心组件。通过创建NavGraph、声明NavHost和NavController,可以实现Fragment间的导航。NavHostFragment在onCreate时创建NavController,并管理Fragment的回退栈。同时,文章探讨了NavController的创建时机、Fragment回退栈的实现以及不同Navigator的添加方式。
摘要由CSDN通过智能技术生成

一、简述

Jetpack中的Navgation和SystemUI中的NavgationBar导航栏并不是一个东西。在Jetpack中的Navgation是为了适配Fragment而诞生的,在当今Android开发中,Fragment的优点在于轻量、可控制性强,但其相较与Activity而言,仍然有着其弊端,如:Activity的回退栈以及页面的参数传递。此时Navgation正是为了适配Fragment开发而推出的。此篇仅仅简单介绍Navgation的使用,原理下篇叙述。

二、Navgation介绍

2.1 Navgation三大件:

1、导航图:用于指明从源页面跳转的页面或者目的地。
2、NavHost:显示导航图中目标的空白容器。导航组件包含一个默认 NavHost 实现 (NavHostFragment),可显示Fragment 目标,说白了就是存放Fragment等控件的容器。
3、NavController:在 NavHost 中管理应用导航的对象。当用户在整个应用中移动时,NavController 会安排NavHost 中目标内容的交换。

2.2 优点

   处理 Fragment 事务。
   默认情况下,正确处理往返操作。
   为动画和转换提供标准化资源。
   实现和处理深层链接。
   包括导航界面模式(例如抽屉式导航栏和底部导航),用户只需完成极少的额外工作。
   Safe Args - 可在目标之间导航和传递数据时提供类型安全的 Gradle 插件。
   ViewModel 支持 - 您可以将 ViewModel 的范围限定为导航图,以在图表的目标之间共享与界面相关的数据。

2.3 使用Navgation

(1)导入Navgation依赖

    def nav_version = "2.3.0"
    // Java language implementation
    implementation "androidx.navigation:navigation-fragment:$nav_version"
    implementation "androidx.navigation:navigation-ui:$nav_version"

(2)创建导航图
在这里插入图片描述
在这里插入图片描述
这里必须要声明app:startDestination属性指明首次启动时加载的Fragment
Action标签指明跳转的目的地,也可以在fragment中声明Action,但仅此表示从fragmentX ----> fragmentY;
若像下列在fragment外定义action标签,则便是任意fragment都可以跳转到该action中的destination。

注意:并非只能声明fragment标签,也可以是activity、dialog控件。
<?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/fragment_a">

    <action
        android:id="@+id/to_fragmenta"
        app:destination="@+id/fragment_a"
        app:enterAnim="@anim/nav_default_enter_anim"
        app:exitAnim="@anim/nav_default_exit_anim">
    </action>
    <action
        android:id="@+id/to_fragmentb"
        app:destination="@+id/fragment_b"
        app:enterAnim="@anim/nav_default_enter_anim"
        app:exitAnim="@anim/nav_default_exit_anim">
    </action>
    <action
        android:id="@+id/to_fragmentc"
        app:destination="@+id/fragment_c"
        app:enterAnim="@anim/nav_default_enter_anim"
        app:exitAnim="@anim/nav_default_exit_anim">
    </action>
    <action
        android:id="@+id/to_fragmentd"
        app:destination="@+id/fragment_d"
        app:enterAnim="@anim/nav_default_enter_anim"
        app:exitAnim="@anim/nav_default_exit_anim">
    </action>
    <action
        android:id="@+id/to_fragmente"
        app:destination="@+id/fragment_e"
        app:enterAnim="@anim/nav_default_enter_anim"
        app:exitAnim="@anim/nav_default_exit_anim">
    </action>

    <fragment
        android:id="@+id/fragment_a"
        android:name="com.example.navigatinandfragment.FragmentA"
        android:label="bfragment"
        tools:layout="@layout/fragment_a">
    </fragment>
    <fragment
        android:id="@+id/fragment_b"
        android:name="com.example.navigatinandfragment.FragmentA"
        android:label="cfragment"
        tools:layout="@layout/fragment_b">
        <!--为destination提供深层链接技术-->
        <deepLink app:uri="www.YourWebsite.com/{
   mn_params}"/>
    </fragment>
    <fragment
        android:id="@+id/fragment_c"
        android:name="com.example.navigatinandfragment.FragmentA"
        android:label="dfragment"
        tools:layout="@layout/fragment_c">
    </fragment>
    <fragment
        android:id="@+id/fragment_d"
        android:name="com.example.navigatinandfragment.FragmentA"
        android:label="dfragment"
        tools:layout="@layout/fragment_d">
    </fragment>
    <fragment
        android:id="@+id/fragment_e"
        android:name="com.example.navigatinandfragment.FragmentA"
        android:label="efragment"
        tools:layout="@layout/fragment_e">
    </fragment>

</navigation>

(3)声明NavHost,app:defaultNavHost="true"属性很关键,功能是让fragment拦截back按键,实现回退栈

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

    <fragment
        android:id="@+id/fragment_nav"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"/>
    <!--让fragment拦截back按键,实现回退栈-->
    
<!--Activity的底部导航栏,同微信界面中底部导航栏-->
   <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_height="50dp"
        android:layout_width="match_parent"
        android:id="@+id/buttom"
        android:background="@android:color/white"
        android:layout_alignParentBottom="true"
        app:itemIconTint="@drawable/select"
        app:itemTextColor="@drawable/select"
        app:menu="@menu/meni"
        app:labelVisibilityMode="labeled">
<!--此属性是为了防止导航栏Item超过3个时不显示title-->
    </com.google.android.material.bottomnavigation.BottomNavigationView>

(4)创建NavController,绑定NavGraph和底部导航栏

public class MainActivity extends AppCompatActivity {
   
    BottomNavigationView bottom;
    NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bottom = findViewById(R.id.buttom);
        navController = Navigation.findNavController(this,R.id.fragment_nav);
        //NavigationUI类  是用来对AppBar和navController进行绑定
        NavigationUI.setupWithNavController(bottom,navController);
    }
//        button.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
   
//            @Override
//            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
   
//                switch (menuItem.getItemId()){
   
//                    case R.id.bfragment:
//                        navController.navigate(
//                                R.id.to_bfragment);
//                        break;
//                    case R.id.cfragment:
//                        navController.navigate(
//                                R.id.to_cfragment);
//                        break;
//                    case R.id.dfragment:
//                        navController.navigate(
//                                R.id.to_dfragment);
//                        break;
//                    case R.id.efragment:
//                        navController.navigate(
//                                R.id.to_efragment);
//                        break;
//                    case R.id.afragment:
//                        navController.navigate(
//                                R.id.to_afragment);
//                        break;
//                }
//
//                return true;
//            }
//        });
}

(5)Fragment之间传递数据、实现深度链接技术

public class FragmentA extends Fragment {
   
    Button button;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
   
        return inflater.inflate(R.layout.fragment_a,container);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
   
        super.onViewCreated(view, savedInstanceState);
        button = view.findViewById(R.id.btn);
        button.setOnClickListener(new View.OnClickListener() {
   
            @Override
            public void onClick(View v) {
   
                sendNotifacation();
            }
        });
    }

    private void sendNotifacation() {
   
        if(getActivity() == null){
   
            return;
        }
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
   
            NotificationManager manager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel notificationChannel = new NotificationChannel("1","Channel_name",NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setDescription("desc");
            manager.createNotificationChannel(notificationChannel);
        }

        NotificationCompat.Builder notification = new NotificationCompat.Builder(getActivity(),"1")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("Navigation_And_Fragment")
                .setContentText("Hello World!")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(getPendingIntent())
                .setAutoCancel
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值