feat: 添加 ViewModel、View 扩展方法,调整部分代码注释和结构
This commit is contained in:
@ -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) } }
|
||||
}
|
||||
@ -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,如果没有id:SDK>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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user