Android架构之Navigation组件(三)

Jetpack组件系列文章
Android架构之LifeCycle组件
Android架构之Navigation组件(一)
Android架构之Navigation组件(二)
Android架构之Navigation组件(三)
Android架构之Navigation组件(四)
Android架构之ViewModel组件
Android架构之LiveData组件
Android架构之Room组件(一)
Android架构之Room组件(二)
Android架构之WorkManager组件
Android架构之DataBinding(一)
Android架构之DataBinding(二)
Android架构之Paging组件(一)
Android架构之Paging组件(二)
Jetpack与MVVM架构

Navigation结合ToorBar 使用

我们要完成的效果如下:

初始化界面如下
在这里插入图片描述
点击按钮跳转到OtherFragment,页面如下
在这里插入图片描述
点击返回键,并且返回toorbarFragment。

在使用Toorbar之间,需要将主题设置为NoActionBar

编写toor_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/toor_graph"
    tools:ignore="UnusedNavigation"
    app:startDestination="@id/toorbarFragment">

    <fragment
        android:id="@+id/toorbarFragment"
        android:name="com.example.jetpack.ToorbarFragment"
        android:label="fragment_toorbar"
        tools:layout="@layout/fragment_toorbar" />
    <fragment
        android:id="@+id/toOtherFragment"
        android:name="com.example.jetpack.toOtherFragment"
        android:label="fragment_to_other"
        tools:layout="@layout/fragment_to_other" />
</navigation>

我们将起始目的地设置为toorbarFragment。

activity_toorbar.xml布局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ToorbarActivity"
    android:orientation="vertical">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        app:title="Material Design"
        app:titleTextColor="@android:color/white"
        >
    </androidx.appcompat.widget.Toolbar>
    <fragment
        android:id="@+id/nav_toorbar_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost= "true"
        app:navGraph="@navigation/toor_graph"/>
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="跳转"/>
</LinearLayout>

ToorbarActivity代码

public class ToorbarActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toorbar);

        //获取NavController对象
        final NavController navController = Navigation.findNavController(this,R.id.nav_toorbar_fragment);
        //获取App bar对象 设置顶级目的地
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        //获取Toorbar 对象
        final Toolbar toolbar = findViewById(R.id.toolbar);

        //将toorbar、navController、appBarConfiguration 关联起来
        NavigationUI.setupWithNavController(toolbar,navController,appBarConfiguration);
        //点击按钮跳转到toOtherFragment
        final Button btn = findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        navController.navigate(R.id.toOtherFragment);
                    }
                });
        //监听页面切换
        navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @SuppressLint("RestrictedApi")
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
                if(destination.getId() == R.id.toOtherFragment){
                    toolbar.setLogo(R.drawable.ic_launcher_foreground);
                    //隐藏按钮s
                    btn.setVisibility(View.GONE);
                }else if(destination.getId() == R.id.toorbarFragment){
                    toolbar.setTitle("小鑫啊哈哈哈哈");
                    toolbar.setLogo(null);
                    //显示按钮
                    btn.setVisibility(View.VISIBLE);
                }
            }
        });
    }
}

这样就可以完成在同一个Activity不同Fragment拥有不同的Toorbar.需要注意的是:fragment需要在导航图中进行注册, 也可以通过menu来进行跳转,需要在获取toolbar组件后,将上这一句代码

setSupportActionBar(toolbar);

这样在onCreateOptionsMenu设置menu的时候才会生效.

Navigation结合CollapsingToolbarLayout使用

用法跟toolbar基本上差不多,只需要更改下布局文件,和稍微更改下ToolbarActivity

这里就不再详细的介绍了,只给出布局文件,部分修改的代码

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ToorbarActivity"
    android:orientation="vertical">
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="250dp">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleGravity="top"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/colorAccent"
                app:title="Material Design"
                app:titleTextColor="@android:color/white"
                >
            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
    <fragment
        android:id="@+id/nav_toorbar_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost= "true"
        app:navGraph="@navigation/toor_graph"/>
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="跳转"/>
</LinearLayout>
 //获取NavController对象
        final NavController navController = Navigation.findNavController(this,R.id.nav_toorbar_fragment);
        //获取App bar对象 设置顶级目的地
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        //获取Toorbar 对象
        final Toolbar toolbar = findViewById(R.id.toolbar);
        //获取collapsingToolbarLayout对象即可
        final CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout);
        //将collapsingToolbarLayout,toorbar、navController、appBarConfiguration 关联起来
        NavigationUI.setupWithNavController(layout,toolbar,navController,appBarConfiguration);

支持应用栏变体

如果对于应用中的每个目的地,应用栏的布局都类似,那么向 Activity 添加顶部应用栏的效果很好。但是,如果顶部应用栏在不同目的地之间有很大变化,请考虑从 Activity 中移除顶部应用栏,并改为在每个目的地 Fragment 中进行定义。
例如,一个目的地可能使用标准 Toolbar,而另一个目的地则使用 AppBarLayout 创建带有标签页的更复杂的应用栏,如下图 所示。
在这里插入图片描述
在这里插入图片描述

创建导航图 toolbar.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/toolbar_graph"
    app:startDestination="@id/toolbarFragment1"
    tools:ignore="UnusedNavigation">

    <fragment
        android:id="@+id/toolbarFragment1"
        android:name="com.example.jetpack.toolbarFragment1"
        android:label="fragment_toolbar1"
        tools:layout="@layout/fragment_toolbar1" />
    <fragment
        android:id="@+id/toolbarFragment2"
        android:name="com.example.jetpack.toolbarFragment2"
        android:label="fragment_toolbar2"
        tools:layout="@layout/fragment_toolbar2" />
</navigation>

这两个 Fragment 的导航配置逻辑相同,不过您应该在每个 Fragment 的 onViewCreated() 方法中调用 setupWithNavController(),而不是通过 Activity 对它们进行初始化:

fragment_toolbar1.xml文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".toolbarFragment1">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="@color/colorAccent" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_marginRight="20dp"
                android:id="@+id/imageview"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:src="@mipmap/ic_launcher"/>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Toolbar"
                android:textSize="20sp"
                android:textColor="#000"/>
        </LinearLayout>
    </androidx.appcompat.widget.Toolbar>

</FrameLayout>

toolbarFragment1.java文件

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_toolbar1, container, false);
        Toolbar toolbar = view.findViewById(R.id.toolbar);
        TabLayout tablayout = view.findViewById(R.id.tablayout);

        final NavController navController = Navigation.findNavController(getActivity(),R.id.nav_host_fragment);

        AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();
        //关联起来
        NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

        view.findViewById(R.id.imageview).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                navController.navigate(R.id.toolbarFragment2);
            }
        });
        return view;
    }

fragment_toolbar2.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".toolbarFragment2"
    android:orientation="vertical">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="@color/colorAccent"
        app:title="Toolbar" />
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed"
        app:tabTextColor="#fff"
        app:tabSelectedTextColor="#000"
        app:tabBackground="@color/colorPrimary"/>

</LinearLayout>

toolbarFragment2.java文件

  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_toolbar2, container, false);
        Toolbar toolbar = view.findViewById(R.id.toolbar);
        TabLayout tablayout = view.findViewById(R.id.tablayout);

        NavController navController = Navigation.findNavController(getActivity(),R.id.nav_host_fragment);

        AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();
        //关联起来
        NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

        //初始化tablayout
        tablayout.addTab(tablayout.newTab().setText("Tab1"));
        tablayout.addTab(tablayout.newTab().setText("Tab2"));
        tablayout.addTab(tablayout.newTab().setText("Tab3"));
        return view;
    }

配合NavigationView

创建导航图 navview_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/navview_graph"
    app:startDestination="@id/viewFragment1">

    <fragment
        android:id="@+id/viewFragment1"
        android:name="com.example.jetpack.viewFragment1"
        android:label="fragment_view1"
        tools:layout="@layout/fragment_view1" />
    <fragment
        android:id="@+id/viewFragment2"
        android:name="com.example.jetpack.viewFragment2"
        android:label="fragment_view2"
        tools:layout="@layout/fragment_view2" />
</navigation>

NavigationView需要的menu文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/viewFragment1"
            android:title="view1"/>
        <item
            android:id="@+id/viewFragment2"
            android:title="view2"/>>
    </group>

</menu>

Activity的布局文件

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <fragment
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/nav_host_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navview_graph" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:menu="@menu/navview_menu"/>

</androidx.drawerlayout.widget.DrawerLayout>

Activity代码

public class NavigationViewActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigation_view);

        //初始化NavigationView
        NavigationView nav_view = findViewById(R.id.nav_view);
        DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph())
                        .setDrawerLayout(drawerLayout)
                        .build();
        NavigationUI.setupWithNavController(nav_view,navController);
        
    }
}

效果类似下图:
在这里插入图片描述
需要注意一点,menu文件item项的id,必须和导航图中的fragmentd

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值