Skip to content

Commit b3b0df9

Browse files
committed
1.优化Flow的lifecycle回调
2.增加只有Activity和Fragment只有在前台时才收到回调,处于后台是暂停回调
1 parent 9e33e73 commit b3b0df9

File tree

7 files changed

+601
-188
lines changed

7 files changed

+601
-188
lines changed

CHANGE_lOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# CHANGE LOG
2+
### v1.4.0
3+
4+
+ 优化Flow的lifecycle回调
5+
+ 增加只有Activity和Fragment只有在前台时才收到回调,处于后台是暂停回调
6+
27
### v1.3.9
38

49
+ 优化日志打印

README.md

Lines changed: 145 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@
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)
@@ -46,6 +45,7 @@
4645
## Gradle
4746

4847
### 1. 在根目录的build.gradle中添加
48+
4949
```groovy
5050
plugins {
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
7173
ksp.incremental=false
7274
```
@@ -92,7 +94,6 @@ ksp "com.github.catchpig.kmvvm:compiler:last_version"
9294
implementation "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
463470
class 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
516525
bodyBinding.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

app/src/main/java/com/catchpig/kmvvm/article/ArticleFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.catchpig.kmvvm.adapter.ArticleAdapter
66
import com.catchpig.kmvvm.databinding.FragmentArticleBinding
77
import com.catchpig.mvvm.base.fragment.BaseVMFragment
88
import com.catchpig.mvvm.ext.lifecycleRefresh
9+
import com.catchpig.mvvm.ext.repeatOnLifecycleRefresh
910
import com.gyf.immersionbar.ktx.statusBarHeight
1011

1112
class ArticleFragment : BaseVMFragment<FragmentArticleBinding, ArticleViewModel>() {
@@ -50,7 +51,7 @@ class ArticleFragment : BaseVMFragment<FragmentArticleBinding, ArticleViewModel>
5051
bodyBinding.refreshView.run {
5152
setOnRefreshLoadMoreListener { nextPageIndex ->
5253
viewModel.queryArticles(nextPageIndex)
53-
.lifecycleRefresh(this@ArticleFragment, this)
54+
.repeatOnLifecycleRefresh(this@ArticleFragment, this)
5455
}
5556
}
5657
}

0 commit comments

Comments
 (0)