diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 66f66ad..51880d4 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -14,6 +14,7 @@ diff --git a/observer/build.gradle b/observer/build.gradle index 2769148..b3ad552 100644 --- a/observer/build.gradle +++ b/observer/build.gradle @@ -50,7 +50,7 @@ afterEvaluate { // You can then customize attributes of the publication as shown below. groupId = 'com.github.tangwanchao' artifactId = 'source-observer' - version = '1.1.4' + version = '2.0.0' } } } diff --git a/observer/src/main/java/me/twc/source/observer/engine/ISourceObserverView.kt b/observer/src/main/java/me/twc/source/observer/engine/ISourceObserverView.kt index dee0386..8cb8096 100644 --- a/observer/src/main/java/me/twc/source/observer/engine/ISourceObserverView.kt +++ b/observer/src/main/java/me/twc/source/observer/engine/ISourceObserverView.kt @@ -18,6 +18,11 @@ interface ISourceObserverView { */ fun showSourceErrorView() + /** + * 展示空数据 ui + */ + fun showSourceEmptyView() + /** * 展示成功 ui */ diff --git a/observer/src/main/java/me/twc/source/observer/widget/SourceObserverView.kt b/observer/src/main/java/me/twc/source/observer/widget/SourceObserverView.kt index e372900..806a2c5 100644 --- a/observer/src/main/java/me/twc/source/observer/widget/SourceObserverView.kt +++ b/observer/src/main/java/me/twc/source/observer/widget/SourceObserverView.kt @@ -56,6 +56,10 @@ abstract class SourceObserverView @JvmOverloads constructor( showRetry() } + override fun showSourceEmptyView() { + showEmpty() + } + override fun showSourceSuccessView() { showContent() } diff --git a/paging/.gitignore b/paging/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/paging/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/paging/build.gradle b/paging/build.gradle new file mode 100644 index 0000000..3a7bb7d --- /dev/null +++ b/paging/build.gradle @@ -0,0 +1,71 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'maven-publish' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.2" + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 30 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +// 用于打包源代码的任务 +task androidSourcesJar(type: Jar) { + archiveClassifier.set('sources') + from android.sourceSets.main.java.srcDirs +} + +afterEvaluate { + publishing { + publications { + // Creates a Maven publication called "release". + release(MavenPublication) { + // Applies the component for the release build variant. + from components.release + artifact androidSourcesJar + // You can then customize attributes of the publication as shown below. + groupId = 'com.github.tangwanchao' + artifactId = 'source-paging' + version = '2.0.0' + } + } + } +} + +dependencies { + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + + compileOnly 'com.scwang.smart:refresh-layout-kernel:2.0.3' + + compileOnly project(path: ':source') + compileOnly project(path: ':observer') +} \ No newline at end of file diff --git a/paging/consumer-rules.pro b/paging/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/paging/proguard-rules.pro b/paging/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/paging/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/paging/src/androidTest/java/me/twc/source/observer/paging/ExampleInstrumentedTest.kt b/paging/src/androidTest/java/me/twc/source/observer/paging/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..a048373 --- /dev/null +++ b/paging/src/androidTest/java/me/twc/source/observer/paging/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package me.twc.source.observer.paging + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("me.twc.source.observer.paging.test", appContext.packageName) + } +} \ No newline at end of file diff --git a/paging/src/main/AndroidManifest.xml b/paging/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3c060ca --- /dev/null +++ b/paging/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/paging/src/main/java/me/twc/source/observer/paging/IPagination.kt b/paging/src/main/java/me/twc/source/observer/paging/IPagination.kt new file mode 100644 index 0000000..b2b74f8 --- /dev/null +++ b/paging/src/main/java/me/twc/source/observer/paging/IPagination.kt @@ -0,0 +1,20 @@ +package me.twc.source.observer.paging + +/** + * @author 唐万超 + * @date 2022/09/22 + */ +interface IPagination { + /** + * 是否有更多数据 + * + * @return [true : 没有更多数据] + * [false: 有更多数据] + */ + fun noMoreData():Boolean + + /** + * 获取分页的数据 + */ + fun getPagingDataList():List +} \ No newline at end of file diff --git a/paging/src/main/java/me/twc/source/observer/paging/ObserverUtil.kt b/paging/src/main/java/me/twc/source/observer/paging/ObserverUtil.kt new file mode 100644 index 0000000..c477dc9 --- /dev/null +++ b/paging/src/main/java/me/twc/source/observer/paging/ObserverUtil.kt @@ -0,0 +1,64 @@ +package me.twc.source.observer.paging + +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import com.scwang.smart.refresh.layout.SmartRefreshLayout +import me.twc.source.ErrorSource +import me.twc.source.LoadingSource +import me.twc.source.Source +import me.twc.source.SuccessSource +import me.twc.source.observer.engine.ISourceObserverView + +/** + * 配合 [SmartRefreshLayout] 刷新观察 + */ +fun LiveData>>.paginationRefreshObserver( + owner: LifecycleOwner, + refreshLayout: SmartRefreshLayout, + observerView: ISourceObserverView, + block: (list: List) -> Unit +) = this.observe(owner) { source -> + when (source) { + LoadingSource -> { + refreshLayout.autoRefreshAnimationOnly() + refreshLayout.setEnableLoadMore(false) + } + is ErrorSource -> { + refreshLayout.finishRefresh(false) + observerView.showSourceErrorView() + } + is SuccessSource -> { + val pagination = source.data + refreshLayout.finishRefresh(0, true, pagination.noMoreData()) + val data = pagination.getPagingDataList() + if (data.isEmpty()) { + observerView.showSourceEmptyView() + } else { + refreshLayout.setEnableLoadMore(true) + observerView.showSourceSuccessView() + block(data) + } + } + } +} + +/** + * 配合 [SmartRefreshLayout] 加载更多观察 + */ +fun LiveData>>.paginationLoadMoreObserver( + owner: LifecycleOwner, + refreshLayout: SmartRefreshLayout, + block: (list: List) -> Unit +) = this.observe(owner) { source -> + when (source) { + LoadingSource -> Unit + is ErrorSource -> { + refreshLayout.finishLoadMore(0, false, false) + } + is SuccessSource -> { + val pagination = source.data + refreshLayout.finishLoadMore(0, true, pagination.noMoreData()) + block(pagination.getPagingDataList()) + } + } +} \ No newline at end of file diff --git a/paging/src/test/java/me/twc/source/observer/paging/ExampleUnitTest.kt b/paging/src/test/java/me/twc/source/observer/paging/ExampleUnitTest.kt new file mode 100644 index 0000000..c153b54 --- /dev/null +++ b/paging/src/test/java/me/twc/source/observer/paging/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package me.twc.source.observer.paging + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 045b5f6..f348344 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,3 +2,4 @@ include ':source' include ':app' rootProject.name = "RetrofitSource" include ':observer' +include ':paging' diff --git a/source/build.gradle b/source/build.gradle index 88c809a..f14f29f 100644 --- a/source/build.gradle +++ b/source/build.gradle @@ -50,7 +50,7 @@ afterEvaluate { // You can then customize attributes of the publication as shown below. groupId = 'com.github.tangwanchao' artifactId = 'retrofit-source' - version = '1.1.4' + version = '2.0.0' } } }