
Navigation is a routing component, an excellent Fragment management tool, and it can also manage Activity. Developers can focus on business development and avoid dealing with too many Fragment management codes, thereby accelerating business development efficiency.
1. Composition of Navigation
Navigation map
This is the resource file under the navigation folder under the Android resource file path. In this resource file, you can configure Fragment, Activity and action, etc.
NavHost
This is a blank container for displaying pages. The default is NavHostFragment, all other Fragments rely on it to display.
NavController
The management object in NavHost can jump to Fragment and back stack through the Controller object. It can also be used to bind operations such as NavigationBar
.
resource
Here are the layout resources such as Fragment and Activity. If it is bound to BottomNavigationView
, menu resources are required.
2. Implement a simple Navigation
Here, a Fragment is shown first, and then there is a button in FragmentA
, click to enter FragmentB
. We add entry one by one according to the several parts mentioned above
1. Import dependencies
def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
Code language: JavaScript (javascript)
2. Add a navigation map
Create a new navigation resource file under res dir, and create a new nav.xml file.
And do the following configuration:
<?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"
app:startDestination="@id/fmt_a"
android:id="@+id/nav">
<fragment
android:id="@+id/fmt_a"
android:name="com.mg.axechen.libnavigation.fragment.FragmentA"
app:layout="@layout/fragment_a"
android:label="FramentA" >
<action android:id="@+id/action_fmta_to_fmtb"
app:destination="@id/fmt_b"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"/>
</fragment>
<fragment
android:id="@+id/fmt_b"
android:name="com.mg.axechen.libnavigation.fragment.FragmentB"
app:layout="@layout/fragment_b"
android:label="FragmentB" />
</navigation>
Code language: HTML, XML (xml)
Note: The navigation here must add an initial Fragment, app:startDestination="@id/fmt_a"
otherwise an exception will occur:
Caused by: android.view.InflateException: Binary XML file line #14 in com.mg.axechen.libnavigation:layout/activity_test: Error inflating class fragment
Caused by: java.lang.IllegalStateException: no start destination defined via app:startDestination for com.mg.axechen.libnavigation:id/nav
Code language: PHP (php)
Here is a description of these configurations:
<fragment
android:id="@+id/fmt_a"
android:name="com.mg.axechen.libnavigation.fragment.FragmentA"
app:layout="@layout/fragment_a"
android:label="FramentA" >
<action android:id="@+id/action_fmta_to_fmtb"
app:destination="@id/fmt_b"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"/>
Code language: HTML, XML (xml)
You can also configure the Activity usage to be consistent with Fragment.
3. Add NavHost
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
<fragment
android:id="@+id/fmt_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav"
app:defaultNavHost="true"
/>
</FrameLayout>
Code language: HTML, XML (xml)
There are several parameters here:
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/nav"
app:defaultNavHost="true"
Code language: JavaScript (javascript)
The first is name
, and NavHostFragment
is currently specified by default.
The second is to specify the navigation map, where the nav resource file under navigation is specified.
The third parameter will cause the Fragment’s back stack to change
4. Add NavController
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
initNavigation();
}
private void initNavigation() {
NavController navController = Navigation.findNavController(this, R.id.fmt_test);
}
}
Code language: JavaScript (javascript)
In this way, when the Test Activity is started, the TestActivity
will display FragmentA
through the NavController
.FragmentA
can also jump to FragmentB
through NavControl.
public class FragmentA extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a,container,false);
Button test = view.findViewById(R.id.test);
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(view).navigate(R.id.action_fmta_to_fmtb);
}
});
return view;
}
}
Code language: PHP (php)
3. Use with BottomNavigationView
This is also a common usage. The usage of BottomNavigationView
will not be explained here. If you need to use it with BottonNavigationView
, you also need to bind NavController
When creating the menu of BottomNavigationView
, the id of the menu needs to be consistent with the id configured in the navigation graph: for example:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/fmt_a"
android:icon="@mipmap/index"
android:title="Home"></item>
<item android:id="@+id/fmt_b"
android:icon="@mipmap/cate"
android:title="List"></item>
<item android:id="@+id/fmt_c"
android:icon="@mipmap/cart"
android:title="Shopping cart"></item>
<item android:id="@+id/fmt_d"
android:icon="@mipmap/me"
android:title="About"></item>
</menu>
Code language: HTML, XML (xml)
Navigation map:
<fragment
android:id="@+id/fmt_a"
android:name="com.mg.axechen.libnavigation.fragment.FragmentA"
tools:layout="@layout/fragment_a"
android:label="FramentA" >
<!-- action_now_to_target -->
<action android:id="@+id/action_fmta_to_fmtb"
app:destination="@id/fmt_b"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"/>
</fragment>
<fragment
android:id="@+id/fmt_b"
android:name="com.mg.axechen.libnavigation.fragment.FragmentB"
tools:layout="@layout/fragment_b"
android:label="FragmentB" />
<fragment
android:id="@+id/fmt_c"
android:name="com.mg.axechen.libnavigation.fragment.FragmentC"
tools:layout="@layout/fragment_c"
android:label="FragmentC" />
<fragment
android:id="@+id/fmt_d"
android:name="com.mg.axechen.libnavigation.fragment.FragmentD"
tools:layout="@layout/fragment_d"
android:label="FragmentD" />
private void initNavigation() {
NavController navController = Navigation.findNavController(this, R.id.fmt_main);
navController.navigate(R.id.fmt_d);
bottomNavigationView = findViewById(R.id.btn_navigation_view);
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
Code language: HTML, XML (xml)
In this way, you can control the display of Fragment through BottonNavigationView
.
4. Use of defaultNavHost
If this is true, the return key will be handed over to Navigation for management, which will override the Activity’s rollback event, so that each rollback will take out the last saved Fragment from the stack.
If false, the Activity’s fallback event will not be overridden.
This property can be used in different scenarios. If you use BottonNavigationView
+ Navigation
as the home page, if you need to return to the desktop by clicking back, you can set this property to false
.
5. Support DeepLink
DeepLink is actually a page that is directly located through an agreed-upon Url.
<fragment
android:id="@+id/fmt_a"
android:name="com.mg.axechen.libnavigation.fragment.FragmentA"
tools:layout="@layout/fragment_a"
android:label="FramentA" >
<deepLink app:uri="http://www.printf.pro/{params}"></deepLink>
</fragment>
Code language: HTML, XML (xml)
You can configure deepLink directly in the fragment, and then open the Fragment directly by accessing this url.
6. Pass parameters
The passed parameters are passed through Bundle, and Fragment is also received through getArguments()
when receiving. Activity receives through Intent
Pass parameters:
Bundle bundle = new Bundle();
bundle.putString("name","para");
Navigation.findNavController(getView())
.navigate(R.id.action_fmta_to_activity_demo,bundle);
Code language: JavaScript (javascript)
Activity:
String name = getIntent().getStringExtra("name");
Fragment:
String params = getArguments().getString("name");
Code language: JavaScript (javascript)
7. Transition animation
The transition animation has actually been configured in the previous configuration. The animation is configured in the Action.
<action android:id="@+id/action_fmta_to_fmtb"
app:destination="@id/fmt_b"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"/>
Code language: HTML, XML (xml)
enterAnim
and exitAnim
are transition animations.