该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

由原来的java版本改成kotlin版本, 优化了很多细节.

目前已经使用该框架开发过超过5个应用, 未发现性能问题和内存泄露bug.

架构

使用MVPVM架构:

  1. 在写View时,只需要关心不同的状态(数据)与UI的关系, 至于状态的变更,转换等都不需要考虑. 可以将业务逻辑与UI抽离, 只需要关注UI的相关逻辑. 例如: 在写订单详情界面时, 只需要把订单所有相关的控件写在XML里, 然后根据不同的订单状态控制它们的数据和显示等.
  2. 在写ViewModel层时, 只要关系该界面需要哪些数据, 以及数据的转换,显示等数据与UI的对应关系处理. 例如:订单详情界面需要订单的基本信息,付款信息,收货地址和订单状态等信息, 订单状态一般是整形的,需要转为文本类型.
  3. 在写Model层时, 只需要负责获取和保存数据, 至于数据之后转换,变更都不需要处理.
  4. 在写Presenter层时, 只关心数据初始化, 以及点击事件等事件的处理等业务逻辑方面的事情, 在调用完Model的接口后, 将结果交给ViewModel即可, 不需要关系UI是怎么显示该数据的, 只要数据没问题, 就不关Presenter的事情. 例如: 在订单详情界面, 只要在界面刚创建时获取订单数据, 然后将订单数据传给ViewModel. 在点击付款按钮时, 在Presenter层中会收到点击事件, 从ViewModel中获取订单的付款数据(备注等),然后调用付款接口即可.

特点

一种View绑定一种ViewModel, 因为View需要ViewModel提供界面数据, 而同一个ViewModel可以绑定不同的View, 可以轻松实现一种ViewModel对应不同的View. 在框架中的RecycleView就是通过该方式控制不同的Item类型的, 状态组件也是通过该方式实现的. 例如: 在订单列表界面, 不同的订单状态显示的布局不一致, 但是Bean又是一样的, 这时可以在ViewModel中根据不同的状态,加载不同的布局文件.

在Presenter中, 只处理数据也事件, 不直接与界面上的View交互, 因此, 在Presenter中也不会持有View的引用(弹窗除外) , 那Presenter怎么控制View, 通过数据进行间接控制. 例如: 付款按钮根据订单状态不同而显示隐藏, 在Presenter中要控制该按钮, 只要修改订单状态即可, 按钮的显示隐藏是ViewModel与View的事件.

数据流动: 用户->View->Presenter->Model->Presenter->ViewModel->View->用户 例如: 用户点击按钮->Presenter调用Model接口->Model获取数据->返回给Presenter->Presenter转给ViewModel->View根据ViewModel自动更新->展示给用户

需要获取数据情况: 用户输入->ViewModel双向绑定自动同步->Presenter处理输入事件或点击事件->Presenter调用Model接口->->Model获取数据->返回给Presenter->Presenter转给ViewModel->View根据ViewModel自动更新->展示给用户

ViewModel中数据分为两类:

  1. state: 状态, 单向绑定的数据, 通常是完整的bean
  2. data: 数据, 双向绑定的数据, 通常是单个属性, 例如要输入名称, 则为string类型的name字段. 当然, 你也可以不做区分, 但是得注意数据的流向, 保证View不可改变状态中的数据, 避免出现数据紊乱和不可控.

与MVP相比, P层的职责更明确, 只需要负责生命周期事件和点击事件等交互事件. 与MVVM相比, ViewModel的职责也更明确, 只需要处理数据与UI的关系. 无需处理业务逻辑事件等.

注意: 基础Activity继承了Presenter层接口, 表示Presenter的角色.

项目目录, 详情请看目录说明.md

- app 应用主包
- baseframe 基础mvpvm架构
- common 通用组件
- data 数据层,存放bean,接口等
- library 第三方应用的包以及针对第三方包的封装

使用说明

  1. 基础activity
class TestBaseActivity : BaseBindingActivity<TestBaseViewModel, ViewDataBinding>() {

    //布局文件放在viewModel或者这里都可以,优先这里的,如果这里返回0才会使用viewmodel中的
    //如果是lazy的界面,那就只能在viewmodel中获取布局
    override fun getLayoutId(): Int {
        return R.layout.activity_test_base
    }

    override fun initParams() {
        //处理入参
    }
    
    override fun initContent() {
        setTitle("测试基础框架")
    }

    override suspend fun fetchData() {
        //获取数据
    }

    override fun onClick(view: View) {
        //处理点击事件
    }
}
  1. 列表界面

@AndroidEntryPoint
class TestListActivity : BaseListActivity<TestListViewModel, ViewDataBinding>(), IItemViewLongClickListener{

    override fun initParams() {
    }
    
    override fun initContent() {
        setTitle("测试列表界面")
        //设置开启下拉刷新
        setRefreshEnable(true)
        //设置开启加载更多
        setLoadMoreEnable(true)
    }

    override suspend fun fetchData() {
        //测试加载动画
        delay(1000)
        refreshData()
    }

    override fun onClick(view: View) {
        //处理点击事件
    }

    override suspend fun fetchData(pageNum: Int, pageSize: Int, useCache: Boolean, param: Any?) {
        //分页获取列表数据
        val list = ArrayList<BaseItemViewModel<*>>()
        list.add(TestItemViewModel("测试数据pageNum:${pageNum}"))
        list.add(TestItemViewModel("测试数据${pageNum}"))
        //设置数据和页码
        setData(list, pageNum)
    }

    override fun onItemClick(view: View, itemViewModel: BaseViewModel) {
        //item的点击事件
    }
}
其他范例可以直接查看app模块中的com.wjjun.test中
包括了大部分常用的布局和用法

空文件

简介

使用kotlin搭建的jetpack框架 展开 收起
Android 等 2 种语言
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化