一、概述
传统的Activity与Fragment之间共享数据,Fragment与Fragment之间共享数据,我一般会采用EventBus事件总线来实现。不过现在可以借助另外一种简单的方式LiveData+ViewModel也可以实现这种共享
二、代码示例
示例描述:要求FragmentA发送出数据,FragmentB和Activity都能接收到。FragmentB发送出的数据FragmentA和Activity都能接收到。Activity发送出去的数据FragmentA和FragmentB都能接收到。
上代码:
SharedDataActivity.kt用于承载两个Fragment以及自己数据的Activity
/** * Activity和Fragment,Fragment和Fragment之间共享数据 */ class ShareDataActivity :AppCompatActivity(){ private var mModel:UserViewModel?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_share_data) //第一种实现方式 mModel = ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(com.tony.demo.utils.ContextUtils.getApplicationContext())).get(UserViewModel::class.java) //第二种实现方式 // mModel = ViewModelProvider(this).get(UserViewModel::class.java) supportFragmentManager.beginTransaction().replace(R.id.fl_continer1,FragmentA()).commit() supportFragmentManager.beginTransaction().replace(R.id.fl_continer2, FragmentB()).commit() btnSendToActivity.setOnClickListener { mModel?.getAccount()?.postValue(AccountBean("Activity的数据:杨洛峋",5)) } mModel?.getAccount()?.observe(this){ tvContentActivity.text = "接收到来自${it.name} ${it.age} 岁了!" } } }
activity_shared_data.layout
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="3"> <FrameLayout android:id="@+id/fl_continer1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <FrameLayout android:id="@+id/fl_continer2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" /> <RelativeLayout android:id="@+id/fl_continer3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"> <Button android:id="@+id/btnSendToActivity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Activity发送消息" /> <TextView android:id="@+id/tvContentActivity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="" /> </RelativeLayout> </LinearLayout>
FragmentA.kt
/** * 使用LiveData+ViewModel让A和B进行通信 */ class FragmentA : Fragment(){ private var mModel: UserViewModel? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_a, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //第一种实现方式 // mModel = ViewModelProvider(requireActivity()).get(UserViewModel::class.java) //第二种实现方式 mModel = ViewModelProvider(requireActivity(), ViewModelProvider.AndroidViewModelFactory.getInstance(ContextUtils.getApplicationContext())) .get(UserViewModel::class.java) btnSendToB.setOnClickListener { //A向B发送数据 mModel?.getAccount()?.postValue(AccountBean("FragmentA的消息:杨洛峋",5)) } //当数据有变化的时候执行此方法 mModel?.getAccount()?.observe(requireActivity()) { tvContentA.text = "接收到来自${it.name} ${it.age} 岁了!" } } }
fragment_a.layout
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btnSendToB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="A发送消息" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tvContentA" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
FragmentB.kt
/** * 使用LiveData+ViewModel让A和B进行通信 */ class FragmentB : Fragment() { private var mModel: UserViewModel? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_b, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //第一种实现方式 // mModel = ViewModelProvider(requireActivity()).get(UserViewModel::class.java) //第二种实现方式 mModel = ViewModelProvider(requireActivity(),ViewModelProvider.AndroidViewModelFactory.getInstance(ContextUtils.getApplicationContext())).get(UserViewModel::class.java) btnSendToA.setOnClickListener { mModel?.getAccount()?.postValue(AccountBean("FragmentB的消息:杨洛峋小宝宝",5)) } mModel?.getAccount()?.observe(requireActivity()){ tvContentB.text = "接收到来自${it.name} ${it.age} 岁了!" } } }
framgent_b.layout
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btnSendToA" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="B发送消息" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tvContentB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
运行测试结果:
标签:Fragment,mModel,ViewModel,ViewModelProvider,Activity,UserViewModel,class From: https://www.cnblogs.com/tony-yang-flutter/p/17622690.html