refactor some class

androidx
Ztiany 5 years ago
parent 260f6a8de5
commit 7095135a4d
  1. 53
      lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt
  2. 239
      lib_base/src/main/java/com/android/base/app/aac/ResourceLiveData.kt
  3. 2
      lib_base/src/main/java/com/android/base/app/activity/BaseActivity.kt
  4. 2
      lib_base/src/main/java/com/android/base/app/fragment/BaseDialogFragment.kt
  5. 2
      lib_base/src/main/java/com/android/base/app/fragment/BaseFragment.kt
  6. 2
      lib_base/src/main/java/com/android/base/app/mvp/RxPresenter.kt
  7. 2
      lib_base/src/main/java/com/android/base/app/mvvm/RxViewModel.kt
  8. 42
      lib_base/src/main/java/com/android/base/app/ui/RefreshStateLayoutEx.kt
  9. 39
      lib_base/src/main/java/com/android/base/app/ui/UIKit.kt
  10. 172
      lib_base/src/main/java/com/android/base/data/Resource.kt
  11. 203
      lib_base/src/main/java/com/android/base/data/State.kt
  12. 15
      lib_base/src/main/java/com/android/base/data/Status.kt
  13. 207
      lib_base/src/main/java/com/android/base/rx/RxLiveStateEx.kt
  14. 40
      lib_base/src/main/java/com/android/base/rx/RxLivedata.kt
  15. 5
      lib_base/src/main/java/com/android/base/rx/autodispose/RxKitForAutoDispose.kt
  16. 135
      lib_base/src/main/java/com/android/base/rx/autodispose/RxLiveStateExForAutodDispose.kt
  17. 99
      lib_base/src/main/java/com/android/base/utils/common/Strings.kt
  18. 12
      lib_base/src/main/java/com/android/base/utils/security/security-utils.kt
  19. 2
      lib_base/src/main/res/values/base_attrs.xml
  20. 1
      lib_qrcode/build.gradle

@ -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, T> H.handleLiveResource(
liveData: LiveData<Resource<T>>,
fun <H, T> H.handleLiveState(
liveData: LiveData<State<T>>,
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, T> H.handleLiveResourceWithData(
liveData: LiveData<Resource<T>>,
fun <H, T> H.handleLiveStateWithData(
liveData: LiveData<State<T>>,
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
}
})

@ -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 <T> Observable<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(it))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T, R> Observable<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T) -> R) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(map(it)))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T> Observable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(it.orElse(null)))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T, R> Observable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<R>>, 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 <T> Flowable<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(it))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T, R> Flowable<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T) -> R) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(map(it)))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T> Flowable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(it.orElse(null)))
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T, R> Flowable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<R>>, 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<Resource<Any>>) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success())
},
{
liveData.postValue(Resource.error(it))
}
)
}
fun <T> Completable.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>, provider: () -> T) {
liveData.postValue(Resource.loading())
this.subscribe(
{
liveData.postValue(Resource.success(provider()))
},
{
liveData.postValue(Resource.error(it))
}
)
}
//-----------------------------------------------------------------------------------------
fun <T> Observable<T>.toResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
subscribe(
{
mutableLiveData.postValue(Resource.success(it))
},
{
mutableLiveData.postValue(Resource.error(it))
}
)
return mutableLiveData
}
fun <T> Observable<Optional<T>>.optionalToResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
subscribe(
{
mutableLiveData.postValue(Resource.success(it.orElse(null)))
},
{
mutableLiveData.postValue(Resource.error(it))
}
)
return mutableLiveData
}
fun <T> Flowable<T>.toResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
subscribe(
{
mutableLiveData.postValue(Resource.success(it))
},
{
mutableLiveData.postValue(Resource.error(it))
}
)
return mutableLiveData
}
fun <T> Flowable<Optional<T>>.optionalToResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
subscribe(
{
mutableLiveData.postValue(Resource.success(it.orElse(null)))
},
{
mutableLiveData.postValue(Resource.error(it))
}
)
return mutableLiveData
}
fun Completable.toResourceLiveData(): LiveData<Resource<Any>> {
val mutableLiveData = MutableLiveData<Resource<Any>>()
mutableLiveData.value = Resource.loading()
subscribe(
{
mutableLiveData.postValue(Resource.success())
},
{
mutableLiveData.postValue(Resource.error(it))
}
)
return mutableLiveData
}
//-----------------------------------------------------------------------------------------
fun <T> Observable<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Flowable<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Single<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Maybe<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}

@ -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

@ -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

@ -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

@ -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

@ -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

@ -1,42 +0,0 @@
package com.android.base.app.ui
import com.android.base.app.Sword
import timber.log.Timber
fun <T> 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()
}
}

@ -124,3 +124,42 @@ fun RefreshListLayout<*>.showLoadingIfEmpty() {
}
}
}
fun <T> 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()
}
}

@ -1,172 +0,0 @@
package com.android.base.data
/**
* @author Ztiany
* Email: ztiany3@gmail.com
* Date : 2018-05-15 16:23
*/
class Resource<T> 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 <T> success(): Resource<T> {
return Resource(null, null, Status.SUCCESS)
}
fun <T> success(data: T?): Resource<T> {
return Resource(null, data, Status.SUCCESS)
}
fun <T> error(error: Throwable): Resource<T> {
return error(error, null)
}
/**
* 创建一个 error 状态且设置一个默认的数据
*/
fun <T> error(error: Throwable, defaultValue: T?): Resource<T> {
return Resource(error, defaultValue, Status.ERROR)
}
fun <T> loading(): Resource<T> {
return loading(null)
}
/**
* 创建一个 loading 状态且设置一个默认的数据
*/
fun <T> loading(defaultValue: T?): Resource<T> {
return Resource(null, defaultValue, Status.LOADING)
}
/**
* 如果数据源(比如 Repository)缓存了上一次请求的数据然后对其当前请求返回的数据发现数据是一样的可以使用此状态表示
*
* @return Resource
*/
fun <T> noChange(): Resource<T> {
return Resource(null, null, Status.NOT_CHANGED)
}
}
}
/**when in loading*/
inline fun <T> Resource<T>.onLoading(onLoading: () -> Unit): Resource<T> {
if (this.isLoading) {
onLoading()
}
return this
}
/**when error occurred*/
inline fun <T> Resource<T>.onError(onError: (error: Throwable) -> Unit): Resource<T> {
if (this.isError) {
onError(error())
}
return this
}
/**when no change*/
inline fun <T> Resource<T>.onNoChange(onNoChange: () -> Unit): Resource<T> {
if (this.isNoChange) {
onNoChange()
}
return this
}
/**when succeeded*/
inline fun <T> Resource<T>.onSuccess(onSuccess: (data: T?) -> Unit): Resource<T> {
if (this.isSuccess) {
onSuccess(this.orElse(null))
}
return this
}
/**when succeeded and has data*/
inline fun <T> Resource<T>.onSuccessWithData(onSuccess: (data: T) -> Unit): Resource<T> {
val t = this.get()
if (this.isSuccess && t != null) {
onSuccess(t)
}
return this
}

@ -0,0 +1,203 @@
package com.android.base.data
/**
* @author Ztiany
* Email: ztiany3@gmail.com
* Date : 2018-05-15 16:23
*/
class State<T> 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 <T> success(): State<T> {
return State(null, null, SUCCESS)
}
fun <T> success(data: T?): State<T> {
return State(null, data, SUCCESS)
}
fun <T> error(error: Throwable): State<T> {
return error(error, null)
}
/**
* 创建一个 error 状态且设置一个默认的数据
*/
fun <T> error(error: Throwable, defaultValue: T?): State<T> {
return State(error, defaultValue, ERROR)
}
fun <T> loading(): State<T> {
return loading(null)
}
/**
* 创建一个 loading 状态且设置一个默认的数据
*/
fun <T> loading(defaultValue: T?): State<T> {
return State(null, defaultValue, LOADING)
}
/**
* 如果数据源(比如 Repository)缓存了上一次请求的数据然后对其当前请求返回的数据发现数据是一样的可以使用此状态表示
*
* @return State
*/
fun <T> noChange(): State<T> {
return State(null, null, NOT_CHANGED)
}
}
}
class StateHandler<T> {
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 <T> State<T>.handleState(handler: StateHandler<T>.() -> Unit) {
val stateHandler = StateHandler<T>()
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 <T> State<T>.onLoading(onLoading: () -> Unit): State<T> {
if (this.isLoading) {
onLoading()
}
return this
}
/**when error occurred*/
inline fun <T> State<T>.onError(onError: (error: Throwable) -> Unit): State<T> {
if (this.isError) {
onError(error())
}
return this
}
/**when no change*/
inline fun <T> State<T>.onNoChange(onNoChange: () -> Unit): State<T> {
if (this.isNoChange) {
onNoChange()
}
return this
}
/**when succeeded*/
inline fun <T> State<T>.onSuccess(onSuccess: (data: T?) -> Unit): State<T> {
if (this.isSuccess) {
onSuccess(this.orElse(null))
}
return this
}
/**when succeeded and has data*/
inline fun <T> State<T>.onSuccessWithData(onSuccess: (data: T) -> Unit): State<T> {
val t = this.get()
if (this.isSuccess && t != null) {
onSuccess(t)
}
return this
}

@ -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
}

@ -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 <T> Observable<T>.subscribeWithLiveData(liveData: MutableLiveData<State<T>>) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(it))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T, R> Observable<T>.subscribeWithLiveData(liveData: MutableLiveData<State<R>>, map: (T) -> R) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(map(it)))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T> Observable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<T>>) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(it.orElse(null)))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T, R> Observable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<R>>, 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 <T> Flowable<T>.subscribeWithLiveData(liveData: MutableLiveData<State<T>>) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(it))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T, R> Flowable<T>.subscribeWithLiveData(liveData: MutableLiveData<State<R>>, map: (T) -> R) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(map(it)))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T> Flowable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<T>>) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(it.orElse(null)))
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T, R> Flowable<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<R>>, 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<State<Any>>) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success())
},
{
liveData.postValue(State.error(it))
}
)
}
fun <T> Completable.subscribeWithLiveData(liveData: MutableLiveData<State<T>>, provider: () -> T) {
liveData.postValue(State.loading())
this.subscribe(
{
liveData.postValue(State.success(provider()))
},
{
liveData.postValue(State.error(it))
}
)
}
//-----------------------------------------------------------------------------------------
fun <T> Observable<T>.toResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
mutableLiveData.value = State.loading()
subscribe(
{
mutableLiveData.postValue(State.success(it))
},
{
mutableLiveData.postValue(State.error(it))
}
)
return mutableLiveData
}
fun <T> Observable<Optional<T>>.optionalToResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
mutableLiveData.value = State.loading()
subscribe(
{
mutableLiveData.postValue(State.success(it.orElse(null)))
},
{
mutableLiveData.postValue(State.error(it))
}
)
return mutableLiveData
}
fun <T> Flowable<T>.toResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
mutableLiveData.value = State.loading()
subscribe(
{
mutableLiveData.postValue(State.success(it))
},
{
mutableLiveData.postValue(State.error(it))
}
)
return mutableLiveData
}
fun <T> Flowable<Optional<T>>.optionalToResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
mutableLiveData.value = State.loading()
subscribe(
{
mutableLiveData.postValue(State.success(it.orElse(null)))
},
{
mutableLiveData.postValue(State.error(it))
}
)
return mutableLiveData
}
fun Completable.toResourceLiveData(): LiveData<State<Any>> {
val mutableLiveData = MutableLiveData<State<Any>>()
mutableLiveData.value = State.loading()
subscribe(
{
mutableLiveData.postValue(State.success())
},
{
mutableLiveData.postValue(State.error(it))
}
)
return mutableLiveData
}
//-----------------------------------------------------------------------------------------

@ -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 <T> Observable<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Flowable<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Single<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}
fun <T> Maybe<T>.toLiveData(): LiveData<T> {
val liveData = MutableLiveData<T>()
this.subscribeIgnoreError {
liveData.postValue(it)
}
return liveData
}

@ -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<T> : LifecycleScopeProvider<T> {

@ -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 <T> ObservableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
fun <T> ObservableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<State<T>>) {
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 <T, R> ObservableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T) -> R) {
liveData.postValue(Resource.loading())
fun <T, R> ObservableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<State<R>>, 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 <T> ObservableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
fun <T> ObservableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<T>>) {
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 <T, R> ObservableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T?) -> R?) {
liveData.postValue(Resource.loading())
fun <T, R> ObservableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<R>>, 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 <T> FlowableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
fun <T> FlowableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<State<T>>) {
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 <T, R> FlowableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T) -> R) {
liveData.postValue(Resource.loading())
fun <T, R> FlowableSubscribeProxy<T>.subscribeWithLiveData(liveData: MutableLiveData<State<R>>, 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 <T> FlowableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<T>>) {
liveData.postValue(Resource.loading())
fun <T> FlowableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<T>>) {
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 <T, R> FlowableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<Resource<R>>, map: (T?) -> R?) {
liveData.postValue(Resource.loading())
fun <T, R> FlowableSubscribeProxy<Optional<T>>.subscribeOptionalWithLiveData(liveData: MutableLiveData<State<R>>, 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<Resource<Any>>) {
liveData.postValue(Resource.loading())
fun CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData<State<Any>>) {
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 <T> CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData<Resource<T>>, provider: () -> T) {
liveData.postValue(Resource.loading())
fun <T> CompletableSubscribeProxy.subscribeWithLiveData(liveData: MutableLiveData<State<T>>, 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 <T> ObservableSubscribeProxy<T>.toResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
fun <T> ObservableSubscribeProxy<T>.toResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
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 <T> ObservableSubscribeProxy<Optional<T>>.optionalToResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
fun <T> ObservableSubscribeProxy<Optional<T>>.optionalToResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
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 <T> FlowableSubscribeProxy<T>.toResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
fun <T> FlowableSubscribeProxy<T>.toResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
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 <T> FlowableSubscribeProxy<Optional<T>>.optionalToResourceLiveData(): LiveData<Resource<T>> {
val mutableLiveData = MutableLiveData<Resource<T>>()
mutableLiveData.value = Resource.loading()
fun <T> FlowableSubscribeProxy<Optional<T>>.optionalToResourceLiveData(): LiveData<State<T>> {
val mutableLiveData = MutableLiveData<State<T>>()
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<Resource<Any>> {
val mutableLiveData = MutableLiveData<Resource<Any>>()
mutableLiveData.value = Resource.loading()
fun CompletableSubscribeProxy.toResourceLiveData(): LiveData<State<Any>> {
val mutableLiveData = MutableLiveData<State<Any>>()
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

@ -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.comzhangsan@xxx.com.cnxxx代表邮件服务商
* @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.23233.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()
}

@ -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()
}

@ -72,7 +72,7 @@
<attr name="srl_target_id" format="reference"/>
<!-- a array of colors -->
<attr name="srl_color_scheme" format="reference"/>
<!--restore refresh status-->
<!--restore refresh state-->
<attr name="srl_restore_refresh_status" format="boolean"/>
</declare-styleable>

@ -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
}
Loading…
Cancel
Save