释放双眼,带上耳机,听听看~!
随着Jetpack组件的火爆,单Activity+多Fragment的架构开始被越来越多的被采用。Fragment写多了,难免要写许多重复的代码,这时封装一个包含了大多数重复代码的BaseFragment能起到事半功倍的效果。下面给出一个结合Databinding、ViewModel、Lifecycle的BaseFragment:
BaseFragment
...
//两个泛型,TBinding代表databinding为fragment的layout文件生成的XXXBinding,TModel代表fragment对应的viewmodel。
//比如MainFragment的layout是fragment_main.xml,viewmodel是MainViewModel,那对应的TBinding和TModel就分别是FragmentMainBinding和MainViewModel。
//两个变量,brId是layout里viewmodel的variable变量名在BR类里对应生成的id,modelClass则是viewmodel对应的class文件
//比如MainViewModel在fragment_main.xml里的variable为mainViewModel,那么brId和modelClass则分别为BR.mainViewModel与MainViewModel::class.java。
abstract class BaseFragment<TBinding: ViewDataBinding, TModel: ViewModel>(private val brId: Int, modelClass: Class<TModel>) : Fragment() {
protected lateinit var binding: TBinding //也可以用by lazy,放在onVreateView里初始化更方便
protected val viewModel by lazy { ViewModelProviders.of(this).get(modelClass) }
protected val activity by lazy { getActivity() as MainActivity } //让具体子Fragment持有Activity的引用,方便Fragment与Activity交互
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//TBinding的具体类型不确定,只能用DataBindingUtil.inflate(),而不能用XXXBinding.inflate()
binding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false)
binding.lifecycleOwner = this //绑定viewmodel的lifecycle
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
binding.setVariable(brId, viewModel)
activity.currentFragment = this //currentFragment是Activity里的变量,用来持有显示的当前Fragment,便于Activity与Fragment交互
}
protected abstract fun getLayoutId(): Int //获取具体子Fragment对应的layoutId
...
}
注释十分详细,就不多解释了。里面还可以加入一些各Fragment均持有的变量或方法。下面贴一个具体的子Fragment代码:
MainFragment
...
class MainFragment : BaseFragment<FragmentMainBinding, MainViewModel>(BR.mainViewModel, MainViewModel::class.java) {
...
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
...
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
...
}
override fun getLayoutId(): Int {
return R.layout.fragment_main //返回对应的layoutId
}
...
}
在onCreateView()
和onActivityCreated()
里也可以加入各Fragment对应的初始化代码。这里还可以直接用继承自BaseFragment的activity来完成与Activity的通信。
作者:缺牙青蛙
链接:https://www.jianshu.com/p/43d50a58ba65
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。