feat: 添加 ViewModel、View 扩展方法,调整部分代码注释和结构

This commit is contained in:
Quyunshuo
2022-05-18 22:48:13 +08:00
parent 086078f618
commit 80896bff0e
4 changed files with 66 additions and 63 deletions

View File

@ -26,5 +26,5 @@ inline fun <T> LifecycleOwner.observeLiveData(
liveData: LiveData<T>, liveData: LiveData<T>,
crossinline action: (t: T) -> Unit crossinline action: (t: T) -> Unit
) { ) {
liveData.observe(this, { it?.let { t -> action(t) } }) liveData.observe(this) { it?.let { t -> action(t) } }
} }

View File

@ -3,13 +3,8 @@ package com.quyunshuo.androidbaseframemvvm.base.ktx
import android.animation.Animator import android.animation.Animator
import android.animation.IntEvaluator import android.animation.IntEvaluator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.os.Build
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.quyunshuo.androidbaseframemvvm.base.ktx.ViewClickDelay.SPACE_TIME
import com.quyunshuo.androidbaseframemvvm.base.ktx.ViewClickDelay.hash
import com.quyunshuo.androidbaseframemvvm.base.ktx.ViewClickDelay.lastClickTime
/** /**
* @Author: QuYunShuo * @Author: QuYunShuo
@ -21,6 +16,7 @@ import com.quyunshuo.androidbaseframemvvm.base.ktx.ViewClickDelay.lastClickTime
/*************************************** View可见性相关 ********************************************/ /*************************************** View可见性相关 ********************************************/
/** /**
* 隐藏View * 隐藏View
* @receiver View
*/ */
fun View.gone() { fun View.gone() {
visibility = View.GONE visibility = View.GONE
@ -36,38 +32,40 @@ fun View.visible() {
/** /**
* View不可见但存在原位置 * View不可见但存在原位置
* @receiver View
*/ */
fun View.invisible() { fun View.invisible() {
visibility = View.INVISIBLE visibility = View.INVISIBLE
} }
/** /**
* 判断View是不是[View.VISIBLE]状态 * 设置 View[View.VISIBLE]
* 如果 [isVisible] 值为true将 [View.setVisibility] 设置为 [View.VISIBLE],反之为 [View.GONE]
*
* @receiver View
* @param isVisible Boolean 是否显示
*/ */
val View.isVisible: Boolean fun View.setVisible(isVisible: Boolean) {
get() { if (isVisible) visible() else gone()
return visibility == View.VISIBLE }
}
/** /**
* 判断View是不是[View.INVISIBLE]状态 * 设置 View[View.GONE]
* 如果 [isGone] 值为true将 [View.setVisibility] 设置为 [View.GONE],反之为 [View.VISIBLE]
*
* @receiver View
* @param isGone Boolean 是否隐藏
*/ */
val View.isInvisible: Boolean fun View.setGone(isGone: Boolean) {
get() { if (isGone) visible() else gone()
return visibility == View.INVISIBLE }
}
/**
* 判断View是不是[View.GONE]状态
*/
val View.isGone: Boolean
get() {
return visibility == View.GONE
}
/*************************************** View宽高相关 ********************************************/ /*************************************** View宽高相关 ********************************************/
/** /**
* 设置View的高度 * 设置 View 的高度
* @receiver View
* @param height Int 目标高度
* @return View
*/ */
fun View.height(height: Int): View { fun View.height(height: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams( val params = layoutParams ?: ViewGroup.LayoutParams(
@ -81,6 +79,9 @@ fun View.height(height: Int): View {
/** /**
* 设置View的宽度 * 设置View的宽度
* @receiver View
* @param width Int 目标宽度
* @return View
*/ */
fun View.width(width: Int): View { fun View.width(width: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams( val params = layoutParams ?: ViewGroup.LayoutParams(
@ -94,8 +95,10 @@ fun View.width(width: Int): View {
/** /**
* 设置View的宽度和高度 * 设置View的宽度和高度
* @param width 要设置的宽度 * @receiver View
* @param height 要设置的 * @param width Int 要设置的
* @param height Int 要设置的高度
* @return View
*/ */
fun View.widthAndHeight(width: Int, height: Int): View { fun View.widthAndHeight(width: Int, height: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams( val params = layoutParams ?: ViewGroup.LayoutParams(
@ -199,44 +202,12 @@ fun View.animateWidthAndHeight(
/*************************************** View其他 ********************************************/ /*************************************** View其他 ********************************************/
/** /**
* 获取View id如果没有idSDK>17, 使用[View.generateViewId];否则使用[View.hashCode] * 获取View id
*/ */
@SuppressLint("ObsoleteSdkInt")
fun View.getViewId(): Int { fun View.getViewId(): Int {
var id = id var id = id
if (id == View.NO_ID) { if (id == View.NO_ID) {
id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { id = View.generateViewId()
View.generateViewId()
} else {
this.hashCode()
}
} }
return id return id
}
object ViewClickDelay {
var hash: Int = 0
var lastClickTime: Long = 0
var SPACE_TIME: Long = 2000 // 间隔时间
}
/**
* 防快速点击
* @receiver View
* @param clickAction 要响应的操作
*/
infix fun View.clickDelay(clickAction: () -> Unit) {
this.setOnClickListener {
if (this.hashCode() != hash) {
hash = this.hashCode()
lastClickTime = System.currentTimeMillis()
clickAction()
} else {
val currentTime = System.currentTimeMillis()
if (currentTime - lastClickTime > SPACE_TIME) {
lastClickTime = System.currentTimeMillis()
clickAction()
}
}
}
} }

View File

@ -18,4 +18,36 @@ fun ViewModel.launchIO(
throwable.printStackTrace() throwable.printStackTrace()
}, },
block: suspend CoroutineScope.() -> Unit block: suspend CoroutineScope.() -> Unit
): Job = viewModelScope.launch(Dispatchers.IO + exceptionHandler, block = block) ): Job = viewModelScope.launch(Dispatchers.IO + exceptionHandler, block = block)
/**
* 开启一个线程调度模式为[Dispatchers.Default]的协程 有默认的异常处理器
*
* @receiver ViewModel
*
* @param exceptionHandler CoroutineExceptionHandler 异常处理器
* @param block suspend CoroutineScope.() -> Unit 协程体
* @return Job
*/
fun ViewModel.launchDefault(
exceptionHandler: CoroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
throwable.printStackTrace()
},
block: suspend CoroutineScope.() -> Unit
): Job = viewModelScope.launch(Dispatchers.Default + exceptionHandler, block = block)
/**
* 开启一个线程调度模式为[Dispatchers.Main]的协程 有默认的异常处理器
*
* @receiver ViewModel
*
* @param exceptionHandler CoroutineExceptionHandler 异常处理器
* @param block suspend CoroutineScope.() -> Unit 协程体
* @return Job
*/
fun ViewModel.launchMain(
exceptionHandler: CoroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
throwable.printStackTrace()
},
block: suspend CoroutineScope.() -> Unit
): Job = viewModelScope.launch(Dispatchers.Main + exceptionHandler, block = block)

View File

@ -19,7 +19,7 @@ open class BaseRepository {
* 该方法将flow的执行切换至IO线程 * 该方法将flow的执行切换至IO线程
* *
* @param requestBlock 请求的整体逻辑 * @param requestBlock 请求的整体逻辑
* @return Flow<T> * @return Flow<T> @BuilderInference block: suspend FlowCollector<T>.() -> Unit
*/ */
protected fun <T> request(requestBlock: suspend FlowCollector<T>.() -> Unit): Flow<T> { protected fun <T> request(requestBlock: suspend FlowCollector<T>.() -> Unit): Flow<T> {
return flow(block = requestBlock).flowOn(Dispatchers.IO) return flow(block = requestBlock).flowOn(Dispatchers.IO)