简介
- NavHost: 是一个存放页面的容器,同时也是一个控制器(Activity /Fragment)
- NavController:切换页面,需要定制切换路线
- NavGraph:利用图形化的方式定制切换路线
Navigation组件配合ViewModel实现数据共享
1.首先创建一个Activity, 两个Fragment以及一个ViewModel
fragment的xml如下
// fragment_home
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="data"
type="com.wjx.android.jetpackdemo.navigation.MyViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/home_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@{String.valueOf(data.getNumber())}"
android:textSize="18sp" />
<Button
android:id="@+id/home_btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/home_text"
android:layout_centerHorizontal="true"
android:onClick="@{()->data.add(1)}"
android:text="add" />
<Button
android:id="@+id/home_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/home_btn_add"
android:layout_centerHorizontal="true"
android:text="home" />
</RelativeLayout>
</layout>
// fragment_detail
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="data"
type="com.wjx.android.jetpackdemo.navigation.MyViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/detail_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@{String.valueOf(data.getNumber())}"
android:textSize="18sp" />
<Button
android:id="@+id/detail_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/detail_text"
android:layout_centerHorizontal="true"
android:text="detail" />
</RelativeLayout>
</layout>
2.右键res目录创建AndroidResource文件
3.打开my_nav_graph文件并点击下图中绿色箭头将两个fragment引入
-
并通过连线来实现页面跳转过程(点击连线可以设置页面进入退出动画)
4.进入主Activity页面布局文件(选择Containers下的NavHostFragment创建HostFragment)
5.之后将布局四边点击圆圈,设置全屏显示
6.创建ViewModel
class MyViewModel : ViewModel() {
private var number: MutableLiveData<Int>? = null
fun getNumber(): MutableLiveData<Int> {
if (number == null) {
number = MutableLiveData()
number!!.value = 0
}
return number!!
}
fun add(x: Int) {
number!!.value = number!!.value!! + x
}
}
7.NavigationActivity实现
class NavigationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation)
var controller = Navigation.findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, controller)
}
// 设置返回键
override fun onSupportNavigateUp(): Boolean {
var controller = Navigation.findNavController(this, R.id.fragment)
return controller.navigateUp()
}
}
8.实现HomeFragment和DetailFragment
class HomeFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
var binding = DataBindingUtil.inflate<FragmentHomeBinding>(inflater, R.layout.fragment_home, container, false)
binding.data = myViewModel
binding.setLifecycleOwner(activity)
binding.homeBtn.setOnClickListener {
// 使用id布局id转发
Navigation.findNavController(it).navigate(R.id.detailFragment)
// 使用action跳转
Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_detailFragment)
}
return binding.root
}
}
class DetailFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
var myViewModel = ViewModelProviders.of(activity!!).get(MyViewModel::class.java)
var binding = DataBindingUtil.inflate<FragmentDetailBinding>(inflater, R.layout.fragment_detail, container, false)
binding.data = myViewModel
binding.setLifecycleOwner(activity)
// 实现路由跳转
binding.detailBtn.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.homeFragment)
}
return binding.root
}
}