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>,
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.IntEvaluator
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.os.Build
import android.view.View
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
@ -21,6 +16,7 @@ import com.quyunshuo.androidbaseframemvvm.base.ktx.ViewClickDelay.lastClickTime
/*************************************** View可见性相关 ********************************************/
/**
* 隐藏View
* @receiver View
*/
fun View.gone() {
visibility = View.GONE
@ -36,38 +32,40 @@ fun View.visible() {
/**
* View不可见但存在原位置
* @receiver View
*/
fun 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
get() {
return visibility == View.VISIBLE
}
fun View.setVisible(isVisible: Boolean) {
if (isVisible) visible() else gone()
}
/**
* 判断View是不是[View.INVISIBLE]状态
* 设置 View[View.GONE]
* 如果 [isGone] 值为true将 [View.setVisibility] 设置为 [View.GONE],反之为 [View.VISIBLE]
*
* @receiver View
* @param isGone Boolean 是否隐藏
*/
val View.isInvisible: Boolean
get() {
return visibility == View.INVISIBLE
}
/**
* 判断View是不是[View.GONE]状态
*/
val View.isGone: Boolean
get() {
return visibility == View.GONE
}
fun View.setGone(isGone: Boolean) {
if (isGone) visible() else gone()
}
/*************************************** View宽高相关 ********************************************/
/**
* 设置View的高度
* 设置 View 的高度
* @receiver View
* @param height Int 目标高度
* @return View
*/
fun View.height(height: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams(
@ -81,6 +79,9 @@ fun View.height(height: Int): View {
/**
* 设置View的宽度
* @receiver View
* @param width Int 目标宽度
* @return View
*/
fun View.width(width: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams(
@ -94,8 +95,10 @@ fun View.width(width: Int): View {
/**
* 设置View的宽度和高度
* @param width 要设置的宽度
* @param height 要设置的
* @receiver View
* @param width Int 要设置的
* @param height Int 要设置的高度
* @return View
*/
fun View.widthAndHeight(width: Int, height: Int): View {
val params = layoutParams ?: ViewGroup.LayoutParams(
@ -199,44 +202,12 @@ fun View.animateWidthAndHeight(
/*************************************** View其他 ********************************************/
/**
* 获取View id如果没有idSDK>17, 使用[View.generateViewId];否则使用[View.hashCode]
* 获取View id
*/
@SuppressLint("ObsoleteSdkInt")
fun View.getViewId(): Int {
var id = id
if (id == View.NO_ID) {
id = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
View.generateViewId()
} else {
this.hashCode()
}
id = View.generateViewId()
}
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()
},
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线程
*
* @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> {
return flow(block = requestBlock).flowOn(Dispatchers.IO)