diff --git a/lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt b/lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt deleted file mode 100644 index 3965229..0000000 --- a/lib_base/src/main/java/com/android/base/app/aac/LiveStateHandler.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.android.base.app.aac - -import androidx.lifecycle.LifecycleOwner -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.State -import timber.log.Timber - - -interface LiveStateHandler { - - /**处理异常*/ - fun handleError(throwable: Throwable) - -} - -fun H.handleLiveState( - liveData: LiveData>, - forceLoading: Boolean = true, - onSuccess: (T?) -> Unit -) where H : LiveStateHandler, H : LoadingView, H : LifecycleOwner { - - liveData.observe(this, Observer { - when { - it.isError -> { - Timber.d("handleLiveState -> isError") - dismissLoadingDialog() - handleError(it.error()) - } - it.isLoading -> { - Timber.d("handleLiveState -> isLoading") - showLoadingDialog(!forceLoading) - } - it.isSuccess -> { - Timber.d("handleLiveState -> isSuccess") - val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - - dismissLoadingDialog(minimumShowingDialogMills) { - onSuccess(it.get()) - } - }//success end - } - }) - -} - -fun H.handleLiveStateWithData( - liveData: LiveData>, - forceLoading: Boolean = true, - onEmpty: (() -> Unit)? = null, - onSuccess: (T) -> Unit -) where H : LiveStateHandler, H : LoadingView, H : LifecycleOwner { - - liveData.observe(this, Observer { - when { - it.isError -> { - Timber.d("handleLiveStateWithData -> isError") - dismissLoadingDialog() - handleError(it.error()) - } - it.isLoading -> { - Timber.d("handleLiveStateWithData -> isLoading") - showLoadingDialog(!forceLoading) - } - it.isSuccess -> { - Timber.d("handleLiveStateWithData -> isSuccess") - val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() - dismissLoadingDialog(minimumShowingDialogMills) { - if (it.hasData()) { - onSuccess(it.data()) - } else { - onEmpty?.invoke() - } - } - }//success end - } - }) - -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/ui/LiveStateHandler.kt b/lib_base/src/main/java/com/android/base/app/ui/LiveStateHandler.kt new file mode 100644 index 0000000..53a0d58 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/app/ui/LiveStateHandler.kt @@ -0,0 +1,11 @@ +package com.android.base.app.ui + +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer +import com.android.base.app.Sword +import com.android.base.data.State +import timber.log.Timber + + + diff --git a/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt index 268e9a3..cda64a9 100644 --- a/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt +++ b/lib_base/src/main/java/com/android/base/app/ui/UIKit.kt @@ -2,11 +2,89 @@ package com.android.base.app.ui +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer import com.android.base.app.Sword +import com.android.base.data.State +import com.android.base.data.StateHandler import com.android.base.utils.common.isEmpty import timber.log.Timber -fun RefreshListLayout.handleListResultWithStatus(list: List?, onEmpty: (() -> Unit)? = null) { +//----------------------------------------------Common->Loading->Dialog ---------------------------------------------- +interface UIErrorHandler { + /**处理异常*/ + fun handleError(throwable: Throwable) + + /**异常描述*/ + fun generateErrorMessage(throwable: Throwable) +} + +fun H.handleLiveState( + liveData: LiveData>, + forceLoading: Boolean = true, + onSuccess: (T?) -> Unit +) where H : UIErrorHandler, H : LoadingView, H : LifecycleOwner { + + liveData.observe(this, Observer { state -> + when { + state.isError -> { + Timber.d("handleLiveState -> isError") + dismissLoadingDialog() + handleError(state.error()) + } + state.isLoading -> { + Timber.d("handleLiveState -> isLoading") + showLoadingDialog(!forceLoading) + } + state.isSuccess -> { + Timber.d("handleLiveState -> isSuccess") + val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() + dismissLoadingDialog(minimumShowingDialogMills) { + onSuccess(state.get()) + } + }//success end + } + }) + +} + +fun LoadingView.handleState( + state: State, + forceLoading: Boolean = true, + handler: StateHandler.() -> Unit +) { + + val stateHandler = StateHandler() + handler(stateHandler) + + when { + state.isError -> { + Timber.d("handleState -> isError") + dismissLoadingDialog() + stateHandler.onError?.invoke(state.error()) + } + state.isLoading -> { + Timber.d("handleState -> isLoading") + showLoadingDialog(!forceLoading) + } + state.isSuccess -> { + Timber.d("handleState -> isSuccess") + val minimumShowingDialogMills = Sword.get().minimumShowingDialogMills() + dismissLoadingDialog(minimumShowingDialogMills) { + stateHandler.onSuccess?.invoke(state.get()) + if (state.hasData()) { + stateHandler.onSuccessWithData?.invoke(state.data()) + } else { + stateHandler.onEmpty?.invoke() + } + } + }//success end + } +} + +//----------------------------------------------Loading In List---------------------------------------------- +fun RefreshListLayout.handleListResult(list: List?, onEmpty: (() -> Unit)? = null) { if (isLoadingMore) { if (!isEmpty(list)) { addData(list) @@ -31,27 +109,30 @@ fun RefreshListLayout.handleListResultWithStatus(list: List?, onEmpty: } } -fun RefreshListLayout.handleListResultWithoutStatus(list: List?, onEmpty: (() -> Unit)? = null) { - if (isLoadingMore) { - if (!isEmpty(list)) { - addData(list) - } - } else { - replaceData(list) +fun RefreshListLayout<*>.handleListError(throwable: Throwable) { + if (isRefreshing) { refreshCompleted() } - - if (pager != null) { - loadMoreCompleted(list != null && pager.hasMore(list.size)) + if (isLoadingMore) { + loadMoreFailed() } - - if (onEmpty != null && isEmpty) { - onEmpty() + if (isEmpty) { + val errorTypeClassifier = Sword.get().errorClassifier() + if (errorTypeClassifier != null) { + when { + errorTypeClassifier.isNetworkError(throwable) -> showNetErrorLayout() + errorTypeClassifier.isServerError(throwable) -> showServerErrorLayout() + else -> showErrorLayout() + } + } else { + showErrorLayout() + } + } else { + showContentLayout() } - } -fun RefreshListLayout.submitListResultWithStatus(list: List?, hasMore: Boolean, onEmpty: (() -> Unit)? = null) { +fun RefreshListLayout.submitListResult(list: List?, hasMore: Boolean, onEmpty: (() -> Unit)? = null) { if (isRefreshing) { refreshCompleted() } @@ -70,75 +151,119 @@ fun RefreshListLayout.submitListResultWithStatus(list: List?, hasMore: } } -fun RefreshListLayout.submitListResultWithoutStatus(list: List?, hasMore: Boolean, onEmpty: (() -> Unit)? = null) { - if (isRefreshing) { +fun RefreshListLayout.handleStateList(state: State>, onEmpty: (() -> Unit)? = null) { + when { + state.isLoading -> { + showLoadingIfEmpty() + } + state.isError -> { + handleListError(state.error()) + } + state.isSuccess -> { + handleListResult(state.get(), onEmpty) + } + } +} + +fun RefreshListLayout.handleStateFullList(state: State>, hasMore: Boolean, onEmpty: (() -> Unit)? = null) { + when { + state.isLoading -> { + showLoadingIfEmpty() + } + state.isError -> { + handleListError(state.error()) + } + state.isSuccess -> { + submitListResult(state.get(), hasMore, onEmpty) + } + } +} + +fun RefreshListLayout<*>.showLoadingIfEmpty() { + if (isEmpty) { + if (isRefreshing) { + showBlank() + } else { + showLoadingLayout() + } + } +} + +//----------------------------------------------Loading In List And Without State---------------------------------------------- +fun RefreshListLayout.handleListResultWithoutState(list: List?, onEmpty: (() -> Unit)? = null) { + if (isLoadingMore) { + if (!isEmpty(list)) { + addData(list) + } + } else { + replaceData(list) refreshCompleted() } - replaceData(list) - loadMoreCompleted(hasMore) + if (pager != null) { + loadMoreCompleted(list != null && pager.hasMore(list.size)) + } if (onEmpty != null && isEmpty) { onEmpty() } + } -fun RefreshListLayout<*>.handleListErrorWithStatus(throwable: Throwable) { +fun RefreshListLayout<*>.handleListErrorWithoutState() { if (isRefreshing) { refreshCompleted() } if (isLoadingMore) { loadMoreFailed() } - if (isEmpty) { - val errorTypeClassifier = Sword.get().errorClassifier() - if (errorTypeClassifier != null) { - when { - errorTypeClassifier.isNetworkError(throwable) -> showNetErrorLayout() - errorTypeClassifier.isServerError(throwable) -> showServerErrorLayout() - else -> showErrorLayout() - } - } else { - showErrorLayout() - } - } else { - showContentLayout() - } } -fun RefreshListLayout<*>.handleListErrorWithoutStatus() { +fun RefreshListLayout.submitListResultWithoutState(list: List?, hasMore: Boolean, onEmpty: (() -> Unit)? = null) { if (isRefreshing) { refreshCompleted() } - if (isLoadingMore) { - loadMoreFailed() + + replaceData(list) + loadMoreCompleted(hasMore) + + if (onEmpty != null && isEmpty) { + onEmpty() } } -fun RefreshListLayout<*>.showLoadingIfEmpty() { - if (isEmpty) { - if (isRefreshing) { - showBlank() - } else { +//----------------------------------------------Loading In StateView---------------------------------------------- +fun RefreshStateLayout.handleStateResult(state: State, onEmpty: (() -> Unit)? = null, onResult: ((T) -> Unit)) { + when { + state.isLoading -> { showLoadingLayout() } + state.isError -> { + handleResultError(state.error()) + } + state.isSuccess -> { + handleResult(state.get(), onEmpty, onResult) + } } } - -fun RefreshStateLayout.handleResultWithStatus(t: T?, onResult: ((T) -> Unit)) { +fun RefreshStateLayout.handleResult(t: T?, onEmpty: (() -> Unit)? = null, onResult: ((T) -> Unit)) { if (isRefreshing) { refreshCompleted() } if (t == null || (t is Collection<*> && t.isEmpty()) || (t is Map<*, *> && t.isEmpty())) { - showEmptyLayout() + if (onEmpty != null) { + onEmpty() + } else { + showEmptyLayout() + } } else { onResult.invoke(t) showContentLayout() } } -fun RefreshStateLayout.handleErrorWithStatus(throwable: Throwable) { +fun RefreshStateLayout.handleResultError(throwable: Throwable) { if (isRefreshing) { refreshCompleted() } diff --git a/lib_base/src/main/java/com/android/base/utils/android/SoftKeyboardUtils.java b/lib_base/src/main/java/com/android/base/utils/android/SoftKeyboardUtils.java index 5eaebc2..720aced 100644 --- a/lib_base/src/main/java/com/android/base/utils/android/SoftKeyboardUtils.java +++ b/lib_base/src/main/java/com/android/base/utils/android/SoftKeyboardUtils.java @@ -42,7 +42,7 @@ public class SoftKeyboardUtils { } public static boolean hideSoftInput(Activity activity) { - if (activity.getCurrentFocus() != null) { + if (activity != null && activity.getCurrentFocus() != null) { InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); return imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); } @@ -53,7 +53,7 @@ public class SoftKeyboardUtils { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); return imm.isActive(); } - + @SuppressWarnings("all") public static void showErrorImmediately(String error, TextView editText) { editText.setError(error); diff --git a/lib_base/src/main/java/com/android/base/widget/pulltozoom/PullToZoomScrollView.java b/lib_base/src/main/java/com/android/base/widget/pulltozoom/PullToZoomScrollView.java index acbd0c3..7f50a42 100644 --- a/lib_base/src/main/java/com/android/base/widget/pulltozoom/PullToZoomScrollView.java +++ b/lib_base/src/main/java/com/android/base/widget/pulltozoom/PullToZoomScrollView.java @@ -229,8 +229,10 @@ public class PullToZoomScrollView extends NestedScrollView { mZoomView.setPivotY(mOriginContainerViewHeight / 3F); float addOffset = (height - mOriginContainerViewHeight) * mZoomFactory / mOriginContainerViewHeight; float scale = height * 1.0F / mOriginContainerViewHeight + addOffset; - mZoomView.setScaleX(scale); - mZoomView.setScaleY(scale); + if (!Float.isInfinite(scale)) { + mZoomView.setScaleX(scale); + mZoomView.setScaleY(scale); + } } private void getInnerViewHeight() {