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