代码提交
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.app.Activity
|
||||
import java.util.Stack
|
||||
|
||||
object ActivityManager {
|
||||
|
||||
private val activityStack = Stack<Activity>()
|
||||
|
||||
// 添加Activity到栈
|
||||
fun addActivity(activity: Activity) {
|
||||
activityStack.add(activity)
|
||||
}
|
||||
|
||||
// 移除指定Activity
|
||||
fun removeActivity(activity: Activity) {
|
||||
activityStack.remove(activity)
|
||||
}
|
||||
|
||||
// 获取当前Activity
|
||||
fun currentActivity(): Activity? {
|
||||
return if (activityStack.isEmpty()) null else activityStack.lastElement()
|
||||
}
|
||||
|
||||
// 结束指定Activity
|
||||
fun finishActivity(activity: Activity) {
|
||||
if (!activity.isFinishing) {
|
||||
activity.finish()
|
||||
}
|
||||
}
|
||||
|
||||
// 结束所有Activity
|
||||
fun finishAllActivity() {
|
||||
activityStack.forEach {
|
||||
if (!it.isFinishing) {
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
activityStack.clear()
|
||||
}
|
||||
|
||||
// 退出应用程序
|
||||
fun exitApp() {
|
||||
finishAllActivity()
|
||||
android.os.Process.killProcess(android.os.Process.myPid())
|
||||
}
|
||||
|
||||
fun getActivityStack(): Stack<Activity>{
|
||||
return activityStack
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.util.SparseIntArray
|
||||
|
||||
object DataUtil {
|
||||
|
||||
fun getWeighAddressArray(): SparseIntArray {
|
||||
return SparseIntArray().apply {
|
||||
put(0, 12)
|
||||
put(1, 13)
|
||||
put(2, 14)
|
||||
put(3, 9)
|
||||
put(4, 10)
|
||||
put(5, 11)
|
||||
put(6, 6)
|
||||
put(7, 7)
|
||||
put(8, 8)
|
||||
put(9, 5)
|
||||
put(12, 4)
|
||||
put(10, 3)
|
||||
put(11, 3)
|
||||
put(13, 3)
|
||||
put(14, 3)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Date
|
||||
|
||||
|
||||
object DateTimeUtil {
|
||||
|
||||
const val YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"
|
||||
|
||||
fun formatDateTime(dateTime: LocalDateTime, pattern: String = YYYY_MM_DD_HH_MM_SS): String {
|
||||
val formatter = DateTimeFormatter.ofPattern(pattern)
|
||||
return dateTime.format(formatter)
|
||||
}
|
||||
|
||||
fun convert(dateStr: String, pattern: String = YYYY_MM_DD_HH_MM_SS): Date {
|
||||
val formatter = DateTimeFormatter.ofPattern(pattern)
|
||||
val ldt = LocalDateTime.parse(dateStr, formatter)
|
||||
val zdt = ldt.atZone(ZoneId.systemDefault())
|
||||
return Date.from(zdt.toInstant())
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val now = LocalDateTime.now()
|
||||
println("默认格式: ${formatDateTime(now)}")
|
||||
println("自定义格式: ${formatDateTime(now, "yyyy年MM月dd日 HH时mm分ss秒")}")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonToken
|
||||
import com.google.gson.stream.JsonWriter
|
||||
|
||||
class DecimalAdapter : TypeAdapter<Number>() {
|
||||
override fun write(out: JsonWriter, value: Number) {
|
||||
// out.value(value.toString()) // 强制以字符串形式写入
|
||||
out.value("$value") // 强制以字符串形式写入
|
||||
}
|
||||
|
||||
override fun read(reader: JsonReader): Number {
|
||||
return when (reader.peek()) {
|
||||
JsonToken.NUMBER -> reader.nextDouble()
|
||||
JsonToken.STRING -> reader.nextString().toDouble()
|
||||
else -> 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用方式
|
||||
//val gson = GsonBuilder()
|
||||
// .registerTypeAdapter(Double::class.java, DecimalAdapter())
|
||||
// .create()
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
|
||||
|
||||
object KeyboardUtil {
|
||||
|
||||
fun hideKeyboard(context: Context, view: View) {
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
view.clearFocus() // 清除焦点避免键盘再次弹出
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.util.Log
|
||||
|
||||
//object LogUtil {
|
||||
//
|
||||
// fun d(tag: String, msg: String) {
|
||||
// Log.d(tag, msg)
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.adapter.DishPartAdapter
|
||||
import com.shuwei.dish.match.adapter.DishShowAdapter
|
||||
import com.shuwei.dish.match.adapter.SamplingAdapter
|
||||
|
||||
class SwipeCallback(
|
||||
private val adapter: BaseQuickAdapter<*,*>,
|
||||
private val callback: (position: Int) -> Unit = {}
|
||||
) :
|
||||
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder
|
||||
): Boolean {
|
||||
return false // 不允许拖动,只允许滑动删除
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||
val position = viewHolder.getBindingAdapterPosition()
|
||||
callback(position)
|
||||
}
|
||||
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
val position = viewHolder.getBindingAdapterPosition()
|
||||
// 默认的拖动和滑动方向
|
||||
val dragFlags = 0
|
||||
// ItemTouchHelper.UP or ItemTouchHelper.DOWN
|
||||
var swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
|
||||
|
||||
if (adapter is SamplingAdapter) {
|
||||
if (!adapter.items[position].isCooking) {
|
||||
swipeFlags = 0
|
||||
}
|
||||
} else if (adapter is DishShowAdapter) {
|
||||
if (!adapter.items[position].isCooking) {
|
||||
swipeFlags = 0
|
||||
}
|
||||
} else if (adapter is DishPartAdapter) {
|
||||
if (!adapter.items[position].isNewDishType) {
|
||||
swipeFlags = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 根据viewHolder的逻辑判断是否允许滑动
|
||||
val count = recyclerView.adapter?.itemCount ?:0
|
||||
//BaseQuickAdapter中空布局使用的ViewHolder是这个import com.chad.library.adapter4.viewholder.StateLayoutVH
|
||||
if (count == 1 && viewHolder !is QuickViewHolder) {
|
||||
swipeFlags = 0 // 不允许滑动
|
||||
}
|
||||
return makeMovementFlags(dragFlags, swipeFlags)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.shuwei.dish.match.R
|
||||
|
||||
|
||||
object ToastUtil {
|
||||
|
||||
fun show(context: Context, message: String, duration:Int = Toast.LENGTH_SHORT) {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val layout: View = inflater.inflate(R.layout.custom_toast, null)
|
||||
val textView = layout.findViewById<TextView>(R.id.tvMessage)
|
||||
textView.text = message
|
||||
|
||||
val toast = Toast(context)
|
||||
toast.view = layout // 设置自定义视图
|
||||
toast.setGravity(Gravity.CENTER, 0, 0) // 调整位置居中显示
|
||||
toast.setDuration(duration)
|
||||
toast.show()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.shuwei.dish.match.utils
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.aithings.Weigher
|
||||
import com.shuwei.dish.match.base.BaseApp
|
||||
import com.shuwei.dish.match.utils.ext.toast
|
||||
import com.wabon.wbintelligenthardwaresdk.api.SensorScale
|
||||
|
||||
object WeightUtil {
|
||||
|
||||
fun connect(initCallback: (connect: Boolean) -> Unit) {
|
||||
Weigher.setListener(object : WeightListenerImpl() {
|
||||
override fun onInit(connect: Boolean) {
|
||||
initCallback(connect)
|
||||
Log.d("WeightUtil", "connect=$connect")
|
||||
}
|
||||
|
||||
override fun onZero() {
|
||||
Log.d("WeightUtil", "zero ok")
|
||||
}
|
||||
|
||||
override fun onTare() {
|
||||
Log.d("WeightUtil", "去皮置零操作成功")
|
||||
}
|
||||
|
||||
override fun onSetIdentify() {
|
||||
Log.d("WeightUtil", "鉴别率设置操作成功")
|
||||
}
|
||||
|
||||
override fun onGetWeight(address: Int, state: Int, weight: Int) {
|
||||
runOnUiThread {
|
||||
val stateStr = when (state) {
|
||||
SensorScale.STATE_STABLE -> "稳定"
|
||||
SensorScale.STATE_UNSTABLE -> "不稳定"
|
||||
SensorScale.STATE_OVER_WEIGHT -> "量程溢出"
|
||||
else -> ""
|
||||
}
|
||||
val result1 = String.format("$stateStr 重量:%s kg", weight / 1000f)
|
||||
Log.d("WeightUtil", "ttlReturn, address:$address,$result1")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReadIdentify(rate: Int) {
|
||||
Log.d("WeightUtil", "读取鉴别率成功:rate=$rate")
|
||||
}
|
||||
|
||||
override fun onFail(errCode: Int) {
|
||||
val str = when (errCode) {
|
||||
Weigher.ERR_001 -> "电子称未初始化"
|
||||
Weigher.ERR_002 -> "开机零位异常"
|
||||
Weigher.ERR_003 -> "传感器故障"
|
||||
Weigher.ERR_004 -> "鉴别率超出范围"
|
||||
Weigher.ERR_PCB_NOT_SUPPORT -> "主板不支持, " + Build.MODEL
|
||||
else -> ""
|
||||
}
|
||||
Log.d("WeightUtil", str)
|
||||
}
|
||||
|
||||
override fun onFastFilter() {
|
||||
Log.d("WeightUtil", "快速滤波设置成功")
|
||||
}
|
||||
|
||||
override fun onReadParam() {
|
||||
Log.d("WeightUtil", "prepare ok")
|
||||
}
|
||||
|
||||
override fun onRangCal() {
|
||||
Log.d("WeightUtil", "rang cal ok")
|
||||
}
|
||||
|
||||
override fun onSetParam() {
|
||||
Log.d("WeightUtil", "onSetParam")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun runOnUiThread(action: () -> Unit) {
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
fun addWeightListener(
|
||||
zero: (() -> Unit) = {},
|
||||
getWeight: ((address: Int, state: Int, weight: Int) -> Unit) = { _, _, _ -> }
|
||||
) {
|
||||
Weigher.setListener(object : WeightListenerImpl() {
|
||||
override fun onZero() {
|
||||
zero()
|
||||
}
|
||||
|
||||
override fun onGetWeight(address: Int, state: Int, weight: Int) {
|
||||
getWeight(address, state, weight)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class WeightListenerImpl : Weigher.Listener {
|
||||
override fun onInit(connect: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onZero() {
|
||||
|
||||
}
|
||||
|
||||
override fun onTare() {
|
||||
|
||||
}
|
||||
|
||||
override fun onSetIdentify() {
|
||||
|
||||
}
|
||||
|
||||
override fun onGetWeight(address: Int, state: Int, weight: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onReadIdentify(rate: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFail(errCode: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFastFilter() {
|
||||
|
||||
}
|
||||
|
||||
override fun onReadParam() {
|
||||
|
||||
}
|
||||
|
||||
override fun onRangCal() {
|
||||
|
||||
}
|
||||
|
||||
override fun onSetParam() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package com.shuwei.dish.match.utils.ext
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Resources
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityOptionsCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.shuwei.dish.match.utils.ToastUtil
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
fun Context.toast(
|
||||
message: String?,
|
||||
duration: Int = Toast.LENGTH_SHORT,
|
||||
) {
|
||||
if (message.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
//Toast.makeText(this, message, duration).show()
|
||||
ToastUtil.show(this, message, duration)
|
||||
}
|
||||
|
||||
fun Fragment.toast(
|
||||
message: String?,
|
||||
duration: Int = 2000
|
||||
) {
|
||||
activity?.toast(message, duration)
|
||||
}
|
||||
|
||||
//fun Fragment.toast(
|
||||
// message: String?,
|
||||
// duration: Int = 2000
|
||||
//) {
|
||||
// if (isAdded.not()) {
|
||||
// return
|
||||
// }
|
||||
// CustomToast(
|
||||
// activity = requireActivity(),
|
||||
// message = message,
|
||||
// duration = duration
|
||||
// ).show()
|
||||
//}
|
||||
//
|
||||
//public fun BaseActivity.toast(message: String?, duration: Int = 2000) {
|
||||
// CustomToast(
|
||||
// activity = this,
|
||||
// message = message,
|
||||
// duration = duration
|
||||
// ).show()
|
||||
//}
|
||||
|
||||
fun View.visible() {
|
||||
visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun View.invisible() {
|
||||
visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
fun View.gone() {
|
||||
visibility = View.GONE
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Context.startActivity(
|
||||
bundle: Bundle? = null,
|
||||
options: ActivityOptionsCompat? = null
|
||||
) {
|
||||
Intent(this, T::class.java).apply {
|
||||
bundle?.let { putExtras(it) }
|
||||
if (options != null && this@startActivity is Activity) {
|
||||
startActivity(this, options.toBundle())
|
||||
} else {
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> Context.startActivity(
|
||||
block: Intent.() -> Unit = {}
|
||||
) {
|
||||
Intent(this, T::class.java).apply {
|
||||
block()
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
||||
//inline fun <reified T : Activity> Context.startActivity(action:(bundle: Bundle)-> Unit) {
|
||||
// Intent(this, T::class.java).apply {
|
||||
// action(Bundle())
|
||||
// startActivity(this)
|
||||
// }
|
||||
//}
|
||||
|
||||
inline fun <reified T> String.toType(gson: Gson? = null, typeToken: TypeToken<T>): T {
|
||||
return (gson ?: Gson()).fromJson(this, typeToken.type)
|
||||
}
|
||||
|
||||
inline fun <reified T> String.toObject(gson: Gson? = null): T {
|
||||
return (gson ?: Gson()).fromJson(this, T::class.java)
|
||||
}
|
||||
|
||||
fun Any?.toJsonString(gson: Gson? = null): String {
|
||||
return (gson ?: Gson()).toJson(this) ?: ""
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
inline fun SharedPreferences.edit(
|
||||
commit: Boolean = false,
|
||||
action: SharedPreferences.Editor.() -> Unit
|
||||
) {
|
||||
val editor = edit()
|
||||
action(editor)
|
||||
if (commit) editor.commit() else editor.apply()
|
||||
}
|
||||
|
||||
fun SharedPreferences.put(vararg pairs: Pair<String, Any>) {
|
||||
edit {
|
||||
pairs.forEach { (key, value) ->
|
||||
when (value) {
|
||||
is Int -> putInt(key, value)
|
||||
is String -> putString(key, value)
|
||||
is Boolean -> putBoolean(key, value)
|
||||
is Float -> putFloat(key, value)
|
||||
is Long -> putLong(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val Float.dp: Float
|
||||
get() = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
this,
|
||||
Resources.getSystem().displayMetrics
|
||||
)
|
||||
|
||||
val Int.dp: Int
|
||||
get() = this.toFloat().dp.toInt()
|
||||
|
||||
fun EditText.addOnActionSearchListener(searchCallback: () -> Unit) {
|
||||
setOnEditorActionListener { v, actionId, event ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
// 处理搜索逻辑
|
||||
searchCallback()
|
||||
return@setOnEditorActionListener true // 阻止事件继续传递
|
||||
}
|
||||
return@setOnEditorActionListener false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun View.clickWithDebounce(delay: Long = 500, action: () -> Unit) {
|
||||
var job: Job? = null
|
||||
setOnClickListener {
|
||||
job?.cancel()
|
||||
job = CoroutineScope(Dispatchers.Main).launch {
|
||||
delay(delay)
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.shuwei.dish.match.utils.ext
|
||||
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
|
||||
|
||||
inline fun buildSpannableString(builderAction: SpannableStringBuilder.() -> Unit): SpannableStringBuilder {
|
||||
return SpannableStringBuilder().apply(builderAction)
|
||||
}
|
||||
|
||||
fun SpannableStringBuilder.appendText(text: String, vararg spans: Any): SpannableStringBuilder {
|
||||
val start = length
|
||||
append(text)
|
||||
spans.forEach { span ->
|
||||
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun SpannableStringBuilder.withSpan(span: Any, block: SpannableStringBuilder.() -> Unit) {
|
||||
val start = length
|
||||
block()
|
||||
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
Reference in New Issue
Block a user