美文网首页
ViewModel+LiveData实现Fragment通信

ViewModel+LiveData实现Fragment通信

作者: 奔跑的佩恩 | 来源:发表于2023-02-22 18:53 被阅读0次

    前言

    在上一节中我们学习了LiveData的基本使用,大家感兴趣的话,可参考以下文章
    LiveData的使用
    今天让我们来学习下ViewModel+LiveData实现Fragment通信
    今天涉及内容如下:

    1. ActivityFragment之间,FragmentFragment之间通讯的方式
    2. ViewModel+LiveData实现 ActivityFragmentFragmentFragment之间通讯的原理
    3. 效果图与项目结构图
    4. 通信代码实现
      4.1 FragmentContainerView基本使用
      4.2 具体代码

    运行效果图如下


    效果图.gif

    一. Activity与Fragment之间,Fragment与Fragment之间通讯的方式

    在以前的文章,我们已经讲过了Activity与Fragment之间,Fragment与Fragment之间通信方式,大家感兴趣的话可参考以下文章:
    Fragment(五)——Activity向Fragment传值
    Fragment(八)——Fragment向Activity传值
    Fragment(九)——Fragment与Fragmnet之间的交互
    现在有了ViewModel+LiveData,我们可以用新的方式实现ActivityFragment之间,FragmentFragment之间通讯的方式

    二. ViewModel+LiveData实现 Activity与Fragment,Fragment与Fragment之间通讯的原理

    ViewModel贯穿Activity的整个生命周期,Fragment又包含在Activity的生命周期之内,我们只要在ViewModel中利用LiveData来存储和监听数据的变化,便可实现数据在ActivityFragment间数据的持有和更新

    三. 效果图与项目结构图

    下面以在Activity中加载两个Fragment: FirstFragmentSecondFragment,然后在每个Fragment中加载一个Seekbar,调整其中一个Fragment中的Seekbar,另一个Fragment中的Seekbar也跟随变化的例子讲解,下面先给出运行效果图

    效果图.gif 项目结构图.png

    四.通信代码实现

    4.1 FragmentContainerView基本使用

    在介绍ActiviyFragment的使用之前,我们先来了解下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所指定的fragementtag值。
    FragmentContainerView不应该被用作Fragment用例之外的其他viewgroup (FrameLayout, LinearLayout等)的替代。

    FragmentContainerView只允许由Fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)返回的view。试图添加任何其他视图将导致IllegalStateException

    对于大于17api,FragmentContainerView禁用布局动画和transitions。否则,动画应该通过FragmentTransaction.setCustomAnimations(int, int, int, int)完成。如果animateLayoutChanges被设置为truesetLayoutTransition(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代码:

    相关文章

      网友评论

          本文标题:ViewModel+LiveData实现Fragment通信

          本文链接:https://www.haomeiwen.com/subject/nwlokdtx.html