如下圖我們今天要做的頁面架構是,我們在一個Activity裡面放了三個fragment,分別是文章、活動與影片頁面。今天的需求是,在Activity層按下編輯鈕時,fragment必須要監聽到這件事並且浮出左側的radio button與下方的刪除鈕。今天我們要的方法是在activity建立一個viewModel,然後讓各個fragment去訂閱viewModel的資料變化來達到效果。或許除了用viewModel可能還有更快更好的方法,但今天就是當作一個viewModel的練習嘛,先不要太嚴格。
//目前最新版是2.2.0
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
class BaseViewModelFactory<T>(private val creator: () -> T): ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return creator() as T
}
}
待會會利用這裡的方法來取得viewModel
inline fun <reified T : ViewModel> FragmentActivity.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
inline fun <reified T : ViewModel> Fragment.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
宣告一個viewModel,裡面放一筆資料,屬於mutableLiveData,型態為boolean
class RemoveVM : ViewModel() {
val isEditable by lazy {
MutableLiveData<Boolean>()
}
}
companion object{
lateinit var removeVM :RemoveVM
}
//取得viewModel實體
removeVM = getViewModel { RemoveVM() }
//先把viewModel中的那筆資料設為false
removeVM.isEditable.value = false
//編輯鈕點擊監聽事件
btn_edit_my_collection.setMyClickListener {
if(removeVM.isEditable.value==false) {
removeVM.isEditable.value = true
btn_edit_my_collection.text = "取消"
}
else {
removeVM.isEditable.value = false
btn_edit_my_collection.text = "編輯"
}
}
三個fragment都一樣。
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.your_fragment, container, false)
return rootView
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//建立一個監聽器叫做statusObserver,監聽的資料型態是boolean
val statusObserver = Observer<Boolean> {
//若這筆資料變成true
if (it) {
//刪除鈕出現
rootView.spacing_line.visibility = View.VISIBLE
rootView.btn_remove.visibility = View.VISIBLE
rootView.btn_remove.text = "刪除 ( 0 )"
//我的recyclerview的每個項目也都有另外設一個屬性叫isEditable
//藉由判斷true or false來決定要不要顯示左側的圓形radio button
//這裡改成true,也就是通知adapter現在要顯示radio button了
myData.myList.forEach { it.isEditable = true }
adapter.notifyDataSetChanged()
}
//若這筆資料變成false
else {
rootView.spacing_line.visibility = View.GONE
rootView.btn_remove.visibility = View.GONE
myCollectionData.articleList.forEach {
it.isEditable = false
}
adapter.notifyDataSetChanged()
}
}
//剛剛我們設了監聽器,可以用來監聽一個型態為boolean值的資料的變化
//那我們到底要監聽誰呢?
//我們現在指定 我們要監聽removeVM中的isEditable這筆資料
//owner是activity,也就是包著三個fragment的activity,
//監聽器的生命就是跟著這個activity的生命週期走
removeVM?.isEditable?.observe(activity!!, statusObserver)
}