You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.8 KiB

package com.gyf.csams.uikit
import android.app.Application
import androidx.compose.material.SnackbarDuration
import androidx.compose.ui.graphics.ImageBitmap
import androidx.lifecycle.*
import com.google.gson.reflect.TypeToken
import com.gyf.csams.R
import com.gyf.csams.util.HttpClient
import com.gyf.csams.util.ImageUtil
import com.gyf.csams.util.SimpleCallback
import com.orhanobut.logger.Logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
interface FormLength {
val nameLengthError: String
}
abstract class FormName<T>(val formDesc: String) {
protected val _formValue = MutableLiveData<T>()
val formValue: LiveData<T> = _formValue
val formPlaceholder = "请输入$formDesc"
abstract fun onChange(value: T)
}
/**
* 文本输入框控制
*
* @property textLength
* @constructor
*
* @param formDesc
*/
open class StringForm(formDesc: String, val textLength: Int) :
FormName<String>(formDesc = formDesc),
FormLength {
constructor(formDesc: String, textLength: Int, value: String) : this(
formDesc = formDesc,
textLength = textLength
) {
_formValue.value = value
}
override val nameLengthError = "${formDesc}不能超过最大长度$textLength"
override fun onChange(value: String) {
if (value.length > textLength) {
_formValue.value = value.slice(IntRange(0, textLength - 1))
} else {
_formValue.value = value
}
Logger.i("${formDesc}更新值:${_formValue.value}")
}
}
data class SnackBar(
val message: String?,
val actionLabel: String? = null,
val duration: SnackbarDuration = SnackbarDuration.Short,
val callback: () -> Unit?
)
/**
* snackbar
*
*/
class ScaffoldModel : ViewModel() {
private val _data = MutableLiveData<SnackBar>()
val data: LiveData<SnackBar> = _data
fun update(message: String? = null, actionLabel: String? = null, callback: () -> Unit? = {}) {
if (message == null) {
_data.value = null
} else {
_data.value =
SnackBar(message = message, actionLabel = actionLabel, callback = callback)
}
}
}
class ImageModel(application: Application, private val urlPath: String) :
AndroidViewModel(application) {
private val _image = MutableLiveData<ImageBitmap>()
private val _imageUrls = MutableLiveData<List<String>>()
val image: LiveData<ImageBitmap> = _image
private var job: Job? = null
/**
* 加载默认图片
*
*/
private fun defaultLoad() {
viewModelScope.launch {
_image.postValue(
ImageUtil.getImage(
getApplication(),
R.drawable.ic_launcher_foreground
)
)
}
}
/**
* 循环加载网络图片
*
*/
fun start() {
Logger.i("启动轮播")
if (job == null || job?.isCompleted == true || job?.isCancelled == true) {
job = viewModelScope.launch {
HttpClient.get(
url = urlPath,
SimpleCallback<List<String>>("请求图片url列表", onSuccess = {
_imageUrls.postValue(it.body)
var index = 0
_imageUrls.value?.apply {
viewModelScope.launch {
do {
val imageBitmap =
ImageUtil.getImage(
context = getApplication(),
data = get(index)
)
Logger.e("成功从image url:${get(index)}解析图片")
_image.postValue(imageBitmap)
delay(5000)
index = if (index == size - 1) 0 else index.plus(1)
} while (job?.isActive == true)
}
}
}, onFail = {
Logger.e("无法从接口地址:${urlPath}获取图片url列表")
defaultLoad()
}, type = object : TypeToken<List<String>>() {}.type)
)
}.apply {
start()
}
}
}
fun cancel() {
Logger.i("停止轮播")
job?.cancel()
}
}
abstract class ScrollList<T> : ViewModel() {
protected val _data = MutableLiveData<MutableList<T>>(mutableListOf())
val data: LiveData<MutableList<T>> = _data
abstract val initSize: Int
//加载列表
abstract fun load()
//加载更多数据
abstract fun loadMore(callback: (message: String) -> Unit)
}