一、简述
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