From 7095135a4d02796dc54a14d4fd338e5ca8875109 Mon Sep 17 00:00:00 2001 From: Ztiany Date: Thu, 17 Oct 2019 21:56:46 +0800 Subject: [PATCH] refactor some class --- ...ResourceHandler.kt => LiveStateHandler.kt} | 53 ++-- .../android/base/app/aac/ResourceLiveData.kt | 239 ------------------ .../android/base/app/activity/BaseActivity.kt | 2 +- .../base/app/fragment/BaseDialogFragment.kt | 2 +- .../android/base/app/fragment/BaseFragment.kt | 2 +- .../com/android/base/app/mvp/RxPresenter.kt | 2 +- .../com/android/base/app/mvvm/RxViewModel.kt | 2 +- .../base/app/ui/RefreshStateLayoutEx.kt | 42 --- .../ui/{RefreshListLayoutEx.kt => UIKit.kt} | 39 +++ .../java/com/android/base/data/Resource.kt | 172 ------------- .../main/java/com/android/base/data/State.kt | 203 +++++++++++++++ .../main/java/com/android/base/data/Status.kt | 15 -- .../java/com/android/base/rx/RxLiveStateEx.kt | 207 +++++++++++++++ .../java/com/android/base/rx/RxLivedata.kt | 40 +++ .../RxKitForAutoDispose.kt} | 5 +- .../RxLiveStateExForAutodDispose.kt} | 135 +++++----- .../com/android/base/utils/common/Strings.kt | 99 ++++---- .../base/utils/security/security-utils.kt | 12 + lib_base/src/main/res/values/base_attrs.xml | 2 +- lib_qrcode/build.gradle | 1 - 20 files changed, 640 insertions(+), 634 deletions(-) rename lib_base/src/main/java/com/android/base/app/aac/{LiveResourceHandler.kt => LiveStateHandler.kt} (51%) delete mode 100644 lib_base/src/main/java/com/android/base/app/aac/ResourceLiveData.kt delete mode 100644 lib_base/src/main/java/com/android/base/app/ui/RefreshStateLayoutEx.kt rename lib_base/src/main/java/com/android/base/app/ui/{RefreshListLayoutEx.kt => UIKit.kt} (71%) delete mode 100644 lib_base/src/main/java/com/android/base/data/Resource.kt create mode 100644 lib_base/src/main/java/com/android/base/data/State.kt delete mode 100644 lib_base/src/main/java/com/android/base/data/Status.kt create mode 100644 lib_base/src/main/java/com/android/base/rx/RxLiveStateEx.kt create mode 100644 lib_base/src/main/java/com/android/base/rx/RxLivedata.kt rename lib_base/src/main/java/com/android/base/rx/{AutoDispose.kt => autodispose/RxKitForAutoDispose.kt} (97%) rename lib_base/src/main/java/com/android/base/{app/aac/AutoDisposeLiveData.kt => rx/autodispose/RxLiveStateExForAutodDispose.kt} (50%) create mode 100644 lib_base/src/main/java/com/android/base/utils/security/security-utils.kt diff --git a/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt b/lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt similarity index 51% rename from lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt rename to lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt index b45bfac..3965229 100644 --- a/lib_base/src/main/java/com/android/base/app/aac/LiveResourceHandler.kt +++ b/lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt @@ -5,93 +5,76 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import com.android.base.app.Sword import com.android.base.app.ui.LoadingView -import com.android.base.data.Resource +import com.android.base.data.State import timber.log.Timber -interface LiveResourceHandler { +interface LiveStateHandler { /**处理异常*/ fun handleError(throwable: Throwable) } -fun H.handleLiveResource( - liveData: LiveData>, +fun H.handleLiveState( + liveData: LiveData>, forceLoading: Boolean = true, onSuccess: (T?) -> Unit -) where H : LiveResourceHandler, H : LoadingView, H : LifecycleOwner { +) where H : LiveStateHandler, H : LoadingView, H : LifecycleOwner { liveData.observe(this, Observer { when { it.isError -> { - Timber.d("handleLiveResource -> isError") + Timber.d("handleLiveState -> isError") dismissLoadingDialog() handleError(it.error()) } it.isLoading -> { - Timber.d("handleLiveResource -> isLoading") + Timber.d("handleLiveState -> isLoading") showLoadingDialog(!forceLoading) } it.isSuccess -> { - Timber.d("handleLiveResource -> isSuccess") + Timber.d("handleLiveState -> isSuccess") val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - if (minimumShowingDialogMills == 0L) { - dismissLoadingDialog() + dismissLoadingDialog(minimumShowingDialogMills) { onSuccess(it.get()) - } else { - dismissLoadingDialog(minimumShowingDialogMills) { - onSuccess(it.get()) - } } - - } + }//success end } }) } -fun H.handleLiveResourceWithData( - liveData: LiveData>, +fun H.handleLiveStateWithData( + liveData: LiveData>, forceLoading: Boolean = true, onEmpty: (() -> Unit)? = null, onSuccess: (T) -> Unit -) where H : LiveResourceHandler, H : LoadingView, H : LifecycleOwner { +) where H : LiveStateHandler, H : LoadingView, H : LifecycleOwner { liveData.observe(this, Observer { when { it.isError -> { - Timber.d("handleLiveResourceWithData -> isError") + Timber.d("handleLiveStateWithData -> isError") dismissLoadingDialog() handleError(it.error()) } it.isLoading -> { - Timber.d("handleLiveResourceWithData -> isLoading") + Timber.d("handleLiveStateWithData -> isLoading") showLoadingDialog(!forceLoading) } it.isSuccess -> { - Timber.d("handleLiveResourceWithData -> isSuccess") - + Timber.d("handleLiveStateWithData -> isSuccess") val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - - if (minimumShowingDialogMills == 0L) { - dismissLoadingDialog() + dismissLoadingDialog(minimumShowingDialogMills) { if (it.hasData()) { onSuccess(it.data()) } else { onEmpty?.invoke() } - } else { - dismissLoadingDialog(minimumShowingDialogMills) { - if (it.hasData()) { - onSuccess(it.data()) - } else { - onEmpty?.invoke() - } - } } - } + }//success end } }) diff --git a/lib_base/src/main/java/com/android/base/app/aac/ResourceLiveData.kt b/lib_base/src/main/java/com/android/base/app/aac/ResourceLiveData.kt deleted file mode 100644 index b49cd24..0000000 --- a/lib_base/src/main/java/com/android/base/app/aac/ResourceLiveData.kt +++ /dev/null @@ -1,239 +0,0 @@ -package com.android.base.app.aac - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import com.android.base.data.Resource -import com.android.base.rx.subscribeIgnoreError -import com.github.dmstocking.optional.java.util.Optional -import io.reactivex.* - - -//----------------------------------------------------------------------------------------- - -fun Observable.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(it)) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Observable.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(map(it))) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Observable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(it.orElse(null))) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Observable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - val value = map(it.orElse(null)) - liveData.postValue(Resource.success(value)) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Flowable.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(it)) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Flowable.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(map(it))) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Flowable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(it.orElse(null))) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Flowable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - val value = map(it.orElse(null)) - liveData.postValue(Resource.success(value)) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Completable.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success()) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -fun Completable.subscribeWithLiveData(liveData: MutableLiveData>, provider: () -> T) { - liveData.postValue(Resource.loading()) - this.subscribe( - { - liveData.postValue(Resource.success(provider())) - }, - { - liveData.postValue(Resource.error(it)) - } - ) -} - -//----------------------------------------------------------------------------------------- - -fun Observable.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() - subscribe( - { - mutableLiveData.postValue(Resource.success(it)) - }, - { - mutableLiveData.postValue(Resource.error(it)) - } - ) - return mutableLiveData -} - -fun Observable>.optionalToResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() - subscribe( - { - mutableLiveData.postValue(Resource.success(it.orElse(null))) - }, - { - mutableLiveData.postValue(Resource.error(it)) - } - ) - return mutableLiveData -} - -fun Flowable.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() - subscribe( - { - mutableLiveData.postValue(Resource.success(it)) - }, - { - mutableLiveData.postValue(Resource.error(it)) - } - ) - return mutableLiveData -} - -fun Flowable>.optionalToResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() - subscribe( - { - mutableLiveData.postValue(Resource.success(it.orElse(null))) - }, - { - mutableLiveData.postValue(Resource.error(it)) - } - ) - return mutableLiveData -} - -fun Completable.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() - subscribe( - { - mutableLiveData.postValue(Resource.success()) - }, - { - mutableLiveData.postValue(Resource.error(it)) - } - ) - return mutableLiveData -} - -//----------------------------------------------------------------------------------------- - -fun Observable.toLiveData(): LiveData { - val liveData = MutableLiveData() - this.subscribeIgnoreError { - liveData.postValue(it) - } - return liveData -} - -fun Flowable.toLiveData(): LiveData { - val liveData = MutableLiveData() - this.subscribeIgnoreError { - liveData.postValue(it) - } - return liveData -} - -fun Single.toLiveData(): LiveData { - val liveData = MutableLiveData() - this.subscribeIgnoreError { - liveData.postValue(it) - } - return liveData -} - -fun Maybe.toLiveData(): LiveData { - val liveData = MutableLiveData() - this.subscribeIgnoreError { - liveData.postValue(it) - } - return liveData -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/activity/BaseActivity.kt b/lib_base/src/main/java/com/android/base/app/activity/BaseActivity.kt index 5b8dbf8..328820e 100644 --- a/lib_base/src/main/java/com/android/base/app/activity/BaseActivity.kt +++ b/lib_base/src/main/java/com/android/base/app/activity/BaseActivity.kt @@ -6,7 +6,7 @@ import android.view.View import androidx.annotation.UiThread import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import com.android.base.rx.AutoDisposeLifecycleOwnerEx +import com.android.base.rx.autodispose.AutoDisposeLifecycleOwnerEx import com.android.base.utils.android.compat.AndroidVersion import com.github.dmstocking.optional.java.util.function.Predicate import timber.log.Timber diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt index c7f0571..676a7cb 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt @@ -15,7 +15,7 @@ import com.android.base.app.activity.OnBackPressListener import com.android.base.app.fragment.delegates.FragmentDelegate import com.android.base.app.fragment.delegates.FragmentDelegateOwner import com.android.base.app.ui.LoadingView -import com.android.base.rx.AutoDisposeLifecycleOwnerEx +import com.android.base.rx.autodispose.AutoDisposeLifecycleOwnerEx import com.github.dmstocking.optional.java.util.function.Predicate import timber.log.Timber diff --git a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt index 2ea9206..620a75a 100644 --- a/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt +++ b/lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt @@ -18,7 +18,7 @@ import com.android.base.app.fragment.delegates.FragmentDelegate import com.android.base.app.fragment.delegates.FragmentDelegateOwner import com.android.base.app.fragment.tools.FragmentConfig import com.android.base.app.ui.LoadingView -import com.android.base.rx.AutoDisposeLifecycleOwnerEx +import com.android.base.rx.autodispose.AutoDisposeLifecycleOwnerEx import com.github.dmstocking.optional.java.util.function.Predicate import timber.log.Timber diff --git a/lib_base/src/main/java/com/android/base/app/mvp/RxPresenter.kt b/lib_base/src/main/java/com/android/base/app/mvp/RxPresenter.kt index aa5b16b..40725ba 100644 --- a/lib_base/src/main/java/com/android/base/app/mvp/RxPresenter.kt +++ b/lib_base/src/main/java/com/android/base/app/mvp/RxPresenter.kt @@ -1,7 +1,7 @@ package com.android.base.app.mvp import androidx.annotation.CallSuper -import com.android.base.rx.AutoDisposeLifecycleScopeProviderEx +import com.android.base.rx.autodispose.AutoDisposeLifecycleScopeProviderEx import com.uber.autodispose.lifecycle.CorrespondingEventsFunction import com.uber.autodispose.lifecycle.LifecycleEndedException import com.uber.autodispose.lifecycle.LifecycleScopes diff --git a/lib_base/src/main/java/com/android/base/app/mvvm/RxViewModel.kt b/lib_base/src/main/java/com/android/base/app/mvvm/RxViewModel.kt index 0aa6398..15b06c3 100644 --- a/lib_base/src/main/java/com/android/base/app/mvvm/RxViewModel.kt +++ b/lib_base/src/main/java/com/android/base/app/mvvm/RxViewModel.kt @@ -3,7 +3,7 @@ package com.android.base.app.mvvm import androidx.annotation.CallSuper import androidx.lifecycle.ViewModel -import com.android.base.rx.AutoDisposeLifecycleScopeProviderEx +import com.android.base.rx.autodispose.AutoDisposeLifecycleScopeProviderEx import com.uber.autodispose.lifecycle.CorrespondingEventsFunction import com.uber.autodispose.lifecycle.LifecycleEndedException import com.uber.autodispose.lifecycle.LifecycleScopes diff --git a/lib_base/src/main/java/com/android/base/app/ui/RefreshStateLayoutEx.kt b/lib_base/src/main/java/com/android/base/app/ui/RefreshStateLayoutEx.kt deleted file mode 100644 index bbc3846..0000000 --- a/lib_base/src/main/java/com/android/base/app/ui/RefreshStateLayoutEx.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.android.base.app.ui - -import com.android.base.app.Sword -import timber.log.Timber - -fun RefreshStateLayout.handleResultWithStatus(t: T?, onResult: ((T) -> Unit)) { - if (isRefreshing) { - refreshCompleted() - } - if (t == null || (t is Collection<*> && t.isEmpty()) || (t is Map<*, *> && t.isEmpty())) { - showEmptyLayout() - } else { - onResult.invoke(t) - showContentLayout() - } -} - -fun RefreshStateLayout.handleErrorWithStatus(throwable: Throwable?) { - if (throwable == null) { - Timber.d("processErrorWithStatus called, but throwable is null") - return - } - if (isRefreshing) { - refreshCompleted() - } - val errorTypeClassifier = Sword.get().errorClassifier() - if (errorTypeClassifier != null) { - when { - errorTypeClassifier.isNetworkError(throwable) -> { - Timber.d("isNetworkError showNetErrorLayout") - showNetErrorLayout() - } - errorTypeClassifier.isServerError(throwable) -> { - Timber.d("isServerError showServerErrorLayout") - showServerErrorLayout() - } - else -> showErrorLayout() - } - } else { - showErrorLayout() - } -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/ui/RefreshListLayoutEx.kt b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt similarity index 71% rename from lib_base/src/main/java/com/android/base/app/ui/RefreshListLayoutEx.kt rename to lib_base/src/main/java/com/android/base/app/ui/UIKit.kt index 39356dc..04fbcf2 100644 --- a/lib_base/src/main/java/com/android/base/app/ui/RefreshListLayoutEx.kt +++ b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt @@ -124,3 +124,42 @@ fun RefreshListLayout<*>.showLoadingIfEmpty() { } } } + + +fun RefreshStateLayout.handleResultWithStatus(t: T?, onResult: ((T) -> Unit)) { + if (isRefreshing) { + refreshCompleted() + } + if (t == null || (t is Collection<*> && t.isEmpty()) || (t is Map<*, *> && t.isEmpty())) { + showEmptyLayout() + } else { + onResult.invoke(t) + showContentLayout() + } +} + +fun RefreshStateLayout.handleErrorWithStatus(throwable: Throwable?) { + if (throwable == null) { + Timber.d("processErrorWithStatus called, but throwable is null") + return + } + if (isRefreshing) { + refreshCompleted() + } + val errorTypeClassifier = Sword.get().errorClassifier() + if (errorTypeClassifier != null) { + when { + errorTypeClassifier.isNetworkError(throwable) -> { + Timber.d("isNetworkError showNetErrorLayout") + showNetErrorLayout() + } + errorTypeClassifier.isServerError(throwable) -> { + Timber.d("isServerError showServerErrorLayout") + showServerErrorLayout() + } + else -> showErrorLayout() + } + } else { + showErrorLayout() + } +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/data/Resource.kt b/lib_base/src/main/java/com/android/base/data/Resource.kt deleted file mode 100644 index 6ec7dc9..0000000 --- a/lib_base/src/main/java/com/android/base/data/Resource.kt +++ /dev/null @@ -1,172 +0,0 @@ -package com.android.base.data - - -/** - * @author Ztiany - * Email: ztiany3@gmail.com - * Date : 2018-05-15 16:23 - */ -class Resource private constructor( - private val error: Throwable?, - //data or default data - private val data: T?, - private val status: Status -) { - - val isSuccess: Boolean - get() = status == Status.SUCCESS - - val isNoChange: Boolean - get() = status == Status.NOT_CHANGED - - val isLoading: Boolean - get() = status == Status.LOADING - - val isError: Boolean - get() = status == Status.ERROR - - fun hasData(): Boolean { - return data != null - } - - /** - * 获取 Resource 中保存的数据,只有在 success 状态并且存在数据时下才能调用此方法,否则将抛出异常。 - * - * @return Resource 中保存的数据。 - * @throws UnsupportedOperationException 非 success 状态调用此方法。 - * @throws NullPointerException Resource 中没有保存数据时调用此方法。 - */ - fun data(): T { - if (isError || isLoading || isNoChange) { - throw UnsupportedOperationException("This method can only be called when the is state success") - } - if (data == null) { - throw NullPointerException("Data is null") - } - return data - } - - /** - * 获取 Resource 中保存的数据,如果不存在数据则返回 defaultData 所设置的默认数据,在不同状态下获取的数据具有不同的意义: - * - * * success 状态下,返回一个成功操作所产生的数据 - * * error 状态下,返回一个默认的数据,如果存在的话 - * * loading 状态下,返回一个默认的数据,如果存在的话 - * - * @param defaultData 如果不存在数据则返回 defaultData 所设置的默认数据。 - * @return Resource 中保存的数据。 - */ - fun orElse(defaultData: T?): T? { - return data ?: defaultData - } - - /** - * 获取 Resource 中保存的数据,在不同状态下获取的数据具有不同的意义: - * - * * success 状态下,返回一个成功操作所产生的数据 - * * error 状态下,返回一个默认的数据,如果存在的话 - * * loading 状态下,返回一个默认的数据,如果存在的话 - * - * @return Resource 中保存的数据。 - */ - fun get(): T? { - return data - } - - fun error(): Throwable { - return error ?: throw NullPointerException("This method can only be called when the state is error") - } - - override fun toString(): String { - return "Resource{" + - "mError=" + error + - ", mStatus=" + status + - ", mData=" + data + - '}'.toString() - } - - companion object { - - fun success(): Resource { - return Resource(null, null, Status.SUCCESS) - } - - fun success(data: T?): Resource { - return Resource(null, data, Status.SUCCESS) - } - - fun error(error: Throwable): Resource { - return error(error, null) - } - - /** - * 创建一个 error 状态,且设置一个默认的数据 - */ - fun error(error: Throwable, defaultValue: T?): Resource { - return Resource(error, defaultValue, Status.ERROR) - } - - fun loading(): Resource { - return loading(null) - } - - /** - * 创建一个 loading 状态,且设置一个默认的数据 - */ - fun loading(defaultValue: T?): Resource { - return Resource(null, defaultValue, Status.LOADING) - } - - /** - * 如果数据源(比如 Repository)缓存了上一次请求的数据,然后对其当前请求返回的数据,发现数据是一样的,可以使用此状态表示 - * - * @return Resource - */ - fun noChange(): Resource { - return Resource(null, null, Status.NOT_CHANGED) - } - } - -} - - -/**when in loading*/ -inline fun Resource.onLoading(onLoading: () -> Unit): Resource { - if (this.isLoading) { - onLoading() - } - return this -} - -/**when error occurred*/ -inline fun Resource.onError(onError: (error: Throwable) -> Unit): Resource { - if (this.isError) { - onError(error()) - } - return this -} - -/**when no change*/ -inline fun Resource.onNoChange(onNoChange: () -> Unit): Resource { - if (this.isNoChange) { - onNoChange() - } - return this -} - -/**when succeeded*/ -inline fun Resource.onSuccess(onSuccess: (data: T?) -> Unit): Resource { - if (this.isSuccess) { - onSuccess(this.orElse(null)) - } - return this -} - -/**when succeeded and has data*/ -inline fun Resource.onSuccessWithData(onSuccess: (data: T) -> Unit): Resource { - val t = this.get() - if (this.isSuccess && t != null) { - onSuccess(t) - } - return this -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/data/State.kt b/lib_base/src/main/java/com/android/base/data/State.kt new file mode 100644 index 0000000..2a8a1f3 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/data/State.kt @@ -0,0 +1,203 @@ +package com.android.base.data + + +/** + * @author Ztiany + * Email: ztiany3@gmail.com + * Date : 2018-05-15 16:23 + */ +class State private constructor( + private val error: Throwable?, + //data or default data + private val data: T?, + private val status: Int +) { + + val isSuccess: Boolean + get() = status == SUCCESS + + val isNoChange: Boolean + get() = status == NOT_CHANGED + + val isLoading: Boolean + get() = status == LOADING + + val isError: Boolean + get() = status == ERROR + + fun hasData(): Boolean { + return data != null + } + + /** + * 获取 State 中保存的数据,只有在 success 状态并且存在数据时下才能调用此方法,否则将抛出异常。 + * + * @return State 中保存的数据。 + * @throws UnsupportedOperationException 非 success 状态调用此方法。 + * @throws NullPointerException State 中没有保存数据时调用此方法。 + */ + fun data(): T { + if (isError || isLoading || isNoChange) { + throw UnsupportedOperationException("This method can only be called when the is state success") + } + if (data == null) { + throw NullPointerException("Data is null") + } + return data + } + + /** + * 获取 State 中保存的数据,如果不存在数据则返回 defaultData 所设置的默认数据,在不同状态下获取的数据具有不同的意义: + * + * * success 状态下,返回一个成功操作所产生的数据 + * * error 状态下,返回一个默认的数据,如果存在的话 + * * loading 状态下,返回一个默认的数据,如果存在的话 + * + * @param defaultData 如果不存在数据则返回 defaultData 所设置的默认数据。 + * @return State 中保存的数据。 + */ + fun orElse(defaultData: T?): T? { + return data ?: defaultData + } + + /** + * 获取 State 中保存的数据,在不同状态下获取的数据具有不同的意义: + * + * * success 状态下,返回一个成功操作所产生的数据 + * * error 状态下,返回一个默认的数据,如果存在的话 + * * loading 状态下,返回一个默认的数据,如果存在的话 + * + * @return State 中保存的数据。 + */ + fun get(): T? { + return data + } + + fun error(): Throwable { + return error + ?: throw NullPointerException("This method can only be called when the state is error") + } + + override fun toString(): String { + return "State{" + + "mError=" + error + + ", mStatus=" + status + + ", mData=" + data + + '}'.toString() + } + + companion object { + + private const val LOADING = 1 + private const val ERROR = 2 + private const val SUCCESS = 3 + private const val NOT_CHANGED = 4 + + fun success(): State { + return State(null, null, SUCCESS) + } + + fun success(data: T?): State { + return State(null, data, SUCCESS) + } + + fun error(error: Throwable): State { + return error(error, null) + } + + /** + * 创建一个 error 状态,且设置一个默认的数据 + */ + fun error(error: Throwable, defaultValue: T?): State { + return State(error, defaultValue, ERROR) + } + + fun loading(): State { + return loading(null) + } + + /** + * 创建一个 loading 状态,且设置一个默认的数据 + */ + fun loading(defaultValue: T?): State { + return State(null, defaultValue, LOADING) + } + + /** + * 如果数据源(比如 Repository)缓存了上一次请求的数据,然后对其当前请求返回的数据,发现数据是一样的,可以使用此状态表示 + * + * @return State + */ + fun noChange(): State { + return State(null, null, NOT_CHANGED) + } + } + +} + +class StateHandler { + var onError: ((Throwable) -> Unit)? = null + var onLoading: (() -> Unit)? = null + var onSuccess: ((T?) -> Unit)? = null + var onSuccessWithData: ((T) -> Unit)? = null + var onEmpty: (() -> Unit)? = null +} + +/**handle all state*/ +inline fun State.handleState(handler: StateHandler.() -> Unit) { + val stateHandler = StateHandler() + handler(stateHandler) + when { + isError -> stateHandler.onError?.invoke(error()) + isLoading -> stateHandler.onLoading?.invoke() + isSuccess -> { + stateHandler.onSuccess?.invoke(get()) + if (hasData()) { + stateHandler.onSuccessWithData?.invoke(data()) + } else { + stateHandler.onEmpty?.invoke() + } + } + } +} + +/**when in loading*/ +inline fun State.onLoading(onLoading: () -> Unit): State { + if (this.isLoading) { + onLoading() + } + return this +} + +/**when error occurred*/ +inline fun State.onError(onError: (error: Throwable) -> Unit): State { + if (this.isError) { + onError(error()) + } + return this +} + +/**when no change*/ +inline fun State.onNoChange(onNoChange: () -> Unit): State { + if (this.isNoChange) { + onNoChange() + } + return this +} + +/**when succeeded*/ +inline fun State.onSuccess(onSuccess: (data: T?) -> Unit): State { + if (this.isSuccess) { + onSuccess(this.orElse(null)) + } + return this +} + +/**when succeeded and has data*/ +inline fun State.onSuccessWithData(onSuccess: (data: T) -> Unit): State { + val t = this.get() + if (this.isSuccess && t != null) { + onSuccess(t) + } + return this +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/data/Status.kt b/lib_base/src/main/java/com/android/base/data/Status.kt deleted file mode 100644 index c68eb77..0000000 --- a/lib_base/src/main/java/com/android/base/data/Status.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.android.base.data - -/** - * 用于表示各种状态 - * - * @author Ztiany - * Email: ztiany3@gmail.com - * Date : 2019-02-18 11:49 - */ -enum class Status { - LOADING, - ERROR, - SUCCESS, - NOT_CHANGED -} diff --git a/lib_base/src/main/java/com/android/base/rx/RxLiveStateEx.kt b/lib_base/src/main/java/com/android/base/rx/RxLiveStateEx.kt new file mode 100644 index 0000000..aa98469 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/rx/RxLiveStateEx.kt @@ -0,0 +1,207 @@ +package com.android.base.rx + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.android.base.data.State +import com.github.dmstocking.optional.java.util.Optional +import io.reactivex.Completable +import io.reactivex.Flowable +import io.reactivex.Observable + + +//----------------------------------------------------------------------------------------- +fun Observable.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(it)) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Observable.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(map(it))) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Observable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(it.orElse(null))) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Observable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { + liveData.postValue(State.loading()) + this.subscribe( + { + val value = map(it.orElse(null)) + liveData.postValue(State.success(value)) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Flowable.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(it)) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Flowable.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(map(it))) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Flowable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(it.orElse(null))) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Flowable>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { + liveData.postValue(State.loading()) + this.subscribe( + { + val value = map(it.orElse(null)) + liveData.postValue(State.success(value)) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Completable.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success()) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +fun Completable.subscribeWithLiveData(liveData: MutableLiveData>, provider: () -> T) { + liveData.postValue(State.loading()) + this.subscribe( + { + liveData.postValue(State.success(provider())) + }, + { + liveData.postValue(State.error(it)) + } + ) +} + +//----------------------------------------------------------------------------------------- + +fun Observable.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() + subscribe( + { + mutableLiveData.postValue(State.success(it)) + }, + { + mutableLiveData.postValue(State.error(it)) + } + ) + return mutableLiveData +} + +fun Observable>.optionalToResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() + subscribe( + { + mutableLiveData.postValue(State.success(it.orElse(null))) + }, + { + mutableLiveData.postValue(State.error(it)) + } + ) + return mutableLiveData +} + +fun Flowable.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() + subscribe( + { + mutableLiveData.postValue(State.success(it)) + }, + { + mutableLiveData.postValue(State.error(it)) + } + ) + return mutableLiveData +} + +fun Flowable>.optionalToResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() + subscribe( + { + mutableLiveData.postValue(State.success(it.orElse(null))) + }, + { + mutableLiveData.postValue(State.error(it)) + } + ) + return mutableLiveData +} + +fun Completable.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() + subscribe( + { + mutableLiveData.postValue(State.success()) + }, + { + mutableLiveData.postValue(State.error(it)) + } + ) + return mutableLiveData +} + +//----------------------------------------------------------------------------------------- diff --git a/lib_base/src/main/java/com/android/base/rx/RxLivedata.kt b/lib_base/src/main/java/com/android/base/rx/RxLivedata.kt new file mode 100644 index 0000000..b8e3349 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/rx/RxLivedata.kt @@ -0,0 +1,40 @@ +package com.android.base.rx + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import io.reactivex.Flowable +import io.reactivex.Maybe +import io.reactivex.Observable +import io.reactivex.Single + +fun Observable.toLiveData(): LiveData { + val liveData = MutableLiveData() + this.subscribeIgnoreError { + liveData.postValue(it) + } + return liveData +} + +fun Flowable.toLiveData(): LiveData { + val liveData = MutableLiveData() + this.subscribeIgnoreError { + liveData.postValue(it) + } + return liveData +} + +fun Single.toLiveData(): LiveData { + val liveData = MutableLiveData() + this.subscribeIgnoreError { + liveData.postValue(it) + } + return liveData +} + +fun Maybe.toLiveData(): LiveData { + val liveData = MutableLiveData() + this.subscribeIgnoreError { + liveData.postValue(it) + } + return liveData +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/rx/AutoDispose.kt b/lib_base/src/main/java/com/android/base/rx/autodispose/RxKitForAutoDispose.kt similarity index 97% rename from lib_base/src/main/java/com/android/base/rx/AutoDispose.kt rename to lib_base/src/main/java/com/android/base/rx/autodispose/RxKitForAutoDispose.kt index 8c57c8d..b4027a5 100644 --- a/lib_base/src/main/java/com/android/base/rx/AutoDispose.kt +++ b/lib_base/src/main/java/com/android/base/rx/autodispose/RxKitForAutoDispose.kt @@ -1,10 +1,11 @@ @file:JvmName("AutoDisposeUtils") -package com.android.base.rx +package com.android.base.rx.autodispose import android.view.View import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner +import com.android.base.rx.RxKit import com.uber.autodispose.* import com.uber.autodispose.AutoDispose.autoDisposable import com.uber.autodispose.android.ViewScopeProvider @@ -14,7 +15,7 @@ import io.reactivex.* import io.reactivex.disposables.Disposable import timber.log.Timber -fun View.newScopeProvider() = ViewScopeProvider.from(this) +fun View.newScopeProvider(): ScopeProvider = ViewScopeProvider.from(this) interface AutoDisposeLifecycleScopeProviderEx : LifecycleScopeProvider { diff --git a/lib_base/src/main/java/com/android/base/app/aac/AutoDisposeLiveData.kt b/lib_base/src/main/java/com/android/base/rx/autodispose/RxLiveStateExForAutodDispose.kt similarity index 50% rename from lib_base/src/main/java/com/android/base/app/aac/AutoDisposeLiveData.kt rename to lib_base/src/main/java/com/android/base/rx/autodispose/RxLiveStateExForAutodDispose.kt index b01cbe9..1d171be 100644 --- a/lib_base/src/main/java/com/android/base/app/aac/AutoDisposeLiveData.kt +++ b/lib_base/src/main/java/com/android/base/rx/autodispose/RxLiveStateExForAutodDispose.kt @@ -1,204 +1,203 @@ -package com.android.base.app.aac +package com.android.base.rx.autodispose import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.android.base.data.Resource -import com.android.base.rx.subscribeIgnoreError +import com.android.base.data.State import com.github.dmstocking.optional.java.util.Optional import com.uber.autodispose.* //----------------------------------------------------------------------------------------- -fun ObservableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) +fun ObservableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(it)) + liveData.postValue(State.success(it)) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun ObservableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { - liveData.postValue(Resource.loading()) +fun ObservableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(map(it))) + liveData.postValue(State.success(map(it))) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun ObservableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) +fun ObservableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(it.orElse(null))) + liveData.postValue(State.success(it.orElse(null))) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun ObservableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { - liveData.postValue(Resource.loading()) +fun ObservableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { + liveData.postValue(State.loading()) this.subscribe( { val value = map(it.orElse(null)) - liveData.postValue(Resource.success(value)) + liveData.postValue(State.success(value)) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun FlowableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) +fun FlowableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(it)) + liveData.postValue(State.success(it)) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun FlowableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { - liveData.postValue(Resource.loading()) +fun FlowableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, map: (T) -> R) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(map(it))) + liveData.postValue(State.success(map(it))) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun FlowableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) +fun FlowableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(it.orElse(null))) + liveData.postValue(State.success(it.orElse(null))) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun FlowableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { - liveData.postValue(Resource.loading()) +fun FlowableSubscribeProxy>.subscribeOptionalWithLiveData(liveData: MutableLiveData>, map: (T?) -> R?) { + liveData.postValue(State.loading()) this.subscribe( { val value = map(it.orElse(null)) - liveData.postValue(Resource.success(value)) + liveData.postValue(State.success(value)) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { - liveData.postValue(Resource.loading()) +fun CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success()) + liveData.postValue(State.success()) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } -fun CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, provider: () -> T) { - liveData.postValue(Resource.loading()) +fun CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData>, provider: () -> T) { + liveData.postValue(State.loading()) this.subscribe( { - liveData.postValue(Resource.success(provider())) + liveData.postValue(State.success(provider())) }, { - liveData.postValue(Resource.error(it)) + liveData.postValue(State.error(it)) } ) } //----------------------------------------------------------------------------------------- -fun ObservableSubscribeProxy.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() +fun ObservableSubscribeProxy.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() subscribe( { - mutableLiveData.postValue(Resource.success(it)) + mutableLiveData.postValue(State.success(it)) }, { - mutableLiveData.postValue(Resource.error(it)) + mutableLiveData.postValue(State.error(it)) } ) return mutableLiveData } -fun ObservableSubscribeProxy>.optionalToResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() +fun ObservableSubscribeProxy>.optionalToResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() subscribe( { - mutableLiveData.postValue(Resource.success(it.orElse(null))) + mutableLiveData.postValue(State.success(it.orElse(null))) }, { - mutableLiveData.postValue(Resource.error(it)) + mutableLiveData.postValue(State.error(it)) } ) return mutableLiveData } -fun FlowableSubscribeProxy.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() +fun FlowableSubscribeProxy.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() subscribe( { - mutableLiveData.postValue(Resource.success(it)) + mutableLiveData.postValue(State.success(it)) }, { - mutableLiveData.postValue(Resource.error(it)) + mutableLiveData.postValue(State.error(it)) } ) return mutableLiveData } -fun FlowableSubscribeProxy>.optionalToResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() +fun FlowableSubscribeProxy>.optionalToResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() subscribe( { - mutableLiveData.postValue(Resource.success(it.orElse(null))) + mutableLiveData.postValue(State.success(it.orElse(null))) }, { - mutableLiveData.postValue(Resource.error(it)) + mutableLiveData.postValue(State.error(it)) } ) return mutableLiveData } -fun CompletableSubscribeProxy.toResourceLiveData(): LiveData> { - val mutableLiveData = MutableLiveData>() - mutableLiveData.value = Resource.loading() +fun CompletableSubscribeProxy.toResourceLiveData(): LiveData> { + val mutableLiveData = MutableLiveData>() + mutableLiveData.value = State.loading() subscribe( { - mutableLiveData.postValue(Resource.success()) + mutableLiveData.postValue(State.success()) }, { - mutableLiveData.postValue(Resource.error(it)) + mutableLiveData.postValue(State.error(it)) } ) return mutableLiveData diff --git a/lib_base/src/main/java/com/android/base/utils/common/Strings.kt b/lib_base/src/main/java/com/android/base/utils/common/Strings.kt index 35def2c..924a39e 100644 --- a/lib_base/src/main/java/com/android/base/utils/common/Strings.kt +++ b/lib_base/src/main/java/com/android/base/utils/common/Strings.kt @@ -4,117 +4,108 @@ package com.android.base.utils.common import java.util.regex.Pattern - private const val CHINA_PHONE_REG = "^1\\d{10}$" private const val ID_CARD_REG = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}" private const val EMAIL_REG = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*" -private const val DIGIT_REG = "\\-?[1-9]\\d+\"" +private const val DIGIT_REG = "-?[1-9]\\d+\"" private const val URL_REG = "(https?://(w{3}\\.)?)?\\w+\\.\\w+(\\.[a-zA-Z]+)*(:\\d{1,5})?(/\\w*)*(\\??(.+=.*)?(&.+=.*)?)?" private const val CHINESE_REGEX = "^[\u4E00-\u9FA5]+$" -private const val DECIMALS_REG = "\\-?[1-9]\\d+(\\.\\d+)?" -private const val LETTERS_REG = ".*[a-zA-Z]++.*" -private const val DIGITAL_REG = ".*[0-9]++.*" +private const val DECIMALS_REG = "-?[1-9]\\d+(\\.\\d+)?" private const val DIGITAL_LETTER_ONLY_REG = "^[A-Za-z0-9]+$" +private const val CONTAINS_DIGITAL_REG = ".*[0-9]+.*" +private const val CONTAINS_LETTERS_REG = ".*[a-zA-Z]+.*" +private const val CONTAINS_LOWERCASE_LETTERS_REG = "^.*[a-z]+.*$" +private const val CONTAINS_UPPERCASE_LETTERS_REG = "^.*[A-Z]+.*$" /** * 验证中国的手机号 * * @return 验证成功返回 true,验证失败返回 false */ -fun isChinaPhoneNumber(mobile: String): Boolean { +fun isChinaPhoneNumber(mobile: String?): Boolean { return !isEmpty(mobile) && Pattern.matches(CHINA_PHONE_REG, mobile) } -fun containsLetter(text: String): Boolean { - return !isEmpty(text) && Pattern.matches(LETTERS_REG, text) +/** + * 只包含 [1-9][a-z][A-Z] + */ +fun containsDigitalLetterOnly(text: String?): Boolean { + return !isEmpty(text) && Pattern.matches(DIGITAL_LETTER_ONLY_REG, text) } -fun containsDigital(text: String): Boolean { - return !isEmpty(text) && Pattern.matches(DIGITAL_REG, text) +/**是否包含字母*/ +fun containsLetter(text: String?): Boolean { + return !isEmpty(text) && Pattern.matches(CONTAINS_LETTERS_REG, text) } -fun containsDigtalLetterOnly(text: String): Boolean { - return !isEmpty(text) && Pattern.matches(DIGITAL_LETTER_ONLY_REG, text) +/** + * 是否包含小写字母 + */ +fun containsLowercaseLetter(text: String): Boolean { + return !isEmpty(text) && Pattern.matches(CONTAINS_LOWERCASE_LETTERS_REG, text) } /** - * 验证身份证号码 - * - * @param idCard 居民身份证号码15位或18位,最后一位可能是数字或字母 - * @return 验证成功返回true,验证失败返回false + * 是否包含大写字母 + */ +fun containsUppercaseLetter(text: String): Boolean { + return !isEmpty(text) && Pattern.matches(CONTAINS_UPPERCASE_LETTERS_REG, text) +} + +/** + * 是否包含数字 + */ +fun containsDigital(text: String?): Boolean { + return !isEmpty(text) && Pattern.matches(CONTAINS_DIGITAL_REG, text) +} + +/** + * 验证身份证号码,居民身份证号码15位或18位,最后一位可能是数字或字母。 */ -fun isIdCard(idCard: String): Boolean { +fun isIdCard(idCard: String?): Boolean { return !isEmpty(idCard) && Pattern.matches(ID_CARD_REG, idCard) } /** * 验证Email - * - * @param email email地址,格式:zhangsan@sina.com,zhangsan@xxx.com.cn,xxx代表邮件服务商 - * @return 验证成功返回true,验证失败返回false */ -fun isEmail(email: String): Boolean { +fun isEmail(email: String?): Boolean { return !isEmpty(email) && Pattern.matches(EMAIL_REG, email) } /** * 验证整数(正整数和负整数) - * - * @param digit 一位或多位0-9之间的整数 - * @return 验证成功返回true,验证失败返回false */ -fun isDigit(digit: String): Boolean { +fun isDigit(digit: String?): Boolean { return !isEmpty(digit) && Pattern.matches(DIGIT_REG, digit) } /** * 验证整数和浮点数(正负整数和正负浮点数) - * - * @param decimals 一位或多位0-9之间的浮点数,如:1.23,233.30 - * @return 验证成功返回true,验证失败返回false */ -fun isDecimals(decimals: String): Boolean { +fun isDecimals(decimals: String?): Boolean { return !isEmpty(decimals) && Pattern.matches(DECIMALS_REG, decimals) } /** - * 验证中文 - * - * @param chinese 中文字符 - * @return 验证成功返回true,验证失败返回false + * 是否为纯中文 */ -fun isChinese(chinese: String): Boolean { +fun isChinese(chinese: String?): Boolean { return !isEmpty(chinese) && Pattern.matches(CHINESE_REGEX, chinese) } /** * 验证URL地址 - * - * @param url url - * @return 验证成功返回true,验证失败返回false */ -fun isURL(url: String): Boolean { +fun isURL(url: String?): Boolean { return !isEmpty(url) && Pattern.matches(URL_REG, url) } -/** - * 获取字符串的字符个数 - */ -fun getCharLength(string: String): Int { - return if (isEmpty(string)) { - 0 - } else string.trim { it <= ' ' }.toCharArray().size -} - -fun isCharLength(string: String?, length: Int): Boolean { - return null != string && (isEmpty(string) && length == 0 || string.trim { it <= ' ' }.toCharArray().size == length) -} - fun isLengthIn(string: String?, min: Int, max: Int): Boolean { val length = string?.length ?: 0 return length in min..max } -fun isEmpty(str: CharSequence?): Boolean { - return str == null || str.toString().trim { it <= ' ' }.isEmpty() -} +fun isEmpty(str: String?): Boolean { + return str == null || str.isEmpty() +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt b/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt new file mode 100644 index 0000000..609842e --- /dev/null +++ b/lib_base/src/main/java/com/android/base/utils/security/security-utils.kt @@ -0,0 +1,12 @@ +package com.android.base.utils.security + +import android.annotation.SuppressLint + +fun md5(content: String): String { + return MD5Utils.md5(content) +} + +@SuppressLint("DefaultLocale") +fun md5UpperCase(content: String): String { + return MD5Utils.md5(content).toUpperCase() +} diff --git a/lib_base/src/main/res/values/base_attrs.xml b/lib_base/src/main/res/values/base_attrs.xml index 6990afd..6be0056 100644 --- a/lib_base/src/main/res/values/base_attrs.xml +++ b/lib_base/src/main/res/values/base_attrs.xml @@ -72,7 +72,7 @@ - + diff --git a/lib_qrcode/build.gradle b/lib_qrcode/build.gradle index e386156..e70a80c 100644 --- a/lib_qrcode/build.gradle +++ b/lib_qrcode/build.gradle @@ -34,7 +34,6 @@ android { dependencies { implementation 'com.google.zxing:core:3.3.3' - api fileTree(dir: 'libs', include: ['*.jar', '*.aar']) implementation uiLibraries.fotoapparat implementation kotlinLibraries.kotlinStdlib } \ No newline at end of file