前言
在上一节中我们学习了LiveData
的基本使用,大家感兴趣的话,可参考以下文章
LiveData的使用
今天让我们来学习下ViewModel+LiveData
实现Fragment
通信
今天涉及内容如下:
-
Activity
与Fragment
之间,Fragment
与Fragment
之间通讯的方式 -
ViewModel+LiveData
实现Activity
与Fragment
,Fragment
与Fragment
之间通讯的原理 - 效果图与项目结构图
- 通信代码实现
4.1FragmentContainerView
基本使用
4.2 具体代码
运行效果图如下
效果图.gif
一. Activity与Fragment之间,Fragment与Fragment之间通讯的方式
在以前的文章,我们已经讲过了Activity与Fragment之间,Fragment与Fragment之间通信方式,大家感兴趣的话可参考以下文章:
Fragment(五)——Activity向Fragment传值
Fragment(八)——Fragment向Activity传值
Fragment(九)——Fragment与Fragmnet之间的交互
现在有了ViewModel+LiveData
,我们可以用新的方式实现Activity
与Fragment
之间,Fragment
与Fragment
之间通讯的方式
二. ViewModel+LiveData实现 Activity与Fragment,Fragment与Fragment之间通讯的原理
ViewModel
贯穿Activity
的整个生命周期,Fragment
又包含在Activity
的生命周期之内,我们只要在ViewModel
中利用LiveData
来存储和监听数据的变化,便可实现数据在Activity
,Fragment
间数据的持有和更新
三. 效果图与项目结构图
下面以在Activity
中加载两个Fragment
: FirstFragment
和SecondFragment
,然后在每个Fragment
中加载一个Seekbar
,调整其中一个Fragment
中的Seekbar
,另一个Fragment
中的Seekbar
也跟随变化的例子讲解,下面先给出运行效果图
四.通信代码实现
4.1 FragmentContainerView基本使用
在介绍Activiy
中Fragment
的使用之前,我们先来了解下FragmentContainerView
的使用。FragmentContainerView
现在已经作为Activiy
布局中加载Fragment
标签的替代方案,是专门为Fragment
设计的自定义布局。在布局文件中作为Fragment
的容器,我们可以像下面这样使用它:
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.fragment.app.FragmentContainerView>
FragmentContainerView
也可以通过使用android:name
属性来添加一个Fragment
:
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.MyFragment"
android:tag="my_tag">
</androidx.fragment.app.FragmentContainerView>
我们可以在Fragment
中通过getTag()
方法获取FragmentContainerView
所指定的fragement
的tag
值。
FragmentContainerView
不应该被用作Fragment
用例之外的其他viewgroup (FrameLayout, LinearLayout等)
的替代。
FragmentContainerView
只允许由Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)
返回的view
。试图添加任何其他视图将导致IllegalStateException
。
对于大于17
的api
,FragmentContainerView
禁用布局动画和transitions
。否则,动画应该通过FragmentTransaction.setCustomAnimations(int, int, int, int)
完成。如果animateLayoutChanges
被设置为true
或setLayoutTransition(LayoutTransition)
被直接调用,将抛出UnsupportedOperationException
。
在FragmentContainerView
中,使用exit
动画的片段在所有其他动画之前绘制。这确保了退出片段不会出现在视图的顶部
4.2 具体代码
MainActivity
中需要加载两个Fragment
,先给出MainActivity
对应布局:
<?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=".ui.MainActivity">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_first"
android:name="com.ktdemo.ui.FirstFragment"
android:tag="FirstFragment_tag"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_second"
android:name="com.ktdemo.ui.SecondFragment"
android:tag="SecondFragment_tag"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/guideline"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
接着我们看看MainActivity
代码:
网友评论