文章目录
一、使用safe args传递参数
1.1 、常见的参数传递
//跳转到第二个Fragment
mBtnToSecondFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置动画
NavOptions options = new NavOptions.Builder()
.setEnterAnim(android.R.anim.fade_in)
.setExitAnim(android.R.anim.fade_out)
.setPopEnterAnim(android.R.anim.fade_in)
.setPopExitAnim(android.R.anim.fade_out)
.build();
//传递参数
Bundle bundle = new Bundle();
bundle.putString("name","android");
bundle.putInt("age",30);
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_secondFragment,bundle,options);
}
});
参数接收:
private void initData() {
//接收参数
Bundle bundle = getArguments();
if (bundle != null) {
String name = bundle.getString("name");
int age = bundle.getInt("age");
Log.e(TAG, "Name is :" + name);
}
}
1.2、使用safe args传递参数
(1)、添加插件的依赖(在Project的build gradle)中添加依赖
def nav = "2.3.0-alpha01"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav"
(2)、在app的build gradle添加对safe args的依赖
plugins {
id 'com.android.application'
id 'androidx.navigation.safeargs'
}
(3)、在导航图中添加标签
<fragment
android:id="@+id/mainFragment"
android:name="com.example.navigationdemo.MainFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main">
<action
android:id="@+id/action_mainFragment_to_secondFragment"
app:destination="@id/secondFragment"/>
<-- 添加参数 -->
<argument
android:name="user_name"
android:defaultValue="unknow"
app:argType="string" />
<argument
android:name="user_age"
android:defaultValue="0"
app:argType="integer" />
</fragment>
(4)、在Fragment中传递参数
//跳转到第二个Fragment
mBtnToSecondFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置动画
NavOptions options = new NavOptions.Builder()
.setEnterAnim(android.R.anim.fade_in)
.setExitAnim(android.R.anim.fade_out)
.setPopEnterAnim(android.R.anim.fade_in)
.setPopExitAnim(android.R.anim.fade_out)
.build();
Bundle bundle = new MainFragmentArgs.Builder()
.setUserName("android jetpack")
.setUserAge(22)
.build().toBundle();
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_secondFragment,bundle,options);
}
});
(5)、接收参数
private void initData() {
//接收参数
String name = MainFragmentArgs.fromBundle(getArguments()).getUserName();
int age = MainFragmentArgs.fromBundle(getArguments()).getUserAge();
Log.e(TAG, "Name is :" + name);
}
二、NavigationUI的使用方法
2.1、NavigationUI存在的意义
导航图是Navigation组件中重要的一部分,它可以帮助我们快速了解页面之间的关系,再通过NavController完成页面的切换工作。而在页面切换过程中,通常还伴随App bar中menu菜单的变化,对于不同的界面,App bar中的menukennel是不一样的,App bar中的各种按钮和菜单,同样承担着页面切换工作。例如,当ActionBar左边的返回按钮被点击时,我们需要响应点击事件返回上一个页面。为了方便管理Navigation和App bar的页面切换事件,JetPack引入NavigationUI组件,使App bar中的按钮和菜单能够与导航图中的页面关联起来。
2.2、NavigationUI的使用
2.2.1、Case说明:
在NavigationUIActivity中有两个Fragment(MainUiFragment和SettingFragment),我们在MainUiFragment右边有一个ActionBar去跳转到SettingFragment,在SettingFragment左侧有一个返回按钮,能够返回MainUiFragment。
2.2.2、目录结构
2.2.3、Case使用说明
(1)、新建navigation文件graph_navui_activity,并新建两个destination(MainUiFragment和SettingFragment),默认加载为MainUiFragment
<?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/graph_navui_activity"
app:startDestination="@id/mainUiFragment">
<fragment
android:id="@+id/mainUiFragment"
android:name="com.example.navigationdemo.testnavigationui.MainUiFragment"
android:label="fragment_main_ui"
tools:layout="@layout/fragment_main_ui">
</fragment>
<fragment
android:id="@+id/settingFragment"
android:name="com.example.navigationdemo.testnavigationui.SettingFragment"
android:label="fragment_setting"
tools:layout="@layout/fragment_setting" />
</navigation>
(2)、新建菜单文件main_menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/settingFragment"
android:icon="@mipmap/ic_launcher"
android:title="设置" />
</menu>
ATTENTION
这里要特别注意: 的id与导航图中(graph_navui_activity)的settingFragment的ID要保持一致。这表示,当被点击时,将会跳转到id对应的fragment。
(3)、在Activity中初始化菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
(4)、使用NavigationUI响应菜单点击事件
public class NavigationUIActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
private NavController mNavController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation_uiactivity);
//用于页面的导航和切换
mNavController = Navigation.findNavController(this, R.id.fragment_nav_ui_container);
//用于App bar的配置
mAppBarConfiguration = new AppBarConfiguration.Builder(mNavController.getGraph()).build();
//将app bar与NavController绑定
NavigationUI.setupActionBarWithNavController(this, mNavController, mAppBarConfiguration);
mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
@Override
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, Bundle arguments) {
//收到切换事件
}
});
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
return NavigationUI.onNavDestinationSelected(item,mNavController) || super.onOptionsItemSelected(item);
}
@Override
public boolean onSupportNavigateUp() {
return NavigationUI.navigateUp(mNavController,mAppBarConfiguration) || super.onSupportNavigateUp();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
}
说明
(1)、由于在导航图和菜单的布局文件中,我们已经把settingFragment设置好了相同的id,因此,在onOptionsItemSelected() 方法中,通过NavigationUI可自动完成页面跳转。
(2)、覆盖onSupportNavigateUp()方法,当我们在settingFragment中单击ActionBar中的返回按钮,NavigationUI会自动返回MainFragment
(3)、AppBarConfiguration用于App bar的配置,NavController用于页面的导航和切换。再通过
NavigationUI.setupActionBarWithNavController(this, mNavController,
mAppBarConfiguration);
将App bar和NavController绑定起来。
(5)、去除settingFragment中的菜单
public class SettingFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_setting, container, false);
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
super.onCreateOptionsMenu(menu, inflater);
}
}
(6)、接收切换通知
NavigationUI在帮助我们完成页面的切换,我们希望能够在切换时得到通知,可通过OnDestinationChangedListener对页面切换事件进行监听
mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
@Override
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, Bundle arguments) {
//收到切换事件
}
});
2.3、NavigationUI的配套使用
NavigationUI对3中类型的App Bar提供支持。
- ActionBar
- ToolBar
- CollaspingToolbarLayout
除了常见的menu菜单,NavigationUI还可以配合另外两种菜单使用。
- App bar左侧的抽屉菜单(DrawLayout+NavigationUI)
- 底部菜单(BottomNavigationView)