联合支付功能调试
This commit is contained in:
@@ -59,7 +59,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar", "*.jar"))))
|
||||
//implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar", "*.jar"))))
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
@@ -110,17 +110,19 @@ dependencies {
|
||||
implementation(libs.pytorch.android)
|
||||
implementation(libs.pytorch.android.torchvision)
|
||||
|
||||
implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha")
|
||||
implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha")
|
||||
implementation(libs.baseRecyclerViewAdapterHelper4)
|
||||
|
||||
implementation(libs.refresh.layout.kernel)
|
||||
implementation(libs.refresh.header.classics)
|
||||
|
||||
val objectboxVersion = "5.0.1"
|
||||
debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion")
|
||||
debugImplementation(libs.objectbox.android.objectbrowser)
|
||||
// releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
|
||||
// implementation("io.objectbox:objectbox-fulltext:5.0.1")
|
||||
|
||||
implementation(libs.androidx.recyclerview)
|
||||
|
||||
implementation("org.greenrobot:eventbus:3.2.0")
|
||||
implementation(libs.eventbus)
|
||||
}
|
||||
|
||||
apply(plugin = "io.objectbox")
|
||||
Binary file not shown.
@@ -32,10 +32,10 @@ import com.sw.dualscreen.databinding.ActivityMainBinding
|
||||
import com.sw.dualscreen.dialog.RemindDialog
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.invisible
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.response.ChargeModeEvent
|
||||
import com.sw.dualscreen.model.response.ClickBackEvent
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.model.response.FoodOrder
|
||||
import com.sw.dualscreen.model.response.PaySuccessEvent
|
||||
@@ -79,7 +79,6 @@ import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@@ -91,6 +90,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
companion object {
|
||||
private const val TAG = "MainActivity"
|
||||
const val TIME_OUT = 5 * 60 * 1000L
|
||||
|
||||
const val WEIGHT_CHANGE_VALUE = 25
|
||||
const val WEIGHT_RESET_RECOGNIZE = 10
|
||||
}
|
||||
|
||||
private val viewModel by viewModels<UserViewModel>()
|
||||
@@ -101,28 +103,36 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private var presentation: MainScreenPresentation? = null
|
||||
private val executor = Executors.newSingleThreadExecutor()
|
||||
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||
private val searchFoodList = mutableListOf<FoodInfo>()
|
||||
private val adapter by lazy {
|
||||
MainFoodListAdapter(searchFoodList).apply {
|
||||
MainFoodListAdapter(mutableListOf()).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
if (searchFoodList[position].isChecked) {
|
||||
if (items[position].isChecked) {
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
searchFoodList.forEachIndexed { index, info ->
|
||||
searchFoodList[index].isChecked = index == position
|
||||
items.forEachIndexed { index, info ->
|
||||
items[index].isChecked = index == position
|
||||
}
|
||||
val item = searchFoodList[position]
|
||||
val item = items[position]
|
||||
log("itemClick ${item.foodName}, position = $position")
|
||||
item.photoUri = null
|
||||
checkedItem = item
|
||||
notifyDataSetChanged()
|
||||
updateCurrentFood(item)
|
||||
//0-计费,1-不计费
|
||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
//不计费模式切换菜品,重新加载数据
|
||||
if (mode == 1) {
|
||||
presentation?.isAgainLoadData = false
|
||||
presentation?.loadUnbilledMode()
|
||||
if (settlementMode == 0) {
|
||||
//联合支付,切换菜品重新请求接口
|
||||
presentation?.let {
|
||||
it.pauseCamera()
|
||||
it.step2FaceRecognizing(item, true)
|
||||
}
|
||||
// presentation?.step3ShowRecognizeResult(presentation!!.currentUserId?:"")
|
||||
} else {
|
||||
//0-计费,1-不计费
|
||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
//不计费模式切换菜品,重新加载数据
|
||||
if (mode == 1) {
|
||||
presentation?.isAgainLoadData = false
|
||||
presentation?.loadUnbilledMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +142,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
|
||||
private var canIdentify: Boolean = false
|
||||
private var bottomSheetDialog: CustomBottomSheetDialog? = null
|
||||
private var lastWeight: Double = 0.0
|
||||
private var lastWeight: Int = 0
|
||||
private var lastPhotoUri: Uri? = null // 最后拍照的图片
|
||||
private var debouncer = Debouncer(5000)
|
||||
private var isRecognitionFood = true
|
||||
@@ -200,8 +210,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
checkedItem = it
|
||||
it.photoUri = null
|
||||
updateCurrentFood(it)
|
||||
searchFoodList.forEachIndexed { index, info ->
|
||||
searchFoodList[index].isChecked = false
|
||||
adapter.items.forEachIndexed { index, info ->
|
||||
adapter.items[index].isChecked = false
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
@@ -209,7 +219,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
|
||||
binding.recyclerview.let {
|
||||
it.layoutManager = GridLayoutManager(this, 2)
|
||||
it.layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false)
|
||||
it.adapter = adapter
|
||||
}
|
||||
binding.tvFoodName.setOnClickListener {
|
||||
@@ -220,7 +230,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private var recognizeWeight = 0.0
|
||||
private var recognizeWeight = 0
|
||||
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
||||
if (foodInfo == null) {
|
||||
binding.tvFoodName.text = "-"
|
||||
@@ -245,52 +255,75 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
binding.ivImg.load(imgUrl)
|
||||
}
|
||||
|
||||
override fun registerDataChange() {
|
||||
super.registerDataChange()
|
||||
SensorScaleUtils.addWeightListener { weight ->
|
||||
log("registerDataChange weight = $weight")
|
||||
//runOnUiThread { binding.tvShowWeight.text="${weight*1000}克" }
|
||||
if (presentation?.jointPaymentQueryFinish == true) {
|
||||
//0-即放即取,1-余量计量
|
||||
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||
if (mealPickupMode == 0 && weight <= 0.005) {
|
||||
isAnalyzing = false
|
||||
presentation?.step1FoodRecognizing()
|
||||
} else {
|
||||
return@addWeightListener
|
||||
}
|
||||
private fun readWeight(weight: Int) {
|
||||
log("registerDataChange weight = $weight")
|
||||
//runOnUiThread { binding.tvShowWeight.text="${weight*1000}克" }
|
||||
if (settlementMode == 0) {
|
||||
//联合支付-------------------------------------------
|
||||
//0-即放即取,1-余量计量
|
||||
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||
if (mealPickupMode == 1) {
|
||||
return
|
||||
}
|
||||
|
||||
//if (presentation?.currentFood == null) return@addWeightListener
|
||||
if (lastWeight - weight > 0.005) {
|
||||
//及放及取,从秤上拿走超过5克
|
||||
if (presentation?.mealPickupMode == 0) {
|
||||
presentation?.updateWeight(weight)
|
||||
lastWeight = weight
|
||||
return@addWeightListener
|
||||
//即放即取+联合支付人脸查询订单完成
|
||||
if (presentation!!.jointPaymentQueryFinish) {
|
||||
if (weight > WEIGHT_RESET_RECOGNIZE) {
|
||||
//已识别完成人脸并查询到订单数据,增加重量不再重新识别
|
||||
return
|
||||
}
|
||||
//重量小于等于5克时改为识别中页面
|
||||
isAnalyzing = false
|
||||
presentation?.step1FoodRecognizing()
|
||||
return
|
||||
}
|
||||
if (isPageVisible.not() || isStartRecognize.not()) {
|
||||
if (ActivityManager.currentActivity() is MainActivity) {
|
||||
isPageVisible = true
|
||||
isStartRecognize = true
|
||||
}
|
||||
return@addWeightListener
|
||||
if (weight <= WEIGHT_RESET_RECOGNIZE) {
|
||||
//秤上重量过下,显示识别中页面
|
||||
presentation?.step1FoodRecognizing()
|
||||
return
|
||||
}
|
||||
//0.05
|
||||
// val isWeightChange = abs(weight - lastWeight) > 0.02
|
||||
val isWeightChange = weight - lastWeight > 0.02
|
||||
val isWeightChange = weight - lastWeight > WEIGHT_CHANGE_VALUE
|
||||
if (weight != lastWeight) {
|
||||
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
|
||||
}
|
||||
recognizeByWeight(weight, isWeightChange)
|
||||
return
|
||||
}
|
||||
//独立支付-------------------------------------------
|
||||
if (lastWeight - weight > 5) {
|
||||
//及放及取,从秤上拿走超过5克
|
||||
if (presentation?.mealPickupMode == 0) {
|
||||
presentation?.updateWeight(weight)
|
||||
lastWeight = weight
|
||||
return
|
||||
}
|
||||
}
|
||||
if (isPageVisible.not() || isStartRecognize.not()) {
|
||||
if (ActivityManager.currentActivity() is MainActivity) {
|
||||
isPageVisible = true
|
||||
isStartRecognize = true
|
||||
}
|
||||
return
|
||||
}
|
||||
// val isWeightChange = abs(weight - lastWeight) > 0.02
|
||||
val isWeightChange = weight - lastWeight > WEIGHT_CHANGE_VALUE
|
||||
if (weight != lastWeight) {
|
||||
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
|
||||
}
|
||||
recognizeByWeight(weight, isWeightChange)
|
||||
}
|
||||
|
||||
override fun registerDataChange() {
|
||||
super.registerDataChange()
|
||||
SensorScaleUtils.addWeightListener { value ->
|
||||
readWeight(value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun recognizeByWeight(weight: Double, isWeightChange: Boolean, block: () -> Unit = {}) {
|
||||
private fun recognizeByWeight(weight: Int, isWeightChange: Boolean, block: () -> Unit = {}) {
|
||||
presentation?.updateWeight(weight)
|
||||
|
||||
if (weight <= 0.005) {
|
||||
if (weight <= WEIGHT_RESET_RECOGNIZE) {
|
||||
log("recognizeByWeight---00002,秤重未超过5克")
|
||||
//检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
|
||||
isRecognitionFood = true
|
||||
@@ -374,9 +407,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
// e.printStackTrace()
|
||||
// list
|
||||
// }
|
||||
searchFoodList.clear()
|
||||
searchFoodList.addAll(list)
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
|
||||
adapter.submitList(list)
|
||||
binding.recyclerview.visible()
|
||||
|
||||
checkedItem = list[0].also {
|
||||
it.photoUri = lastPhotoUri
|
||||
@@ -559,10 +593,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun clearFoodList() {
|
||||
//adapter.updateData(listOf())
|
||||
searchFoodList.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
fun clearRecognizeFood() {
|
||||
log("clearRecognizeFood")
|
||||
binding.recyclerview.invisible()
|
||||
adapter.submitList(null)
|
||||
binding.tvToSearch.gone()
|
||||
|
||||
binding.previewView.visible()
|
||||
binding.ivImg.gone()
|
||||
}
|
||||
|
||||
private fun updateDateTime() {
|
||||
@@ -594,7 +632,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
log("onResume-00001,isRefreshPage=$isRefreshPage")
|
||||
if (presentation == null || !presentation!!.isShowing) {
|
||||
log("onResume-00002,副屏未显示,加载副屏")
|
||||
lastWeight = 0.0
|
||||
lastWeight = 0
|
||||
setupSecondaryDisplay()
|
||||
presentation?.step1FoodRecognizing()
|
||||
} else {
|
||||
@@ -603,7 +641,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
isRefreshPage = false
|
||||
//已显示副屏,则进行更新
|
||||
val weight = lastWeight
|
||||
lastWeight = 0.0
|
||||
lastWeight = 0
|
||||
presentation?.hideRecImage()
|
||||
presentation?.step1FoodRecognizing()
|
||||
|
||||
@@ -662,7 +700,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
eatWeight: Int,
|
||||
eatNum: Int,
|
||||
userId: String?,
|
||||
isMember:Boolean,
|
||||
isMember: Boolean,
|
||||
notEnoughOneBlock: () -> Unit = {},
|
||||
successBlock: () -> Unit
|
||||
) {
|
||||
@@ -800,36 +838,36 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||
//0-计费,1-不计费
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
|
||||
var foodWeight = 0.0
|
||||
var eatWeight = 0.0
|
||||
var foodWeight = 0
|
||||
var eatWeight = 0
|
||||
if (chargeMode == 0) {
|
||||
//计费
|
||||
if (mealPickupMode == 0) {
|
||||
//即放即取
|
||||
eatWeight = lastWeight * 1000
|
||||
foodWeight = lastWeight * 1000
|
||||
eatWeight = lastWeight
|
||||
foodWeight = lastWeight
|
||||
} else {
|
||||
//余量计量
|
||||
eatWeight = (recognizeWeight - lastWeight) * 1000
|
||||
foodWeight = recognizeWeight * 1000
|
||||
eatWeight = recognizeWeight - lastWeight
|
||||
foodWeight = recognizeWeight
|
||||
log("eatWeight=$eatWeight, recognizeWeight=$recognizeWeight, lastWeight=$lastWeight")
|
||||
}
|
||||
} else {
|
||||
//不计费
|
||||
foodWeight = recognizeWeight * 1000
|
||||
foodWeight = recognizeWeight
|
||||
eatWeight = if (mealPickupMode == 0) {
|
||||
//即放即取
|
||||
recognizeWeight * 1000
|
||||
recognizeWeight
|
||||
} else {
|
||||
//余量计量
|
||||
(recognizeWeight - lastWeight) * 1000
|
||||
recognizeWeight - lastWeight
|
||||
}
|
||||
}
|
||||
val eatNum = getEatNum(eatWeight, checkedItem!!.specWeight)
|
||||
val eatNum = getEatNum(eatWeight.toDouble(), checkedItem!!.specWeight)
|
||||
createOrder(
|
||||
foodInfo = checkedItem!!,
|
||||
foodWeight = foodWeight.roundToInt(),
|
||||
eatWeight = eatWeight.roundToInt(),
|
||||
foodWeight = foodWeight,
|
||||
eatWeight = eatWeight,
|
||||
eatNum = eatNum,
|
||||
userId = null,
|
||||
isMember = false
|
||||
@@ -956,7 +994,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
// private val dealyMillis = 10 * 60 * 1000L
|
||||
private val initialDelay = 10 * 1000L
|
||||
private val dealyMillis = 5 * 1000L
|
||||
// private var taskPageNo = 1
|
||||
|
||||
// private var taskPageNo = 1
|
||||
fun startFaceTask() {
|
||||
faceTaskJob =
|
||||
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
|
||||
@@ -1097,13 +1136,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏搜索按钮
|
||||
*/
|
||||
fun hideSearchView() {
|
||||
binding.tvToSearch.gone()
|
||||
}
|
||||
|
||||
// @Subscribe(threadMode = ThreadMode.MAIN)
|
||||
// public fun onResetBox(event: ResetBoxEvent) {
|
||||
// ObjectBox.boxStore.close()
|
||||
|
||||
@@ -77,8 +77,8 @@ class BusinessFragment: BaseFragment<FragmentBusinessBinding>() {
|
||||
}
|
||||
}
|
||||
SensorScaleUtils.addWeightListener { value ->
|
||||
val realWeight = (value * 1000).roundToInt()
|
||||
binding.tvFoodWeight.text = "$realWeight"
|
||||
//val realWeight = (value * 1000).roundToInt()
|
||||
binding.tvFoodWeight.text = "$value"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,19 +10,21 @@ import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.dualscreen.databinding.LayoutFoodListHeaderBinding
|
||||
import com.sw.dualscreen.databinding.ListItemFoodOrderBinding
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.ext.format2String
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.response.FoodItem
|
||||
|
||||
class FoodOrderAdapter(var list: MutableList<FoodItem>) :
|
||||
BaseQuickAdapter<FoodItem, FoodOrderAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: LayoutFoodListHeaderBinding) : QuickViewHolder(binding.root)
|
||||
inner class VH(var binding: ListItemFoodOrderBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = LayoutFoodListHeaderBinding.inflate(inflater, parent, false)
|
||||
val binding = ListItemFoodOrderBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
@@ -31,9 +33,20 @@ class FoodOrderAdapter(var list: MutableList<FoodItem>) :
|
||||
val binding = holder.binding
|
||||
item?.let {
|
||||
binding.tvFoodName.text = it.foodName
|
||||
binding.tvPriceNorm.text = it.foodPrice.format2String(2)
|
||||
val foodPrice = it.foodPrice.format2String(2)
|
||||
if (it.orderFrom == 2) {
|
||||
binding.tvPriceNorm.text = "${it.specName}-${it.specWeight}克"
|
||||
} else {
|
||||
binding.tvPriceNorm.text = "${foodPrice}/${it.num}克"
|
||||
}
|
||||
//if (it.specName.isNullOrBlank().not()) {
|
||||
// binding.tvPriceFlag.text = "[${it.specName}]"
|
||||
//}
|
||||
binding.tvWeight.text = "${it.num}克"
|
||||
binding.tvAmount.text = it.price.format2String(2)
|
||||
binding.tvLabel.run {
|
||||
if (it.orderFrom == 2) visible() else gone()
|
||||
}
|
||||
}
|
||||
setTextColor(binding.tvFoodName, binding.tvPriceNorm, binding.tvWeight, binding.tvAmount)
|
||||
binding.root.updateLayoutParams<RecyclerView.LayoutParams> {
|
||||
|
||||
@@ -177,7 +177,10 @@ data class FoodItem(
|
||||
val discount: Double = 0.0,
|
||||
val income: Double = 0.0,
|
||||
val foodDifferenceId: Long = 0,
|
||||
val createTime: String? = null
|
||||
val createTime: String? = null,
|
||||
val specName: String? = null,
|
||||
val specWeight: Int = 0,
|
||||
val orderFrom: Int = 0
|
||||
)
|
||||
|
||||
data class FoodOrderModel(
|
||||
|
||||
@@ -5,24 +5,16 @@ import android.annotation.SuppressLint
|
||||
import android.app.Presentation
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Outline
|
||||
import android.graphics.Point
|
||||
import android.hardware.Camera
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.FrameLayout
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -30,7 +22,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.arcsoft.face.ErrorInfo
|
||||
import com.sw.dualscreen.BuildConfig
|
||||
import com.sw.dualscreen.GlobalKey
|
||||
import com.sw.dualscreen.MyApp
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.MainActivity
|
||||
import com.sw.dualscreen.adapter.FoodOrderAdapter
|
||||
@@ -40,7 +31,6 @@ import com.sw.dualscreen.ext.format2String
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.maskName
|
||||
import com.sw.dualscreen.ext.roundedDecimalPlace
|
||||
import com.sw.dualscreen.ext.screenSize
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.response.DinnerType
|
||||
@@ -66,7 +56,6 @@ import com.sw.plate.utils.arcface.face.model.CompareResult
|
||||
import com.sw.plate.utils.arcface.face.model.FacePreviewInfo
|
||||
import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration
|
||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
@@ -105,14 +94,14 @@ class MainScreenPresentation(
|
||||
private var irFaceRectTransformer: FaceRectTransformer? = null
|
||||
|
||||
private var detectWeight = 0.0 //识别菜品时的重量
|
||||
var lastWeight = 0.0 // 上一次的计算热量结果
|
||||
var lastWeight = 0 // 上一次的计算热量结果
|
||||
|
||||
// private var userNutritionData: UserNutritionData? = null
|
||||
private var userNutrition: UserNutrition? = null
|
||||
private var dinnerTypeInfo: DinnerType? = null
|
||||
private val debouncer = Debouncer(500)
|
||||
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
||||
var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
||||
var recognitionWeight: Int = 0 // 人脸识别时的重量
|
||||
|
||||
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
|
||||
var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
|
||||
@@ -144,8 +133,8 @@ class MainScreenPresentation(
|
||||
|
||||
private var isFirstGetWeight = true
|
||||
|
||||
fun updateWeight(weight: Double) {
|
||||
lastWeight = weight * 1000 // 将千克转成克
|
||||
fun updateWeight(weight: Int) {
|
||||
lastWeight = weight
|
||||
Timber.tag(TAG)
|
||||
.d("updateWeight lastWeight = $weight, currentStep = $currentStep, isGoStep1 = $isGoStep1")
|
||||
//0-即放即取,1-余量计量
|
||||
@@ -164,14 +153,14 @@ class MainScreenPresentation(
|
||||
// }
|
||||
// isFirstGetWeight = true
|
||||
// }
|
||||
if (currentStep == 2 && lastWeight <= 5 && isGoStep1) {
|
||||
if (currentStep == 2 && lastWeight <= MainActivity.WEIGHT_RESET_RECOGNIZE && isGoStep1) {
|
||||
//人脸识别过程中,秤上物品拿走
|
||||
isGoStep1 = false
|
||||
activity.runOnUiThread {
|
||||
Timber.tag(TAG).e("切回step1")
|
||||
step1FoodRecognizing()
|
||||
}
|
||||
} else if (lastWeight <= 5) {
|
||||
} else if (lastWeight <= MainActivity.WEIGHT_RESET_RECOGNIZE) {
|
||||
isGoStep1 = false
|
||||
activity.runOnUiThread {
|
||||
Timber.tag(TAG).e("切回step1")
|
||||
@@ -287,6 +276,14 @@ class MainScreenPresentation(
|
||||
}
|
||||
}
|
||||
|
||||
private fun setTopInfoVisible() {
|
||||
binding.llTopInfo.visible()
|
||||
binding.flFoodDetail.gone()
|
||||
binding.llTopInfo.updateLayoutParams {
|
||||
height = activity.screenSize[1] / 2 + 120.dp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示识别出的菜品信息
|
||||
*/
|
||||
@@ -297,8 +294,7 @@ class MainScreenPresentation(
|
||||
currentStep = 3
|
||||
stepChangeCallback(currentStep)
|
||||
|
||||
binding.llTopInfo.visible()
|
||||
binding.flFoodDetail.gone()
|
||||
setTopInfoVisible()
|
||||
//根据接口数据更新热量数据--------------------------
|
||||
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
|
||||
activity.runOnUiThread {
|
||||
@@ -491,6 +487,9 @@ class MainScreenPresentation(
|
||||
* 餐品识别中
|
||||
*/
|
||||
fun step1FoodRecognizing() {
|
||||
if (currentStep == 1) {
|
||||
return
|
||||
}
|
||||
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
jointPaymentQueryFinish = false
|
||||
@@ -505,7 +504,6 @@ class MainScreenPresentation(
|
||||
// }
|
||||
// return
|
||||
//}
|
||||
currentStep = 1
|
||||
LightManager.closeGreenLight()
|
||||
LightManager.closeRedLight()
|
||||
|
||||
@@ -513,12 +511,9 @@ class MainScreenPresentation(
|
||||
currentFood = null
|
||||
// userNutritionData = null
|
||||
userNutrition = null
|
||||
recognitionWeight = 0.0
|
||||
recognitionWeight = 0
|
||||
|
||||
stepChangeCallback(currentStep)
|
||||
|
||||
binding.llTopInfo.visible()
|
||||
binding.flFoodDetail.gone()
|
||||
setTopInfoVisible()
|
||||
|
||||
binding.calorieInclude.root.gone()
|
||||
binding.nutritionInclude.root.gone()
|
||||
@@ -537,8 +532,10 @@ class MainScreenPresentation(
|
||||
binding.flRecognizeIr.gone()
|
||||
|
||||
pauseCamera()
|
||||
activity.clearFoodList()
|
||||
activity.hideSearchView()
|
||||
activity.clearRecognizeFood()
|
||||
|
||||
currentStep = 1
|
||||
stepChangeCallback(currentStep)
|
||||
}
|
||||
|
||||
// fun foodRecSuccess(foodInfo: FoodInfo) {
|
||||
@@ -560,9 +557,14 @@ class MainScreenPresentation(
|
||||
/**
|
||||
* 用户人脸识别中
|
||||
*/
|
||||
fun step2FaceRecognizing(foodInfo: FoodInfo) {
|
||||
fun step2FaceRecognizing(foodInfo: FoodInfo, hideFoodDetail: Boolean = false) {
|
||||
isGoStep1 = true
|
||||
Timber.tag(TAG).d("main,step2,耗时:${System.currentTimeMillis() - startTime}")
|
||||
|
||||
if (hideFoodDetail) {
|
||||
setTopInfoVisible()
|
||||
}
|
||||
|
||||
startTime = System.currentTimeMillis()
|
||||
currentStep = 2
|
||||
LightManager.closeRedLight()
|
||||
@@ -586,7 +588,7 @@ class MainScreenPresentation(
|
||||
dinnerTypeInfo = null
|
||||
// userNutritionData = null
|
||||
userNutrition = null
|
||||
recognitionWeight = 0.0
|
||||
recognitionWeight = 0
|
||||
|
||||
stepChangeCallback(currentStep)
|
||||
currentFood = foodInfo
|
||||
@@ -668,12 +670,12 @@ class MainScreenPresentation(
|
||||
// }
|
||||
}
|
||||
|
||||
private fun calculateNutrition(weight1: Double) {
|
||||
private fun calculateNutrition(value: Int) {
|
||||
if (currentFood == null || userNutrition == null) {
|
||||
return
|
||||
}
|
||||
var weight = weight1
|
||||
if (weight < 0) weight = 0.0
|
||||
var weight = value
|
||||
if (weight < 0) weight = 0
|
||||
debouncer.debounce {
|
||||
Timber.tag(TAG)
|
||||
.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
||||
@@ -684,7 +686,7 @@ class MainScreenPresentation(
|
||||
currentFood!!,
|
||||
// userNutritionData!!,
|
||||
userNutrition!!,
|
||||
weight,
|
||||
weight.toDouble(),
|
||||
dinnerType = dinnerType ?: ""
|
||||
)
|
||||
// Timber.tag(TAG).d("calculateNutrition calcResultInfo = $calcResultInfo")
|
||||
@@ -830,8 +832,23 @@ class MainScreenPresentation(
|
||||
isRecognition = false
|
||||
|
||||
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
||||
//triggerReidentify()
|
||||
}
|
||||
/**
|
||||
* 重置人脸跟踪状态,让已在画面中的人脸重新触发识别
|
||||
* 适用场景:切换按钮后需要重新识别当前画面中的人脸
|
||||
*/
|
||||
fun triggerReidentify() {
|
||||
// 清除UI上的人脸框
|
||||
binding.dualCameraFaceRectView.clearFaceInfo()
|
||||
// 清除本地跟踪数据
|
||||
clearLeftFaceData()
|
||||
// 重置上一次的 trackId,避免 drawPreviewInfo 中的去重逻辑拦截
|
||||
lastFaceTrackId = -1
|
||||
// 插入空帧,让引擎重置内部跟踪状态
|
||||
// isRecognition 保持 true,相机继续送帧,下一帧真实人脸会产生新 trackId
|
||||
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
||||
}
|
||||
|
||||
private var recognizeTime = 0L
|
||||
private fun initArcViewModel() {
|
||||
recognizeViewModel.setLiveType(livenessType)
|
||||
@@ -1187,8 +1204,7 @@ class MainScreenPresentation(
|
||||
}
|
||||
createOrder(notEnoughOneBlock = {
|
||||
if (activity.settlementMode == 0) {
|
||||
binding.flFoodDetail.gone()
|
||||
binding.llTopInfo.visible()
|
||||
setTopInfoVisible()
|
||||
}
|
||||
// if (mealPickupMode == 0) {
|
||||
currentStep = 2
|
||||
@@ -1249,11 +1265,11 @@ class MainScreenPresentation(
|
||||
//userViewModel.postUserNutritionData(listOf(userNutritionParam))
|
||||
activity.createOrder(
|
||||
foodInfo = currentFood!!,
|
||||
foodWeight = lastWeight.roundToInt(),
|
||||
eatWeight = eatWeight.roundToInt(),
|
||||
eatNum = activity.getEatNum(eatWeight, currentFood!!.specWeight),
|
||||
foodWeight = lastWeight,
|
||||
eatWeight = eatWeight,
|
||||
eatNum = activity.getEatNum(eatWeight.toDouble(), currentFood!!.specWeight),
|
||||
userId = currentUserId,
|
||||
isMember = isMember ,
|
||||
isMember = isMember,
|
||||
notEnoughOneBlock = notEnoughOneBlock,
|
||||
successBlock = {
|
||||
activity.runOnUiThread {
|
||||
@@ -1316,11 +1332,12 @@ class MainScreenPresentation(
|
||||
binding.flFoodDetail.visible()
|
||||
binding.detailInclude.let {
|
||||
it.root.updateLayoutParams {
|
||||
height = activity.screenSize[1]/2
|
||||
height = activity.screenSize[1] / 2 + 120.dp
|
||||
}
|
||||
it.tvFoodList.run {
|
||||
if (adapter == null) {
|
||||
layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
|
||||
layoutManager =
|
||||
LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
|
||||
adapter = foodOrderAdapter
|
||||
}
|
||||
}
|
||||
@@ -1332,10 +1349,36 @@ class MainScreenPresentation(
|
||||
}
|
||||
foodOrderAdapter.notifyDataSetChanged()
|
||||
binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克"
|
||||
binding.detailInclude.tvTotalCalorie.text = "总热量:${model.calorie.roundToInt()}千卡"
|
||||
binding.detailInclude.tvTotalCalorie.text =
|
||||
"总热量:${model.calorie.roundToInt()}千卡"
|
||||
jointPaymentQueryFinish = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造符合分辨率的 NV21 格式全黑帧
|
||||
* @param width 图像宽度(如 1920)
|
||||
* @param height 图像高度(如 1080)
|
||||
* @return 合法的全黑帧字节数组
|
||||
*/
|
||||
private fun createBlackNV21Frame(width: Int, height: Int): ByteArray {
|
||||
val frameSize = width * height
|
||||
val nv21Data = ByteArray(frameSize * 3 / 2) // NV21 格式长度 = 宽×高×1.5
|
||||
|
||||
// Y 分量(亮度)设为 0(全黑),UV 分量设为 128(默认值)
|
||||
// 1. 填充 Y 分量(前 frameSize 个字节)
|
||||
// Arrays.fill(nv21Data, 0, frameSize, 0.toByte())
|
||||
nv21Data.fill(0, 0, frameSize)
|
||||
// 2. 填充 UV 分量(后 frameSize/2 个字节)
|
||||
// Arrays.fill(nv21Data, frameSize, nv21Data.size, 128.toByte())
|
||||
nv21Data.fill(128.toByte(), frameSize, nv21Data.size)
|
||||
|
||||
return nv21Data
|
||||
}
|
||||
|
||||
// 调用示例:构造 1920×1080 的全黑帧(长度 1382400)
|
||||
// private val emptyFrame = createBlackNV21Frame(1920, 1080)
|
||||
private val emptyFrame = createBlackNV21Frame(1280, 720)
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import timber.log.Timber
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
typealias Callback = (Double) -> Unit
|
||||
typealias WeightCallback = (Double) -> Unit
|
||||
typealias WeightCallback = (Int) -> Unit
|
||||
|
||||
private const val TAG = "SensorScaleUtils"
|
||||
|
||||
@@ -45,7 +45,7 @@ object SensorScaleUtils {
|
||||
}
|
||||
|
||||
weightCallbackList.forEach {
|
||||
it.invoke(value)
|
||||
it.invoke((value * 1000).roundToInt())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/darker_gray"/>
|
||||
<stroke android:color="#cdcdcd" android:width="1dp"/>
|
||||
<corners android:radius="5dp"/>
|
||||
</shape>
|
||||
@@ -285,7 +285,7 @@
|
||||
<TextView
|
||||
android:id="@+id/meatTv"
|
||||
style="@style/takeFoodNameTv"
|
||||
android:text="蛋肉"
|
||||
android:text="肉蛋豆"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
android:id="@+id/tvFoodName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2.5"
|
||||
android:layout_weight="2.1"
|
||||
android:text="菜品名称"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="26sp"
|
||||
@@ -23,7 +23,7 @@
|
||||
android:id="@+id/tvPriceNorm"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:layout_weight="1.6"
|
||||
android:text="规格"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="26sp"
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- 菜品名称列,权重2.5 -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2.1"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFoodName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="菜品名称"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="25sp"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center_vertical|start" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="档口"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="13sp"
|
||||
android:background="@drawable/bg_order_flag"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:paddingVertical="1dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 规格列,权重1.0 -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.6"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/tvPriceNorm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="规格"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="25sp"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center" />
|
||||
<TextView
|
||||
android:id="@+id/tvPriceFlag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="[大份]"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="15sp"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 重量列,权重1.0 -->
|
||||
<TextView
|
||||
android:id="@+id/tvWeight"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
tools:text="重量(克)"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="25sp"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center" />
|
||||
|
||||
<!-- 小计列,权重1.0 -->
|
||||
<TextView
|
||||
android:id="@+id/tvAmount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
tools:text="小计(元)"
|
||||
android:textColor="#FF889AC2"
|
||||
android:textSize="25sp"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:singleLine="true"
|
||||
android:gravity="center" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -2,6 +2,7 @@
|
||||
agp = "8.10.1"
|
||||
core = "3.4.1"
|
||||
androidCore = "3.3.0"
|
||||
eventbus = "3.2.0"
|
||||
glide = "4.16.0"
|
||||
kotlin = "2.0.21"
|
||||
coreKtx = "1.10.1"
|
||||
@@ -14,6 +15,9 @@ activity = "1.8.0"
|
||||
constraintlayout = "2.1.4"
|
||||
accompanistPermissions = "0.37.3"
|
||||
cameraCore = "1.4.1"
|
||||
objectboxVersion = "5.0.1"
|
||||
refreshLayoutKernel = "3.0.0-alpha"
|
||||
refreshHeaderClassics = "3.0.0-alpha"
|
||||
retrofit = "3.0.0"
|
||||
okhttp = "4.12.0"
|
||||
timber = "5.0.1"
|
||||
@@ -30,11 +34,13 @@ pytorch = "1.13.0"
|
||||
|
||||
recyclerview = "1.3.2"
|
||||
|
||||
#baseQuickAdapter = "4.1.2"
|
||||
baseQuickAdapter = "3.0.4"
|
||||
baseQuickAdapter4 = "4.1.2"
|
||||
|
||||
[libraries]
|
||||
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
||||
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||
eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" }
|
||||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
@@ -56,7 +62,10 @@ hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", ve
|
||||
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
|
||||
|
||||
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||
objectbox-android-objectbrowser = { module = "io.objectbox:objectbox-android-objectbrowser", version.ref = "objectboxVersion" }
|
||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
refresh-header-classics = { module = "io.github.scwang90:refresh-header-classics", version.ref = "refreshHeaderClassics" }
|
||||
refresh-layout-kernel = { module = "io.github.scwang90:refresh-layout-kernel", version.ref = "refreshLayoutKernel" }
|
||||
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
||||
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
|
||||
@@ -68,10 +77,12 @@ androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref
|
||||
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||
|
||||
#noinspection Aligned16KB
|
||||
pytorch-android = { group = "org.pytorch", name = "pytorch_android", version.ref = "pytorch" }
|
||||
pytorch-android-torchvision = { group = "org.pytorch", name = "pytorch_android_torchvision", version.ref = "pytorch" }
|
||||
|
||||
#base-quick-adapter-ktx = { module = "io.github.cymchad:BaseRecyclerViewAdapterHelper4", version.ref = "baseQuickAdapter" }
|
||||
#baseRecyclerViewAdapterHelper = { module = "com.github.CymChad:BaseRecyclerViewAdapterHelper", version.ref = "baseQuickAdapter" }
|
||||
baseRecyclerViewAdapterHelper4 = { module = "io.github.cymchad:BaseRecyclerViewAdapterHelper4", version.ref = "baseQuickAdapter4" }
|
||||
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user