Kotlin+Flow+Retrofit+OKHttp+ViewBanding+ViewModel+LiveData封装的一个Kotlin版本的MVVM框架

Last update: May 23, 2022

Gitee 地址:kmvvm


Github 地址:kmvvm


CHANGE LOG

技术要点

  • 支持Flow+Retrofit+OkHttp实现链式http请求

  • 支持Rxjava+Retrofit+OkHttp实现链式http请求

  • 封装基类:BaseActivity、BaseVMActivity、BaseFragment、BaseVMFragment、RecycleAdapter、BaseViewModel

  • 封装工具扩展类:CalendarExt、ContextExt、DateExt、EditTextExt、GsonExt、RxJavaExt、StringExt、SnackbarExt

  • 引入LifeCycle,将ViewModel和Activity的生命周期绑定在一起

  • 将在Application中初始化移至到ContentProvider中,从而不用封装BaseApplication

  • APT(编译时注解)封装注解:Title、OnClickFirstDrawable、OnClickFirstText、OnClickSecondDrawable、OnClickSecondText、Prefs、PrefsField、StatusBar、ObserverError、Adapter、GlobalConfig、ServiceApi

最低兼容:21

Gradle

1. 在Project的build.gradle中添加

allprojects {
     repositories {
       maven { url 'https://jitpack.io' }
     }
 }

2. 在app的build.gradle的添加

apply plugin: 'kotlin-kapt' // 使用 kapt 注解处理工具

3. 在app的build.gradle的android下添加

    buildFeatures {
        viewBinding = true
    }

4. 添加依赖

Gitee

implementation "com.gitee.catchpig.kmvvm:mvvm:last_version"
kapt "com.gitee.catchpig.kmvvm:compiler:last_version"

Github

implementation "com.github.catchpig.kmvvm:mvvm:last_version"
kapt "com.github.catchpig.kmvvm:compiler:last_version"

使用

1. 配置全部参数

interface IGlobalConfig {
    /**
     * 标题栏高度
     * @return Int
     */
    @DimenRes
    fun getTitleHeight(): Int

    /**
     * 标题栏的返回按钮资源
     * @return Int
     */
    @DrawableRes
    fun getTitleBackIcon(): Int

    /**
     * 标题栏背景颜色
     * @return Int
     */
    @ColorRes
    fun getTitleBackground(): Int

    /**
     * 标题栏文本颜色
     * @return Int
     */
    @ColorRes
    fun getTitleTextColor(): Int

    /**
     * 标题栏下方是否需要横线
     * @return Boolean
     */
    fun isShowTitleLine(): Boolean

    /**
     * 标题栏下方横线颜色
     * @return Int
     */
    @ColorRes
    fun getTitleLineColor(): Int

    /**
     * loading的颜色
     * @return Int
     */
    @ColorRes
    fun getLoadingColor(): Int

    /**
     * loading的背景颜色
     * @return Int
     */
    @ColorRes
    fun getLoadingBackground(): Int

    /**
     * RecyclerView的空页面ViewBinding
     * @param parent ViewGroup
     * @return ViewBinding
     */
    fun getRecyclerEmptyBanding(parent: ViewGroup): ViewBinding
    
    /**
     * 刷新每页加载个数
     * @return Int
     */
    fun getPageSize():Int

    /**
     * 刷新起始页的index(有些后台设置的0,有些后台设置1)
     */
    fun getStartPageIndex():Int
}

使用示例:

@GlobalConfig
class MvvmGlobalConfig : IGlobalConfig {
    override fun getTitleHeight(): Int {
        return R.dimen.title_bar_height
    }

    override fun getTitleBackIcon(): Int {
        return R.drawable.back_black
    }

    override fun getTitleBackground(): Int {
        return R.color.colorPrimary
    }

    override fun getTitleTextColor(): Int {
        return R.color.white
    }

    override fun isShowTitleLine(): Boolean {
        return true
    }

    override fun getTitleLineColor(): Int {
        return R.color.color_black
    }

    override fun getLoadingColor(): Int {
        return R.color.color_black
    }

    override fun getLoadingBackground(): Int {
        return R.color.white
    }

    override fun getRecyclerEmptyBanding(parent: ViewGroup): ViewBinding {
        return LayoutEmptyBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    }
    
    override fun getPageSize(): Int {
        return 16
    }

    override fun getStartPageIndex(): Int {
        return 1
    }
}

2. Activity

  • 使用MVVM的继承BaseVMActivity

  • 不使用MVVM的继承BaseActivity

    2.1 标题注解使用

    使用示例

    @Title(R.string.child_title)
    class ChildActivity : BaseVMActivity<ActivityChildBinding, ChildViewModel>() 

    2.2 状态栏注解使用

    使用示例

    @StatusBar(hide = true)
    class FullScreenActivity : BaseActivity<ActivityFullScreenBinding>()

3. Fragment

  • 使用MVVM的继承BaseVMFragment
  • 不使用MVVM的继承BaseFragment

4. RecycleView

  • Adapter可以继承RecycleAdapter来使用,并在类上添加注解Adapter,RecycleAdapter使用了ViewBanding,只需要实现以下一个方法

使用示例

@Adapter
class UserAdapter(iPageControl: IPageControl) :
    RecyclerAdapter<User, ItemUserBinding>(iPageControl) {

    override fun bindViewHolder(holder: CommonViewHolder<ItemUserBinding>, m: User, position: Int) {
        holder.viewBanding {
            name.text = m.name
        }
    }
}

5. 网络请求

  • 只需要是接口类上加上注解ServiceApi,并使用NetManager.getService()获取对应的接口类

使用示例

@ServiceApi(baseUrl = "https://www.wanandroid.com/", factory = WanAndroidConverterFactory::class,interceptors = [HttpLoggingInterceptor::class])
interface WanAndroidService {
  @GET("banner/json")
  suspend fun banner(): List<Banner>
}
object WanAndroidRepository : WanAndroidProxy {
    private val wanAndroidService = NetManager.getService(WanAndroidService::class.java)

    override suspend fun queryBanner(): Banner {
        val banners = wanAndroidService.queryBanner()
        return banners[0]
    }
}

6. 注解使用

6.1 Title-标题

属性 类型 必须 默认 说明
value StringRes 标题内容
backgroundColor ColorRes 全局标题背景色 标题背景色
textColor ColorRes 全局标题文字颜色 标题文字颜色
backIcon DrawableRes 全局标题返回按钮图标 标题返回按钮图标

6.2 OnClickFirstDrawable-标题上第一个图标按钮的点击事件

属性 类型 必须 默认 说明
value StringRes 按钮图片内容

6.3 OnClickFirstText-标题上第一个文字按钮的点击事件

属性 类型 必须 默认 说明
value StringRes 按钮文字内容

6.4 OnClickSecondDrawable-标题上第二个图标按钮的点击事件

属性 类型 必须 默认 说明
value StringRes 按钮图片内容

6.5 OnClickSecondText-标题上第二个文字按钮的点击事件

属性 类型 必须 默认 说明
value StringRes 按钮文字内容

6.6 StatusBar-状态栏

属性 类型 必须 默认 说明
hide boolean false 隐藏状态栏
enabled boolean false 状态栏是否可用
transparent boolean false 状态栏透明

6.7 Prefs-SharedPreferences注解生成器

属性 类型 必须 默认 说明
value String "" 别名
mode PrefsMode PrefsMode.MODE_PRIVATE 模式,对应PreferencesMode

6.8 PrefsField-SharedPreferences字段注解

属性 类型 必须 默认 说明
value String "" 字段别名,如果为空则取修饰字段的参数名称

6.9 ObserverError-Activity和Fragment中的Flow的onError方法统一处理

6.10 Adapter-RecyclerAdapter的继承类注解,加上此注解之后可以自动找到对应的layout资源

6.11 GlobalConfig-全局参数配置

6.12 ServiceApi-网络请求接口注解类

属性 类型 必须 默认 说明
baseUrl String retrofit的baseurl
factory Factory GsonConverterFactory 数据转换器
connectTimeout Long 5000 http的超时时间
readTimeout Long 5000 http读取超时时间
interceptors Interceptor Interceptor http拦截器

7. 刷新分页

使用RefreshLayoutWrapper+RecyclerAdapter控件实现刷新功能

  • RefreshLayoutWrapper继承于SmartRefreshLayout,具体使用请看SmartRefreshLayout官方文档,默认每页数据量为16,如果想修改每页数据量,可使用如下方法更改:

    RefreshLayoutWrapper.pageSize = 16
    
  • RefreshLayoutWrapper实现了IPageControl ,可以通过调用接口内的方法类获取刷新控件的状态和更改状态

    //获取刷新的状态
    iPageControl.getRefreshStatus()
    
  • RecyclerAdapter在实例化的时候传入IPageControl, 获取数据成功之后,只需要调用autoUpdateList(list)方法, 可以自动RefreshLayoutWrapper页码和刷新状态变化

  • 数据更新失败可以调用RecyclerAdapter.updateFailed()

  • 获取每页的数据量和下一页的页码,可以调用一下方法

    //每页的数据量
    RecyclerAdapter.pageSize = 16
    //下一页的页码
    RecyclerAdapter.nextPageIndex = 1
    

8. 文件下载器(DownloadManager))

  • 单文件下载方法download(DownloadCallback)
    DownloadManager.download(downloadUrl, {
            
        }, { readLength, countLength ->
            progressLiveData.value = (readLength * 100 / countLength).toInt()
        })
    • DownloadCallback

      interface DownloadCallback {
          /**
           * 开始下载
           */
          fun onStart()
      
          /**
           * 下载成功
           * @param path 本地保存的地址
           */
          fun onSuccess(path:String)
      
          /**
           * 下载完成
           */
          fun onComplete()
      
          /**
           * 下载进度
           * @param readLength 读取的进度
           * @param countLength 总进度
           */
          fun onProgress(readLength:Long,countLength:Long)
      
          /**
           * 下载错误
           * @param t 错误信息
           */
          fun onError(t:Throwable)
      }
  • 多文件下载方法multiDownload(MultiDownloadCallback)
    DownloadManager.multiDownload(downloadUrls, {
            
        })
    • MultiDownloadCallback
      interface MultiDownloadCallback {
      /**
      * 开始下载
      */
      fun onStart()
        
      /**
      * 下载成功
      * @param paths 本地保存的地址集
      */
      fun onSuccess(paths:MutableList<String>)
        
      /**
      * 下载完成
      */
      fun onComplete()
        
      /**
      * 下载错误
      * @param t 错误信息
      */
      fun onError(t:Throwable)
      }

9. 工具库

utils

第三方库

SmartRefreshLayout-刷新控件

Immersionbar-状态栏

RxJava3

RxAndroid

OkHttp

Retrofit

Gson

kotlinpoet - kt代码生成工具

AndroidUtilKTX - 工具类

LoadingView - Loading动画

其他

欢迎大家在issue上提出问题,我这边会不定时的看issue,解决问题

GitHub

https://github.com/catchpig/kmvvm
You might also like...

❤️ Android Ghibli using Hilt, Motion, Coroutines, Jetpack (ViewModel) based on MVVM architecture.

Glibhi ❤️ Android Ghibli using Hilt, Motion, Coroutines, Jetpack (ViewModel) based on MVVM architecture. Tech stack & Open-source libraries Minimum SD

Mar 11, 2022

ViewBinding, ViewModel Sample code

Sample_viewBiningK viewBinding, viewModel 샘플코드입니다. 코드출처 app: "모던 안드로이드 아키텍쳐 - Room + LiveData + ViewModel 대통합(https://www.youtube.com/watch?v=fUbiWZ2g

Jan 1, 2022

AAC MVVM + Clean Architecture + Coroutine Flow

GithubBrowser MVVM Clean Architecture Sample AAC MVVM + Clean Architecture + Coroutine Flow 본 샘플 프로젝트는 https://github.com/omjoonkim/GitHubBrowserApp 을

May 3, 2022

ComposeKit with MVVM, DI, Coroutines,Flow

ComposeKit with MVVM, DI, Coroutines,Flow

ComposeKit ComposeKit with MVVM, DI, Coroutines,Flow ComposeKit Kotlin Multiplatform project using Jetpack Compose and SwiftUI Note: Intital implement

May 13, 2022

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, kotlin, navigation component, and so on...

Apr 4, 2022

A sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern.

This repository contains a sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern

May 9, 2022

A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test.

TVMaze-Cache A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test. Features MVVM Architecture + R

Mar 13, 2022

Movie app that receives popular movies and allows the user to search for the specific movie through the Rest API with help of retrofit library &MVVM architecture.

 Movie app that receives popular movies and allows the user to search for the specific movie through the Rest API with help of retrofit library &MVVM architecture.

MovieClue Millions of movies, TV shows and people to discover. Explore now Movie app that recieves popular movies and allow the user to search for spe

Mar 31, 2022

🔥Application created with MVVM, Retrofit, Coroutines, SWAPI and shimmer effect.

🔥 Application created with MVVM, Retrofit, Coroutines, SWAPI and shimmer effect. gif.mp4 📚 knowledges and technologies ViewBinding Retrofit Coroutin

Dec 3, 2021
Comments
  • 1. 啥时候升级gradle 7.2

    你好作者:

    1.新建项目默认都是最新的gradle,按照集成步骤报错,gradle 升级导致引入插件的方式改变,请问什么时候能升级最新版本的gradle 2.请问下自定义ResponseBodyConverter 是不是得要重写BaseResponseBodyConverter? 因为返回的数据格式格式各样 目前情况下处理是不是要绑定SerializationResponseBodyConverter拿到全部Response处理?

    3.有没有沟通群?想讨论学习下

    Reviewed by marren06 at 2022-04-12 06:37
Related tags
Android Jetpack MVVM Boilerplate. Integrated with Jetpack dependencies, Hilt, Room, Okhttp, Retrofit, etc.
Android Jetpack MVVM Boilerplate. Integrated with Jetpack dependencies, Hilt, Room, Okhttp, Retrofit, etc.

Android Jetpack MVVM Boilerplate Android Jetpack MVVM Boilerplate a Jetpack based, MVVM boilerplate template project for Modern Android. Features Here

Oct 27, 2021
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin

ReKotlin Port of ReSwift to Kotlin, which corresponds to ReSwift/4.0.0 Introduction ReKotlin is a Redux-like implementation of the unidirectional data

May 11, 2022
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin Model-View-ViewModel architecture components This is a Kotlin Multiplatform library that provides architecture components of Model-View-

May 17, 2022
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries

?? MyNotes Note taking Android App using androidx libraries, MVVM with Google Architectural components Room, LiveData and ViewModel. Written in Kotlin

May 1, 2022
Android App using Kotlin, MVVM, ViewModel, LiveData, Coroutines, Room and DataBinding
Android App using Kotlin, MVVM, ViewModel, LiveData, Coroutines, Room and DataBinding

Words Android App using Kotlin, MVVM, ViewModel, LiveData, Coroutines, Room and

Mar 9, 2022
App kotlin with flow, paging 3, MVVM, Room, Dagger hilt

TMDBTest App kotlin with flow, paging 3, MVVM, Room, Dagger hilt Para compilar la app se tiene que descargar el proyecto. Luego poner la APIKEY de TMD

Feb 22, 2022
Android MVVM with Single Activity sample app that uses kotlin coroutines flow
Android MVVM with Single Activity sample app that uses kotlin coroutines flow

Android MVVM with Single Activity sample app that uses kotlin coroutines flow. This is a sample app that uses kotlin coroutines flow , stateflow. This

Apr 8, 2022
Atividade do Google Codelabs, utilizando ViewModel e DataBinding.

Cupcake app This app contains an order flow for cupcakes with options for quantity, flavor, and pickup date. The order details get displayed on an ord

Nov 24, 2021