2727+ ### 封装工具扩展类:CalendarExt、ContextExt、DateExt、EditTextExt、GsonExt、RxJavaExt、StringExt、SnackbarExt
2828
2929## 架构图
30+
3031<image src =" ./images/架构图.png " style =" zoom :80% ;" />
3132
3233## 最低兼容:21
3334
34-
3535## release版本
3636
3737[ ![ ] ( https://jitpack.io/v/catchpig/kmvvm.svg )] ( https://jitpack.io/#catchpig/kmvvm )
3838
39-
4039# [ Gitee] ( https://gitee.com/catchpig/kmvvm )
4140
4241# [ Github] ( https://github.com/catchpig/kmvvm )
4645## Gradle
4746
4847### 1. 在根目录的build.gradle中添加
48+
4949``` groovy
5050plugins {
5151 id 'org.jetbrains.kotlin.jvm' version "1.8.0" apply false
@@ -54,6 +54,7 @@ plugins {
5454 id 'com.google.devtools.ksp' version '1.8.21-1.0.11' apply false
5555}
5656```
57+
5758### 2. 在app的build.gradle中添加
5859
5960``` groovy
@@ -67,6 +68,7 @@ plugins {
6768### 3. 在app的gradle.properties中添加
6869
6970+ 停用ksp增量编译
71+
7072``` properties
7173ksp.incremental =false
7274```
@@ -92,7 +94,6 @@ ksp "com.github.catchpig.kmvvm:compiler:last_version"
9294implementation "com.github.catchpig.kmvvm:download:last_version"
9395```
9496
95-
9697## 使用
9798
9899### 1. 配置全部参数
@@ -182,7 +183,7 @@ interface IGlobalConfig {
182183 */
183184 @IdRes
184185 fun onFailedReloadClickId (): Int
185-
186+
186187 /* *
187188 * 刷新每页加载个数
188189 * @return Int
@@ -221,7 +222,7 @@ class MvvmGlobalConfig : IGlobalConfig {
221222 }
222223
223224 override fun getTitleTextStyle (): Int {
224- return TextStyle .BOLD
225+ return TextStyle .BOLD
225226 }
226227
227228 override fun isShowTitleLine (): Boolean {
@@ -243,7 +244,7 @@ class MvvmGlobalConfig : IGlobalConfig {
243244 override fun getRecyclerEmptyBanding (parent : ViewGroup ): ViewBinding {
244245 return LayoutEmptyBinding .inflate(LayoutInflater .from(parent.context), parent, false )
245246 }
246-
247+
247248 override fun getFailedBinding (layoutInflater : LayoutInflater , any : Any ): ViewBinding ? {
248249 return when (any) {
249250 is BaseActivity <* > -> {
@@ -367,15 +368,16 @@ fun clickSecondDrawable(v: View) {
367368
368369+ 网络请求失败可展示失败页面,并有刷新按钮可以重新加载数据
369370+ 在lifecycleLoadingView扩展函数中将showFailedView设置为true,数据请求失败了,就会显示失败页面
370- + 在[ onFailedReload] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/view/BaseView.kt ) 的闭包中再次调用网络请求的接口,就可以重新再加载数据了
371+ + 在[ onFailedReload] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/view/BaseView.kt )
372+ 的闭包中再次调用网络请求的接口,就可以重新再加载数据了
371373
372374``` kotlin
373375/* *
374376 * 加载失败后展示失败页面,点击自定义失败页面的刷新按钮,重新请求数据
375377 * @param autoFirstLoad Boolean 第一次是否自动加载
376378 * @param block [@kotlin.ExtensionFunctionType] Function1<View, Unit>
377379 */
378- fun onFailedReload (autoFirstLoad : Boolean = true, block : View .() -> Unit ){
380+ fun onFailedReload (autoFirstLoad : Boolean = true, block : View .() -> Unit ) {
379381 .... .
380382}
381383```
@@ -416,15 +418,16 @@ snackbar.setOnClickListener {
416418
417419+ 网络请求失败可展示失败页面,并有刷新按钮可以重新加载数据
418420+ 在lifecycleLoadingView扩展函数中将showFailedView设置为true,数据请求失败了,就会显示失败页面
419- + 在[ onFailedReload] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/view/BaseView.kt ) 的闭包中再次调用网络请求的接口,就可以重新再加载数据了
421+ + 在[ onFailedReload] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/view/BaseView.kt )
422+ 的闭包中再次调用网络请求的接口,就可以重新再加载数据了
420423
421424``` kotlin
422425/* *
423426 * 加载失败后展示失败页面,点击自定义失败页面的刷新按钮,重新请求数据
424427 * @param autoFirstLoad Boolean 第一次是否自动加载
425428 * @param block [@kotlin.ExtensionFunctionType] Function1<View, Unit>
426429 */
427- fun onFailedReload (autoFirstLoad : Boolean = true, block : View .() -> Unit ){
430+ fun onFailedReload (autoFirstLoad : Boolean = true, block : View .() -> Unit ) {
428431 .... .
429432}
430433```
@@ -436,7 +439,7 @@ override fun initFlow() {
436439 }
437440}
438441
439- private fun loadBanners (){
442+ private fun loadBanners () {
440443 viewModel.queryBanners().lifecycleLoadingDialog(this , true ) {
441444 val images = mutableListOf<String >()
442445 this .forEach {
@@ -454,15 +457,19 @@ private fun loadBanners(){
454457
455458### 4. RecycleView
456459
457- + Adapter可以继承[ RecycleAdapter] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/adapter/RecyclerAdapter.kt ) 来使用,RecycleAdapter使用了ViewBanding,只需要实现以下两个个方法
460+ +
461+
462+ Adapter可以继承[ RecycleAdapter] ( ./mvvm/src/main/java/com/catchpig/mvvm/base/adapter/RecyclerAdapter.kt )
463+ 来使用,RecycleAdapter使用了ViewBanding,只需要实现以下两个个方法
464+
458465+ RecyclerAdapter可以调用setShowEmptyEnabled()方法来设置全局的空页面是否可用
459466
460467> 使用示例
461468
462469``` kotlin
463470class UserAdapter (iPageControl : IPageControl ) :
464471 RecyclerAdapter <User , ItemUserBinding >(iPageControl) {
465-
472+
466473 override fun viewBinding (parent : ViewGroup ): ItemUserBinding {
467474 return ItemUserBinding .inflate(LayoutInflater .from(parent.context), parent, false )
468475 }
@@ -478,7 +485,10 @@ class UserAdapter(iPageControl: IPageControl) :
478485### 5.刷新分页控件([ RefreshRecyclerView] ( ./mvvm/src/main/java/com/catchpig/mvvm/widget/refresh/RefreshRecyclerView.kt ) )
479486
480487+ RefreshRecyclerView集成了RefreshLayoutWrapper+RecyclerView
481- + 不用关心分页的逻辑,分页的刷新逻辑实现都在[ RefreshLayoutWrapper] ( ./mvvm/src/main/java/com/catchpig/mvvm/widget/refresh/RefreshLayoutWrapper.kt )
488+ +
489+
490+ 不用关心分页的逻辑,分页的刷新逻辑实现都在[ RefreshLayoutWrapper] ( ./mvvm/src/main/java/com/catchpig/mvvm/widget/refresh/RefreshLayoutWrapper.kt )
491+
482492+ 只需要设置LayoutManager和RecyclerAdapter,提供了setLayoutManager和setAdapter方法
483493+ 在获取到数据的时候调用updateData方法
484494+ 获取数据失败的时候调用updateError方法
@@ -496,17 +506,16 @@ class UserAdapter(iPageControl: IPageControl) :
496506``` xml
497507
498508<LinearLayout xmlns : android =" http://schemas.android.com/apk/res/android"
499- xmlns : app =" http://schemas.android.com/apk/res-auto" android : layout_width =" match_parent"
500- android : layout_height =" match_parent" android : orientation =" vertical" >
509+ xmlns : app =" http://schemas.android.com/apk/res-auto" android : layout_width =" match_parent"
510+ android : layout_height =" match_parent" android : orientation =" vertical" >
501511
502512 <TextView android : layout_width =" match_parent" android : layout_height =" 50dp"
503- android : background =" @color/colorPrimary" android : gravity =" center" android : text =" 文章"
504- android : textColor =" @color/color_white" />
513+ android : background =" @color/colorPrimary" android : gravity =" center" android : text =" 文章"
514+ android : textColor =" @color/color_white" />
505515
506516 <com .catchpig.mvvm.widget.refresh.RefreshRecyclerView android : id =" @+id/refresh"
507- android : layout_width =" match_parent"
508- android : layout_height =" match_parent"
509- app : recycler_background =" #445467" >
517+ android : layout_width =" match_parent" android : layout_height =" match_parent"
518+ app : recycler_background =" #445467" >
510519
511520 </com .catchpig.mvvm.widget.refresh.RefreshRecyclerView>
512521</LinearLayout >
@@ -515,7 +524,7 @@ class UserAdapter(iPageControl: IPageControl) :
515524``` kotlin
516525bodyBinding.refresh.run {
517526 setOnRefreshLoadMoreListener { nextPageIndex ->
518- viewModel.queryArticles(nextPageIndex).lifecycleRefresh(this @ArticleFragment,this )
527+ viewModel.queryArticles(nextPageIndex).lifecycleRefresh(this @ArticleFragment, this )
519528 }
520529}
521530```
@@ -618,53 +627,127 @@ class ResponseBodyConverter :
618627##### 6.2.4 如果想直接拿response的结果作为网络请求的返回值,可以直接将[ SerializationResponseBodyConverter] ( ./mvvm/src/main/java/com/catchpig/mvvm/network/converter/SerializationResponseBodyConverter.kt ) 加到ServiceApi注解的responseConverter属性上
619628
620629#### 6.3 FlowExt中扩展了网络请求方法(带lifecycleScope)
630+
621631+ 刷新+RecycleView的网络请求封装
622- - lifecycleRefresh(
623- base: BaseView, refreshLayoutWrapper: RefreshRecyclerView
624- )
632+ - lifecycleRefresh(
633+ base: BaseView,
634+ refreshLayoutWrapper: RefreshRecyclerView,
635+ callback: (MutableList<T >.() -> Unit)? = null
636+ )
637+ - repeatOnLifecycleRefresh(
638+ base: BaseView,
639+ refreshLayoutWrapper: RefreshRecyclerView,
640+ state: Lifecycle.State = Lifecycle.State.STARTED,
641+ callback: (MutableList<T >.() -> Unit)? = null
642+ )
625643+ 不带loading的网络请求封装
626- - lifecycle(
627- base: BaseView,
628- showFailedView: Boolean = false,
629- errorCallback: ((t: Throwable) -> Unit)? = null,
630- callback: T.() -> Unit
631- )
632- - lifecycle(
633- baseViewModel: BaseViewModel,
634- showFailedView: Boolean = false,
635- errorCallback: ((t: Throwable) -> Unit)? = null,
636- callback: T.() -> Unit
637- )
644+ - lifecycleNull(
645+ base: BaseView,
646+ showFailedView: Boolean = false,
647+ errorCallback: ((t: Throwable) -> Unit)? = null,
648+ callback: T?.() -> Unit
649+ )
650+ - repeatOnLifecycleNull(
651+ base: BaseView,
652+ showFailedView: Boolean = false,
653+ state: Lifecycle.State = Lifecycle.State.STARTED,
654+ errorCallback: ((t: Throwable) -> Unit)? = null,
655+ callback: T?.() -> Unit
656+ )
657+ - lifecycle(
658+ base: BaseView,
659+ showFailedView: Boolean = false,
660+ errorCallback: ((t: Throwable) -> Unit)? = null,
661+ callback: T.() -> Unit
662+ )
663+ - repeatOnLifecycle(
664+ base: BaseView,
665+ showFailedView: Boolean = false,
666+ state: Lifecycle.State = Lifecycle.State.STARTED,
667+ errorCallback: ((t: Throwable) -> Unit)? = null,
668+ callback: T.() -> Unit
669+ )
670+ - lifecycle(
671+ baseViewModel: BaseViewModel,
672+ showFailedView: Boolean = false,
673+ errorCallback: ((t: Throwable) -> Unit)? = null,
674+ callback: T.() -> Unit
675+ )
638676+ 带loadingView的网络请求封装
639- - lifecycleLoadingDialog(
640- base: BaseView,
641- showFailedView: Boolean = false,
642- errorCallback: ((t: Throwable) -> Unit)? = null,
643- callback: T.() -> Unit
644- )
645- - lifecycleLoadingDialog(
646- baseViewModel: BaseViewModel,
647- showFailedView: Boolean = false,
648- errorCallback: ((t: Throwable) -> Unit)? = null,
649- callback: T.() -> Unit
650- )
677+ - lifecycleLoadingDialogNull(
678+ base: BaseView,
679+ showFailedView: Boolean = false,
680+ errorCallback: ((t: Throwable) -> Unit)? = null,
681+ callback: T?.() -> Unit
682+ )
683+ - repeatOnLifecycleLoadingDialogNull(
684+ base: BaseView,
685+ showFailedView: Boolean = false,
686+ state: Lifecycle.State = Lifecycle.State.STARTED,
687+ errorCallback: ((t: Throwable) -> Unit)? = null,
688+ callback: T?.() -> Unit
689+ )
690+ - lifecycleLoadingDialog(
691+ base: BaseView,
692+ showFailedView: Boolean = false,
693+ errorCallback: ((t: Throwable) -> Unit)? = null,
694+ callback: T.() -> Unit
695+ )
696+ - repeatOnLifecycleLoadingDialog(
697+ base: BaseView,
698+ showFailedView: Boolean = false,
699+ state: Lifecycle.State = Lifecycle.State.STARTED,
700+ errorCallback: ((t: Throwable) -> Unit)? = null,
701+ callback: T.() -> Unit
702+ )
703+ - lifecycleLoadingDialog(
704+ baseViewModel: BaseViewModel,
705+ showFailedView: Boolean = false,
706+ errorCallback: ((t: Throwable) -> Unit)? = null,
707+ callback: T.() -> Unit
708+ )
709+
651710+ 带loadingDialog的网络请求封装
652- - lifecycleLoadingView(
653- base: BaseView,
654- showFailedView: Boolean = false,
655- errorCallback: ((t: Throwable) -> Unit)? = null,
656- callback: T.() -> Unit
657- )
658- - lifecycleLoadingView(
659- baseViewModel: BaseViewModel,
660- showFailedView: Boolean = false,
661- errorCallback: ((t: Throwable) -> Unit)? = null,
662- callback: T.() -> Unit
663- )
711+ - lifecycleLoadingViewNull(
712+ base: BaseView,
713+ showFailedView: Boolean = false,
714+ errorCallback: ((t: Throwable) -> Unit)? = null,
715+ callback: T?.() -> Unit
716+ )
717+ - repeatOnLifecycleLoadingViewNull(
718+ base: BaseView,
719+ showFailedView: Boolean = false,
720+ state: Lifecycle.State = Lifecycle.State.STARTED,
721+ errorCallback: ((t: Throwable) -> Unit)? = null,
722+ callback: T?.() -> Unit
723+ )
724+ - lifecycleLoadingView(
725+ base: BaseView,
726+ showFailedView: Boolean = false,
727+ errorCallback: ((t: Throwable) -> Unit)? = null,
728+ callback: T.() -> Unit
729+ )
730+ - repeatOnLifecycleLoadingView(
731+ base: BaseView,
732+ showFailedView: Boolean = false,
733+ state: Lifecycle.State = Lifecycle.State.STARTED,
734+ errorCallback: ((t: Throwable) -> Unit)? = null,
735+ callback: T.() -> Unit
736+ )
737+ - lifecycleLoadingView(
738+ baseViewModel: BaseViewModel,
739+ showFailedView: Boolean = false,
740+ errorCallback: ((t: Throwable) -> Unit)? = null,
741+ callback: T.() -> Unit
742+ )
664743
665744### 7. 日志
666745
667- + 不需要在Application中初始化,因为LogUtils已经在[ KotlinMvvmInitializer] ( ./mvvm/src/main/java/com/catchpig/mvvm/initializer/KotlinMvvmInitializer.kt ) 中初始化了
746+ +
747+
748+ 不需要在Application中初始化,因为LogUtils已经在[ KotlinMvvmInitializer] ( ./mvvm/src/main/java/com/catchpig/mvvm/initializer/KotlinMvvmInitializer.kt )
749+ 中初始化了
750+
668751+ 可以使用LogUtils.getInstance().i,LogUtils.getInstance().d等打印日志(不建议)
669752+ 也可以使用LogExt的扩展方法打印日志(建议)
670753
0 commit comments