Android Jetpack之打造通用的BaseFragment

释放双眼,带上耳机,听听看~!

随着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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

人已赞赏
Android文章

Android 梯形TextView

2019-10-23 13:37:16

Android文章

Android高级UI-粒子爆炸效果

2019-10-23 20:32:06

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索