Android 抽取ViewBinding和ViewModel

前言

  最近根據項目需要抽取了一套針對MVVM模式的BaseActivity和BaseFragment,使View與ViewModel不再需要在每個Activity或者Fragment不需要單獨創建,目前屬於比較簡單的版本,直接把代碼放下面。

View層

abstract class BaseFragment<ViewModelLazy : ViewModel, Binding : ViewBinding> : Fragment() {

    protected lateinit var binding: Binding
    protected var viewModel: ViewModelLazy? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        viewModel = bindViewModel()
        binding = bindViewBinding()
        bindObserver()
        loadData()
        return binding.root
    }

    /**
     * 監聽數據變化
     */
    open fun bindObserver() {

    }

    /**
     * 加載數據
     */
    open fun loadData() {

    }

    /**
     * 綁定ViewModel
     * @return ViewModelLazy
     */
    open fun bindViewModel(): ViewModelLazy? {
        return null
    }

    /**
     * 綁定佈局
     * @return View
     */
    abstract fun bindViewBinding(): Binding

}

ViewModel

class MainViewModel : ViewModel() {

    private val _loginResult = MutableLiveData<Boolean>()
    val loginResult: LiveData<Boolean> = _loginResult

    fun login(name: String, pwd: String) {
        viewModelScope.launch(Dispatchers.IO) {
            //網絡請求
            _loginResult.postValue(true)
        }
    }
}

ViewModelEx

//擴展BaseActivity的ViewModel
@MainThread
public inline fun <reified VM : ViewModel> BaseActivity<*, *>.createViewModel(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null,
): Lazy<VM> = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

@MainThread
public fun <VM : ViewModel> BaseActivity<*, *>.createViewModelLazy(
    viewModelClass: KClass<VM>,
    storeProducer: () -> ViewModelStore,
    factoryProducer: (() -> ViewModelProvider.Factory)? = null,
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        defaultViewModelProviderFactory
    }
    return ViewModelLazy(viewModelClass, storeProducer, factoryPromise)
}


//擴展BaseFragment的ViewModel
@MainThread
public inline fun <reified VM : ViewModel> BaseFragment<*, *>.createFragmentViewModel(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null,
): Lazy<VM> = createFragmentViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

@MainThread
public fun <VM : ViewModel> BaseFragment<*, *>.createFragmentViewModelLazy(
    viewModelClass: KClass<VM>,
    storeProducer: () -> ViewModelStore,
    factoryProducer: (() -> ViewModelProvider.Factory)? = null,
): Lazy<VM> {
    val factoryPromise = factoryProducer ?: {
        defaultViewModelProviderFactory
    }
    return ViewModelLazy(viewModelClass, storeProducer, factoryPromise)
}

具體實現

class MainFragment : BaseFragment<MainViewModel, FragmentMainBinding>() {

    override fun bindViewModel(): MainViewModel {
        return createFragmentViewModel<MainViewModel>().value
    }

    override fun bindViewBinding(): FragmentMainBinding {
        return FragmentMainBinding.inflate(layoutInflater)
    }

    override fun loadData() {
        super.loadData()
        viewModel?.login("gxy", "123456")
    }

    override fun bindObserver() {
        super.bindObserver()
        viewModel?.loginResult?.observe(viewLifecycleOwner) {
            Log.e("TAG", "bindObserver:登錄結果${it} ")
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章