1.新建 navigation 目录, 并在该目录下new 一个navigation的xml, 如图

2.新增 fragment
如图

3.activity 中 ConstraintLayout 里新增一个frament 布局.
<?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">
<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/my_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.回到navigation 中新增的那个xml, 可视化视图如下:

操作相应的横向, 指向相应的fragment 完成相应的跳转操作.如果选中其中一个fragment 如图:

可以编辑相应的arguments 数据传递. 当然, 也可以动态的数据传递,看源码:
/**
* Navigate to a destination from the current navigation graph. This supports both navigating
* via an {@link NavDestination#getAction(int) action} and directly navigating to a destination.
*
* @param resId an {@link NavDestination#getAction(int) action} id or a destination id to
* navigate to
* @param args arguments to pass to the destination
*/
public void navigate(@IdRes int resId, @Nullable Bundle args) {
navigate(resId, args, null);
}
此处是可以传递一个bundle 的, 所以fragment之间的数据传递可以通过bundle来传递, 代码如下:
Bundle bundle =new Bundle();
bundle.putString("value","good");
Navigation.findNavController(getView()).navigate(R.id.action_homeFragment_to_myFragment,bundle);
String value=getArguments().getString("value");
5.最后一步, 都配置完毕了,轮到 activity 中需要的操作了, 回到activity代码, 新增代码块如下:
@Override
public boolean onSupportNavigateUp() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment);
return NavHostFragment.findNavController(fragment).navigateUp();
}
为啥要这样设置呢, 继续追踪源码:
/**
* This method is called whenever the user chooses to navigate Up within your application's
* activity hierarchy from the action bar.
*
* <p>If a parent was specified in the manifest for this activity or an activity-alias to it,
* default Up navigation will be handled automatically. See
* {@link #getSupportParentActivityIntent()} for how to specify the parent. If any activity
* along the parent chain requires extra Intent arguments, the Activity subclass
* should override the method {@link #onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder)}
* to supply those arguments.</p>
*
* <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and
* Back Stack</a> from the developer guide and
* <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> from the design guide
* for more information about navigating within your app.</p>
*
* <p>See the {@link androidx.core.app.TaskStackBuilder} class and the Activity methods
* {@link #getSupportParentActivityIntent()}, {@link #supportShouldUpRecreateTask(android.content.Intent)}, and
* {@link #supportNavigateUpTo(android.content.Intent)} for help implementing custom Up navigation.</p>
*
* @return true if Up navigation completed successfully and this Activity was finished,
* false otherwise.
*/
public boolean onSupportNavigateUp() {
Intent upIntent = getSupportParentActivityIntent();
if (upIntent != null) {
if (supportShouldUpRecreateTask(upIntent)) {
TaskStackBuilder b = TaskStackBuilder.create(this);
onCreateSupportNavigateUpTaskStack(b);
onPrepareSupportNavigateUpTaskStack(b);
b.startActivities();
try {
ActivityCompat.finishAffinity(this);
} catch (IllegalStateException e) {
// This can only happen on 4.1+, when we don't have a parent or a result set.
// In that case we should just finish().
finish();
}
} else {
// This activity is part of the application's task, so simply
// navigate up to the hierarchical parent activity.
supportNavigateUpTo(upIntent);
}
return true;
}
return false;
}
/**
* Attempts to navigate up in the navigation hierarchy. Suitable for when the
* user presses the "Up" button marked with a left (or start)-facing arrow in the upper left
* (or starting) corner of the app UI.
*
* <p>The intended behavior of Up differs from {@link #popBackStack() Back} when the user
* did not reach the current destination from the application's own task. e.g. if the user
* is viewing a document or link in the current app in an activity hosted on another app's
* task where the user clicked the link. In this case the current activity (determined by the
* context used to create this NavController) will be {@link Activity#finish() finished} and
* the user will be taken to an appropriate destination in this app on its own task.</p>
*
* @return true if navigation was successful, false otherwise
*/
public boolean navigateUp() {
if (getDestinationCountOnBackStack() == 1) {
// If there's only one entry, then we've deep linked into a specific destination
// on another task so we need to find the parent and start our task from there
NavDestination currentDestination = getCurrentDestination();
int destId = currentDestination.getId();
NavGraph parent = currentDestination.getParent();
while (parent != null) {
if (parent.getStartDestination() != destId) {
TaskStackBuilder parentIntents = new NavDeepLinkBuilder(this)
.setDestination(parent.getId())
.createTaskStackBuilder();
parentIntents.startActivities();
if (mActivity != null) {
mActivity.finish();
}
return true;
}
destId = parent.getId();
parent = parent.getParent();
}
// We're already at the startDestination of the graph so there's no 'Up' to go to
return false;
} else {
return popBackStack();
}
}
大概意思就是让导航navigation的 操作来覆盖activity 的返回操作.至此,实际理论操作就完成了, 后续有空分析下, navigation的源码构成.
网友评论