官术网_书友最值得收藏!

3.4 使用ViewModel實現數據共享

在實際開發中,經常會遇到兩個Fragment之間有通信的需求,假設現在有AFragment和BFragment,這兩個Fragment中都有滑動的標簽,我們想要讓兩個Fragment的標簽選項實現同步滑動,比如:在AFragment中選中了“新聞”標簽,切換到BFragment時也會自動切換到“新聞”標簽。一般情況下實現這個需求的方式有兩種:

  • 在某個Fragment中選中數據時將選擇的標簽位置記錄下來,當切換Fragment時,取出當前記錄的位置進行切換。
  • 通過為宿主Activity增加實現接口的方式進行通信。

上面是開發者經常使用的兩種方式,現在使用ViewModel的特性便可以很簡單地解決這個問題。

在ViewModel中創建一個currentPosition變量,用于記錄當前選中的位置,并提供設置變量的方法以供外部Fragment調用,ViewModel的主要代碼如下:

class ShareDataViewModel : ViewModel() {
    private var currentPosition: Int = 0
    fun getCurrentPosition(): Int {
        return currentPosition
    }
    fun positionChanged(currentPosition: Int) {
        this.currentPosition = currentPosition
    }
}

這里可能會有讀者疑惑,為什么要將currentPosition定義為私有變量,并且單獨提供設置和獲取currentPosition的方法?為什么不直接定義為public屬性,這樣在外部就可以直接調用了。這是因為理論上開發者應將所有類變量的操作都放在類的內部,遵循基本的設計原則,如果將類的屬性設為公共屬性暴露給外部,則無法保證數據的統一性和完整性。

言歸正傳,在AFragment中,當標簽變化的時候設置currentPosition的值,在BFragment獲取值后更新UI代碼,AFragment的主要代碼如下:

class AFragment : Fragment() {
    lateinit var shareDataViewModel: ShareDataViewModel
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        shareDataViewModel = ViewModelProvider(requireActivity()).get(ShareDataViewModel::class.java)
        ...
        //標簽選項發生變化
        shareDataViewModel.positionChanged(position)
        ...
    }
}

BFragment的主要代碼如下:

class BFragment : Fragment() {
    lateinit var shareDataViewModel: ShareDataViewModel
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        shareDataViewModel = ViewModelProvider(requireActivity()).get(ShareDataViewModel::class.java)
        ...
        //獲取當前選中的標簽位置
        shareDataViewModel.getCurrentPosition()
        updateUI()
        ...
    }
}

如此一來,使用ViewModel組件就實現了同一宿主Activity下不同Fragment之間的數據共享功能。

注意

在Fragment中通過ViewModelProvider獲取ViewModel對象時,如果參數是requireActivity(),則獲取的是宿主Activity對應的ViewModel對象。此種獲取方式可以用來實現數據共享。如果參數是this,則獲取的是Fragment各自對應的ViewModel對象,此種方式不能用來實現數據共享功能。

主站蜘蛛池模板: 景洪市| 栾城县| 甘德县| 会宁县| 株洲县| 马边| 图们市| 大新县| 闽清县| 湟中县| 保靖县| 集安市| 蒙城县| 宜昌市| 仪陇县| 桐城市| 陆川县| 浦县| 陇西县| 体育| 晋中市| 绍兴市| 上犹县| 崇阳县| 周宁县| 土默特左旗| 孙吴县| 正定县| 永仁县| 南城县| 阿克苏市| 涿州市| 扶风县| 德钦县| 上犹县| 博乐市| 凯里市| 杨浦区| 新兴县| 巨鹿县| 武乡县|