refactor(ui): 移除设备配置页面并重构调料配置界面
- 移除 DeviceConfigActivity 页面及相关 AndroidManifest 注册 - 将调料配置从单页网格改为上下两层 RecyclerView 结构 - 上层使用 FlexboxLayoutManager 显示 22 格调料位 - 下层使用 GridLayoutManager 显示 18 格调料位 - 更新存储工具类 SpTool 中烹饪模式的访问方式 - 修改首页和初始化页面中烹饪模式的读取逻辑 - 更新 WebSocket 客户端连接逻辑中的重复连接处理
This commit is contained in:
@@ -93,8 +93,8 @@
|
|||||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||||
<activity android:name="com.shuwei.dish.match.ui.DeviceConfigActivity"
|
<!-- <activity android:name="com.shuwei.dish.match.ui.DeviceConfigActivity"-->
|
||||||
android:theme="@style/Theme.DishMatch.NoSplash" />
|
<!-- android:theme="@style/Theme.DishMatch.NoSplash" />-->
|
||||||
<activity android:name="com.shuwei.dish.match.ui.SettingActivity"
|
<activity android:name="com.shuwei.dish.match.ui.SettingActivity"
|
||||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ class ScaleWebSocketClient {
|
|||||||
*/
|
*/
|
||||||
fun connect(deviceId: String, host: String, port: Int) {
|
fun connect(deviceId: String, host: String, port: Int) {
|
||||||
removedDevices.remove(deviceId)
|
removedDevices.remove(deviceId)
|
||||||
|
// 取消旧 IP 的重连任务,防止 IP 变化时新旧任务并发竞争
|
||||||
|
reconnectTasks.remove(deviceId)?.cancel(false)
|
||||||
reconnectDelays[deviceId] = RECONNECT_BASE_MS
|
reconnectDelays[deviceId] = RECONNECT_BASE_MS
|
||||||
doConnect(deviceId, host, port)
|
doConnect(deviceId, host, port)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,347 +1,347 @@
|
|||||||
package com.shuwei.dish.match.ui
|
//package com.shuwei.dish.match.ui
|
||||||
|
//
|
||||||
import android.graphics.Typeface
|
//import android.graphics.Typeface
|
||||||
import android.os.Bundle
|
//import android.os.Bundle
|
||||||
import android.text.SpannableStringBuilder
|
//import android.text.SpannableStringBuilder
|
||||||
import android.text.style.AbsoluteSizeSpan
|
//import android.text.style.AbsoluteSizeSpan
|
||||||
import android.text.style.ForegroundColorSpan
|
//import android.text.style.ForegroundColorSpan
|
||||||
import android.text.style.LineHeightSpan
|
//import android.text.style.LineHeightSpan
|
||||||
import android.text.style.StyleSpan
|
//import android.text.style.StyleSpan
|
||||||
import android.util.Log
|
//import android.util.Log
|
||||||
import android.util.SparseArray
|
//import android.util.SparseArray
|
||||||
import android.widget.FrameLayout
|
//import android.widget.FrameLayout
|
||||||
import androidx.core.graphics.toColorInt
|
//import androidx.core.graphics.toColorInt
|
||||||
import androidx.core.view.forEach
|
//import androidx.core.view.forEach
|
||||||
import androidx.lifecycle.ViewModelProvider
|
//import androidx.lifecycle.ViewModelProvider
|
||||||
import com.shuwei.dish.match.base.BaseActivity
|
//import com.shuwei.dish.match.base.BaseActivity
|
||||||
import com.shuwei.dish.match.base.BaseApp
|
//import com.shuwei.dish.match.base.BaseApp
|
||||||
import com.shuwei.dish.match.db.AppRepository
|
//import com.shuwei.dish.match.db.AppRepository
|
||||||
import com.shuwei.dish.match.dialog.CommonDialog
|
//import com.shuwei.dish.match.dialog.CommonDialog
|
||||||
import com.shuwei.dish.match.entity.SeasoningEntity
|
//import com.shuwei.dish.match.entity.SeasoningEntity
|
||||||
import com.shuwei.dish.match.entity.ResetReasoningRecord
|
//import com.shuwei.dish.match.entity.ResetReasoningRecord
|
||||||
import com.shuwei.dish.match.utils.AddressUtil
|
//import com.shuwei.dish.match.utils.AddressUtil
|
||||||
import com.shuwei.dish.match.utils.JsonAssetsLoader
|
//import com.shuwei.dish.match.utils.JsonAssetsLoader
|
||||||
import com.shuwei.dish.match.utils.MultiClickDetector
|
//import com.shuwei.dish.match.utils.MultiClickDetector
|
||||||
import com.shuwei.dish.match.utils.WeightUtil
|
//import com.shuwei.dish.match.utils.WeightUtil
|
||||||
import com.shuwei.dish.match.utils.ext.appendText
|
//import com.shuwei.dish.match.utils.ext.appendText
|
||||||
import com.shuwei.dish.match.utils.ext.buildSpannableString
|
//import com.shuwei.dish.match.utils.ext.buildSpannableString
|
||||||
import com.shuwei.dish.match.utils.ext.dp
|
//import com.shuwei.dish.match.utils.ext.dp
|
||||||
import com.shuwei.dish.match.utils.ext.startActivity
|
//import com.shuwei.dish.match.utils.ext.startActivity
|
||||||
import com.shuwei.dish.match.utils.ext.toast
|
//import com.shuwei.dish.match.utils.ext.toast
|
||||||
import com.shuwei.dish.match.utils.ext.visible
|
//import com.shuwei.dish.match.utils.ext.visible
|
||||||
import com.shuwei.dish.match.viewmodel.AppViewModel
|
//import com.shuwei.dish.match.viewmodel.AppViewModel
|
||||||
import com.shuwei.dish.match.viewmodel.factory.AppFactory
|
//import com.shuwei.dish.match.viewmodel.factory.AppFactory
|
||||||
import com.shuwei.dish.match.adapter.TextCellAdapter
|
//import com.shuwei.dish.match.adapter.TextCellAdapter
|
||||||
import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding
|
//import com.shuwei.dish.match.databinding.ActivityDeviceConfigBinding
|
||||||
import com.shuwei.dish.match.dialog.SeasoningSearchDialog
|
//import com.shuwei.dish.match.dialog.SeasoningSearchDialog
|
||||||
import com.shuwei.dish.match.utils.SpTool
|
//import com.shuwei.dish.match.utils.SpTool
|
||||||
import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
//import com.shuwei.dish.match.utils.ext.clickWithDebounce
|
||||||
import com.shuwei.dish.match.utils.ext.gone
|
//import com.shuwei.dish.match.utils.ext.gone
|
||||||
import com.shuwei.dish.match.utils.ext.toJsonString
|
//import com.shuwei.dish.match.utils.ext.toJsonString
|
||||||
|
//
|
||||||
class DeviceConfigActivity : BaseActivity() {
|
//class DeviceConfigActivity : BaseActivity() {
|
||||||
|
//
|
||||||
companion object {
|
// companion object {
|
||||||
|
//
|
||||||
const val TAG = "DeviceConfigActivity"
|
// const val TAG = "DeviceConfigActivity"
|
||||||
|
//
|
||||||
const val COOK_MODE = "cookMode"
|
// const val COOK_MODE = "cookMode"
|
||||||
|
//
|
||||||
val modeList = listOf<ModeBean>(
|
// val modeList = listOf<ModeBean>(
|
||||||
ModeBean("制作模式", "菜品快速制作,记录熟重"),
|
// ModeBean("制作模式", "菜品快速制作,记录熟重"),
|
||||||
ModeBean("采样模式", "菜品快速制作,记录熟重"),
|
// ModeBean("采样模式", "菜品快速制作,记录熟重"),
|
||||||
ModeBean("品控模式", "菜品快速制作,记录熟重")
|
// ModeBean("品控模式", "菜品快速制作,记录熟重")
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
data class ModeBean(
|
// data class ModeBean(
|
||||||
var modeName: String,
|
// var modeName: String,
|
||||||
var modeDesc: String
|
// var modeDesc: String
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
private lateinit var binding: ActivityDeviceConfigBinding
|
// private lateinit var binding: ActivityDeviceConfigBinding
|
||||||
|
//
|
||||||
private lateinit var appViewModel: AppViewModel
|
// private lateinit var appViewModel: AppViewModel
|
||||||
|
//
|
||||||
private var cookMode: Int = 0
|
// private var cookMode: Int = 0
|
||||||
// private val weightArray = SparseIntArray()
|
//// private val weightArray = SparseIntArray()
|
||||||
private val weightArray = SparseArray<Double>()
|
// private val weightArray = SparseArray<Double>()
|
||||||
private val addressArray = AddressUtil.getWeighAddressArray()
|
// private val addressArray = AddressUtil.getWeighAddressArray()
|
||||||
|
//
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
// override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
// super.onCreate(savedInstanceState)
|
||||||
binding = ActivityDeviceConfigBinding.inflate(layoutInflater)
|
// binding = ActivityDeviceConfigBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
// setContentView(binding.root)
|
||||||
cookMode = intent.getIntExtra(COOK_MODE, 0)
|
// cookMode = intent.getIntExtra(COOK_MODE, 0)
|
||||||
initViewModel()
|
// initViewModel()
|
||||||
setHeaderBackground()
|
// setHeaderBackground()
|
||||||
setTitleBar(titleBarAction = {
|
// setTitleBar(titleBarAction = {
|
||||||
it.visible()
|
// it.visible()
|
||||||
}, titleAction = {
|
// }, titleAction = {
|
||||||
it.text = "设备配置"
|
// it.text = "设备配置"
|
||||||
}, rightIconActon = {
|
// }, rightIconActon = {
|
||||||
it.gone()
|
// it.gone()
|
||||||
// it.alpha = 0.0F
|
//// it.alpha = 0.0F
|
||||||
// it.setImageResource(R.drawable.ic_setting)
|
//// it.setImageResource(R.drawable.ic_setting)
|
||||||
// it.setOnClickListener {_->
|
//// it.setOnClickListener {_->
|
||||||
// detector.setOnDelayedMultiClickListener(it) {
|
//// detector.setOnDelayedMultiClickListener(it) {
|
||||||
// defaultDataSettingDialog()
|
//// defaultDataSettingDialog()
|
||||||
// }
|
//// }
|
||||||
|
//// }
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// loadQualitySpan(isEnable = false)
|
||||||
|
// when (cookMode) {
|
||||||
|
// 1 -> {
|
||||||
|
// binding.rbModeCook.isChecked = true
|
||||||
|
// binding.rbModeSampling.isChecked = false
|
||||||
|
// loadCookSpan(isClicked = true)
|
||||||
|
// loadSamplingSpan()
|
||||||
// }
|
// }
|
||||||
})
|
//
|
||||||
|
// 2 -> {
|
||||||
loadQualitySpan(isEnable = false)
|
// binding.rbModeCook.isChecked = false
|
||||||
when (cookMode) {
|
// binding.rbModeSampling.isChecked = true
|
||||||
1 -> {
|
// loadCookSpan()
|
||||||
binding.rbModeCook.isChecked = true
|
// loadSamplingSpan(isClicked = true)
|
||||||
binding.rbModeSampling.isChecked = false
|
// }
|
||||||
loadCookSpan(isClicked = true)
|
//
|
||||||
loadSamplingSpan()
|
// else -> {
|
||||||
}
|
// binding.rbModeCook.isChecked = true
|
||||||
|
// binding.rbModeSampling.isChecked = false
|
||||||
2 -> {
|
// loadCookSpan(isClicked = true)
|
||||||
binding.rbModeCook.isChecked = false
|
// loadSamplingSpan()
|
||||||
binding.rbModeSampling.isChecked = true
|
// }
|
||||||
loadCookSpan()
|
// }
|
||||||
loadSamplingSpan(isClicked = true)
|
//
|
||||||
}
|
// binding.rbModeCook.setOnClickListener {
|
||||||
|
// SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
|
||||||
else -> {
|
// binding.rbModeCook.isChecked = true
|
||||||
binding.rbModeCook.isChecked = true
|
// binding.rbModeSampling.isChecked = false
|
||||||
binding.rbModeSampling.isChecked = false
|
// loadCookSpan(isClicked = true)
|
||||||
loadCookSpan(isClicked = true)
|
// loadSamplingSpan()
|
||||||
loadSamplingSpan()
|
// startActivity<SelectDishActivity> {
|
||||||
}
|
// putExtra(SelectDishActivity.IS_CONFIG_PAGE, true)
|
||||||
}
|
// }
|
||||||
|
// finish()
|
||||||
binding.rbModeCook.setOnClickListener {
|
// }
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
|
// binding.rbModeSampling.setOnClickListener {
|
||||||
binding.rbModeCook.isChecked = true
|
// SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
|
||||||
binding.rbModeSampling.isChecked = false
|
// binding.rbModeCook.isChecked = false
|
||||||
loadCookSpan(isClicked = true)
|
// binding.rbModeSampling.isChecked = true
|
||||||
loadSamplingSpan()
|
// loadCookSpan()
|
||||||
startActivity<SelectDishActivity> {
|
// loadSamplingSpan(isClicked = true)
|
||||||
putExtra(SelectDishActivity.IS_CONFIG_PAGE, true)
|
// startActivity<SamplingListActivity> {
|
||||||
}
|
// putExtra(SamplingListActivity.IS_CONFIG_PAGE, true) }
|
||||||
finish()
|
// finish()
|
||||||
}
|
// }
|
||||||
binding.rbModeSampling.setOnClickListener {
|
// addWeighListener()
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
|
// addGridItemListener()
|
||||||
binding.rbModeCook.isChecked = false
|
// loadSeasoning()
|
||||||
binding.rbModeSampling.isChecked = true
|
// }
|
||||||
loadCookSpan()
|
//
|
||||||
loadSamplingSpan(isClicked = true)
|
// private fun addWeighListener() {
|
||||||
startActivity<SamplingListActivity> {
|
// WeightUtil.addWeightListener(
|
||||||
putExtra(SamplingListActivity.IS_CONFIG_PAGE, true) }
|
// weightKey = TAG,
|
||||||
finish()
|
// getWeight = { address, state, weight ->
|
||||||
}
|
// Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
|
||||||
addWeighListener()
|
// weightArray.put(address, weight)
|
||||||
addGridItemListener()
|
// val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
|
||||||
loadSeasoning()
|
// item?.let {
|
||||||
}
|
// it.useWeight = weight.toDouble()
|
||||||
|
// updateGridData(it)
|
||||||
private fun addWeighListener() {
|
// }
|
||||||
WeightUtil.addWeightListener(
|
// Log.d(TAG, "addWeighListener: update-----------------------")
|
||||||
weightKey = TAG,
|
// })
|
||||||
getWeight = { address, state, weight ->
|
// }
|
||||||
Log.d(TAG, "addWeighListener: address=$address,stat=$state,weight=$weight")
|
//
|
||||||
weightArray.put(address, weight)
|
// private var seasoningItems = mutableListOf<SeasoningEntity>()
|
||||||
val item = seasoningItems.firstOrNull { address == addressArray[it.sort] }
|
// private fun addGridItemListener() {
|
||||||
item?.let {
|
// binding.include.root.forEach { child ->
|
||||||
it.useWeight = weight.toDouble()
|
// child.clickWithDebounce {
|
||||||
updateGridData(it)
|
// val sort = child.tag.toString().toInt()
|
||||||
}
|
// val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
|
||||||
Log.d(TAG, "addWeighListener: update-----------------------")
|
// clickGridItem(sort, entity)
|
||||||
})
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
private var seasoningItems = mutableListOf<SeasoningEntity>()
|
//
|
||||||
private fun addGridItemListener() {
|
// val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
|
||||||
binding.include.root.forEach { child ->
|
//
|
||||||
child.clickWithDebounce {
|
// private fun defaultDataSettingDialog() {
|
||||||
val sort = child.tag.toString().toInt()
|
// CommonDialog(this)
|
||||||
val entity = seasoningItems.firstOrNull { it.sort == sort } ?: SeasoningEntity()
|
// .setTitle("温馨提示")
|
||||||
clickGridItem(sort, entity)
|
// .setContent("您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?")
|
||||||
}
|
// .setNegativeButton("取消")
|
||||||
}
|
// .setPositiveButton("确认") { resetList() }
|
||||||
}
|
// .setOnDismissCallback { hideStatusBar() }
|
||||||
|
// .show()
|
||||||
val detector = MultiClickDetector(targetCount = 10, intervalMs = 800)
|
// }
|
||||||
|
//
|
||||||
private fun defaultDataSettingDialog() {
|
// private fun resetList() {
|
||||||
CommonDialog(this)
|
// runCatching {
|
||||||
.setTitle("温馨提示")
|
// val record = JsonAssetsLoader.parseJsonFromAssets<ResetReasoningRecord>(
|
||||||
.setContent("您好,使用默认配置作为您的调料数据,则已有配置将被清除,确认吗?")
|
// this,
|
||||||
.setNegativeButton("取消")
|
// "default_seasoning_list.json"
|
||||||
.setPositiveButton("确认") { resetList() }
|
// )
|
||||||
.setOnDismissCallback { hideStatusBar() }
|
//// val weightArray = WeightUtil.weightArray
|
||||||
.show()
|
// appViewModel.clearAllSeasoning {
|
||||||
}
|
// record?.list?.forEach { entity ->
|
||||||
|
// entity.useWeight = weightArray[addressArray[entity.sort]].toDouble()
|
||||||
private fun resetList() {
|
// appViewModel.saveSeasoning(entity) {
|
||||||
runCatching {
|
// updateGridData(entity)
|
||||||
val record = JsonAssetsLoader.parseJsonFromAssets<ResetReasoningRecord>(
|
// }
|
||||||
this,
|
// }
|
||||||
"default_seasoning_list.json"
|
//// loadSeasoning()
|
||||||
)
|
// }
|
||||||
// val weightArray = WeightUtil.weightArray
|
// }.onFailure { it.printStackTrace() }
|
||||||
appViewModel.clearAllSeasoning {
|
// }
|
||||||
record?.list?.forEach { entity ->
|
//
|
||||||
entity.useWeight = weightArray[addressArray[entity.sort]].toDouble()
|
// private fun initViewModel() {
|
||||||
appViewModel.saveSeasoning(entity) {
|
// val db = BaseApp.instance!!.database
|
||||||
updateGridData(entity)
|
// val factory =
|
||||||
}
|
// AppFactory(AppRepository(db.appDao()))
|
||||||
}
|
// appViewModel =
|
||||||
// loadSeasoning()
|
// ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
}
|
// }
|
||||||
}.onFailure { it.printStackTrace() }
|
//
|
||||||
}
|
// private fun loadSeasoning() {
|
||||||
|
// appViewModel.loadSeasoning {
|
||||||
private fun initViewModel() {
|
// seasoningItems.clear()
|
||||||
val db = BaseApp.instance!!.database
|
// seasoningItems.addAll(it)
|
||||||
val factory =
|
// initConfigData()
|
||||||
AppFactory(AppRepository(db.appDao()))
|
// setGridData(seasoningItems)
|
||||||
appViewModel =
|
// }
|
||||||
ViewModelProvider(this, factory)[AppViewModel::class.java]
|
// }
|
||||||
}
|
//
|
||||||
|
// private fun initConfigData() {
|
||||||
private fun loadSeasoning() {
|
// repeat(12) { num ->
|
||||||
appViewModel.loadSeasoning {
|
// val firstOne = seasoningItems.firstOrNull { it.sort == num }
|
||||||
seasoningItems.clear()
|
// if (firstOne == null) {
|
||||||
seasoningItems.addAll(it)
|
// seasoningItems.add(SeasoningEntity().also { it.sort = num })
|
||||||
initConfigData()
|
// }
|
||||||
setGridData(seasoningItems)
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
|
// private fun setGridData(list: MutableList<SeasoningEntity>) {
|
||||||
private fun initConfigData() {
|
// Log.d(TAG, "setGridData: ${list.toJsonString()}")
|
||||||
repeat(12) { num ->
|
// val gridLayout = binding.include.root
|
||||||
val firstOne = seasoningItems.firstOrNull { it.sort == num }
|
// list.forEach { entity ->
|
||||||
if (firstOne == null) {
|
// val tag = entity.sort.toString()
|
||||||
seasoningItems.add(SeasoningEntity().also { it.sort = num })
|
// val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
||||||
}
|
// TextCellAdapter.loadLayout(frameLayout, entity)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun setGridData(list: MutableList<SeasoningEntity>) {
|
// private fun updateGridData(entity: SeasoningEntity) {
|
||||||
Log.d(TAG, "setGridData: ${list.toJsonString()}")
|
// val gridLayout = binding.include.root
|
||||||
val gridLayout = binding.include.root
|
// val tag = entity.sort.toString()
|
||||||
list.forEach { entity ->
|
// val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
||||||
val tag = entity.sort.toString()
|
// TextCellAdapter.loadLayout(frameLayout, entity)
|
||||||
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
// }
|
||||||
TextCellAdapter.loadLayout(frameLayout, entity)
|
//
|
||||||
}
|
// private fun clickGridItem(sort: Int, entity: SeasoningEntity) {
|
||||||
}
|
// val currentAddress = AddressUtil.getWeighAddressArray().get(sort)
|
||||||
|
//// val seasoningEntity = list.first{it.sort == sort}
|
||||||
private fun updateGridData(entity: SeasoningEntity) {
|
// SeasoningSearchDialog(
|
||||||
val gridLayout = binding.include.root
|
// activity = this,
|
||||||
val tag = entity.sort.toString()
|
// weighIndex = sort,
|
||||||
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
// weighAddress = currentAddress,
|
||||||
TextCellAdapter.loadLayout(frameLayout, entity)
|
// clickName = entity.goodsName
|
||||||
}
|
// ) { item ->
|
||||||
|
// syncItem(entity, item)
|
||||||
private fun clickGridItem(sort: Int, entity: SeasoningEntity) {
|
// //3-调料
|
||||||
val currentAddress = AddressUtil.getWeighAddressArray().get(sort)
|
// entity.materialType = 3
|
||||||
// val seasoningEntity = list.first{it.sort == sort}
|
// entity.sort = sort
|
||||||
SeasoningSearchDialog(
|
// saveSeasoning(entity) {
|
||||||
activity = this,
|
// val tag = sort.toString()
|
||||||
weighIndex = sort,
|
// val gridLayout = binding.include.root
|
||||||
weighAddress = currentAddress,
|
// val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
||||||
clickName = entity.goodsName
|
// TextCellAdapter.loadLayout(frameLayout, entity)
|
||||||
) { item ->
|
// }
|
||||||
syncItem(entity, item)
|
// }.show()
|
||||||
//3-调料
|
// }
|
||||||
entity.materialType = 3
|
//
|
||||||
entity.sort = sort
|
// private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) {
|
||||||
saveSeasoning(entity) {
|
// oldItem.run {
|
||||||
val tag = sort.toString()
|
// goodsId = newItem.goodsId
|
||||||
val gridLayout = binding.include.root
|
// goodsName = newItem.goodsName
|
||||||
val frameLayout = gridLayout.findViewWithTag<FrameLayout>(tag)
|
// goodsOrRelationCode = newItem.goodsOrRelationCode
|
||||||
TextCellAdapter.loadLayout(frameLayout, entity)
|
// relateionType = newItem.relateionType
|
||||||
}
|
// materialType = newItem.materialType
|
||||||
}.show()
|
// allEdible = newItem.allEdible
|
||||||
}
|
// useWeight = newItem.useWeight
|
||||||
|
// popularName = newItem.popularName
|
||||||
private fun syncItem(oldItem: SeasoningEntity, newItem: SeasoningEntity) {
|
// canteenId = newItem.canteenId
|
||||||
oldItem.run {
|
// relateionType_dictText = newItem.relateionType_dictText
|
||||||
goodsId = newItem.goodsId
|
//
|
||||||
goodsName = newItem.goodsName
|
// foodId = newItem.foodId
|
||||||
goodsOrRelationCode = newItem.goodsOrRelationCode
|
// sort = newItem.sort
|
||||||
relateionType = newItem.relateionType
|
// }
|
||||||
materialType = newItem.materialType
|
// }
|
||||||
allEdible = newItem.allEdible
|
//
|
||||||
useWeight = newItem.useWeight
|
// private fun loadQualitySpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
||||||
popularName = newItem.popularName
|
// binding.rbModeQuality.text =
|
||||||
canteenId = newItem.canteenId
|
// getModeTextSpan(
|
||||||
relateionType_dictText = newItem.relateionType_dictText
|
// topText = modeList[2].modeName,
|
||||||
|
// bottomText = modeList[2].modeDesc,
|
||||||
foodId = newItem.foodId
|
// topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
||||||
sort = newItem.sort
|
// bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
||||||
}
|
// )
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun loadQualitySpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
// private fun loadSamplingSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
||||||
binding.rbModeQuality.text =
|
// binding.rbModeSampling.text =
|
||||||
getModeTextSpan(
|
// getModeTextSpan(
|
||||||
topText = modeList[2].modeName,
|
// topText = modeList[1].modeName,
|
||||||
bottomText = modeList[2].modeDesc,
|
// bottomText = modeList[1].modeDesc,
|
||||||
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
// topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
||||||
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
// bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun loadSamplingSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
// private fun loadCookSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
||||||
binding.rbModeSampling.text =
|
// binding.rbModeCook.text =
|
||||||
getModeTextSpan(
|
// getModeTextSpan(
|
||||||
topText = modeList[1].modeName,
|
// topText = modeList[0].modeName,
|
||||||
bottomText = modeList[1].modeDesc,
|
// bottomText = modeList[0].modeDesc,
|
||||||
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
// topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
||||||
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
// bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun loadCookSpan(isClicked: Boolean = false, isEnable: Boolean = true) {
|
// private fun getModeTextSpan(
|
||||||
binding.rbModeCook.text =
|
// topText: String,
|
||||||
getModeTextSpan(
|
// topColor: String,
|
||||||
topText = modeList[0].modeName,
|
// bottomText: String,
|
||||||
bottomText = modeList[0].modeDesc,
|
// bottomColor: String
|
||||||
topColor = if (isEnable) if (isClicked) "#00BC71" else "#000000" else "#B4B4B4",
|
// ): SpannableStringBuilder {
|
||||||
bottomColor = if (isEnable) "#8B8B8B" else "#B4B4B4"
|
//
|
||||||
)
|
//
|
||||||
}
|
// return buildSpannableString {
|
||||||
|
// appendText(
|
||||||
private fun getModeTextSpan(
|
// topText,
|
||||||
topText: String,
|
// ForegroundColorSpan(topColor.toColorInt()),
|
||||||
topColor: String,
|
// StyleSpan(Typeface.BOLD),
|
||||||
bottomText: String,
|
// AbsoluteSizeSpan(36, true),
|
||||||
bottomColor: String
|
// LineHeightSpan { text, start, end, spanstartv, v, fm ->
|
||||||
): SpannableStringBuilder {
|
// fm.descent += 10.dp // 增加行间距
|
||||||
|
// }
|
||||||
|
// )
|
||||||
return buildSpannableString {
|
// append("\n")
|
||||||
appendText(
|
// appendText(
|
||||||
topText,
|
// bottomText,
|
||||||
ForegroundColorSpan(topColor.toColorInt()),
|
// ForegroundColorSpan(bottomColor.toColorInt()),
|
||||||
StyleSpan(Typeface.BOLD),
|
// AbsoluteSizeSpan(26, true)
|
||||||
AbsoluteSizeSpan(36, true),
|
// )
|
||||||
LineHeightSpan { text, start, end, spanstartv, v, fm ->
|
// }
|
||||||
fm.descent += 10.dp // 增加行间距
|
// }
|
||||||
}
|
//
|
||||||
)
|
// fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) {
|
||||||
append("\n")
|
// appViewModel.saveSeasoning(entity) {
|
||||||
appendText(
|
// action()
|
||||||
bottomText,
|
// toast("保存成功")
|
||||||
ForegroundColorSpan(bottomColor.toColorInt()),
|
// }
|
||||||
AbsoluteSizeSpan(26, true)
|
// }
|
||||||
)
|
//
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
fun saveSeasoning(entity: SeasoningEntity, action: () -> Unit = {}) {
|
|
||||||
appViewModel.saveSeasoning(entity) {
|
|
||||||
action()
|
|
||||||
toast("保存成功")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -107,7 +107,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
modeDesc = "菜品快速制作,记录熟重",
|
modeDesc = "菜品快速制作,记录熟重",
|
||||||
modeIconId = R.drawable.ic_mode_cook,
|
modeIconId = R.drawable.ic_mode_cook,
|
||||||
onClick = {
|
onClick = {
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
|
SpTool.cookMode = 0
|
||||||
startActivity<SelectDishActivity>()
|
startActivity<SelectDishActivity>()
|
||||||
finish()
|
finish()
|
||||||
})
|
})
|
||||||
@@ -118,7 +118,7 @@ class HomeActivity : BaseActivity() {
|
|||||||
modeDesc = "菜品快速制作,记录熟重",
|
modeDesc = "菜品快速制作,记录熟重",
|
||||||
modeIconId = R.drawable.ic_mode_sampling,
|
modeIconId = R.drawable.ic_mode_sampling,
|
||||||
onClick = {
|
onClick = {
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
|
SpTool.cookMode = 1
|
||||||
goSampling()
|
goSampling()
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -83,8 +83,7 @@ class InitActivity : BaseActivity() {
|
|||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
// 主设备:走原有路由逻辑
|
// 主设备:走原有路由逻辑
|
||||||
val launchPageType = SpTool.getInt(SpTool.LAUNCH_PAGE_TYPE, -1)
|
when (SpTool.cookMode) {
|
||||||
when (launchPageType) {
|
|
||||||
0 -> {
|
0 -> {
|
||||||
startActivity<SelectDishActivity>()
|
startActivity<SelectDishActivity>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ class SettingActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val fragmentList = mutableListOf<Fragment>().apply {
|
private val fragmentList = mutableListOf<Fragment>().apply {
|
||||||
add(DeviceConfigFragment.newInstance())
|
add(DeviceConfigFragment())
|
||||||
add(SeasoningConfigFragment())
|
add(SeasoningConfigFragment())
|
||||||
add(CollectFragment())
|
add(CollectFragment())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,21 +51,11 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "DeviceConfigFragment"
|
const val TAG = "DeviceConfigFragment"
|
||||||
const val COOK_MODE = "cookMode"
|
|
||||||
|
|
||||||
val modeList = listOf<ModeBean>(
|
val modeList = listOf<ModeBean>(
|
||||||
ModeBean("制作模式", "菜品快速制作,记录熟重"),
|
ModeBean("制作模式", "菜品快速制作,记录熟重"),
|
||||||
ModeBean("采样模式", "菜品快速制作,记录熟重"),
|
ModeBean("采样模式", "菜品快速制作,记录熟重"),
|
||||||
ModeBean("品控模式", "菜品快速制作,记录熟重")
|
ModeBean("品控模式", "菜品快速制作,记录熟重")
|
||||||
)
|
)
|
||||||
|
|
||||||
fun newInstance(cookMode: Int = 0): DeviceConfigFragment {
|
|
||||||
return DeviceConfigFragment().apply {
|
|
||||||
arguments = Bundle().apply {
|
|
||||||
putInt(COOK_MODE, cookMode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ModeBean(
|
data class ModeBean(
|
||||||
@@ -75,7 +65,6 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
|
|
||||||
// private lateinit var appViewModel: AppViewModel
|
// private lateinit var appViewModel: AppViewModel
|
||||||
|
|
||||||
private var cookMode: Int = 0
|
|
||||||
private val weightArray = SparseArray<Double>()
|
private val weightArray = SparseArray<Double>()
|
||||||
private val addressArray = AddressUtil.getWeighAddressArray()
|
private val addressArray = AddressUtil.getWeighAddressArray()
|
||||||
private var seasoningItems = mutableListOf<SeasoningEntity>()
|
private var seasoningItems = mutableListOf<SeasoningEntity>()
|
||||||
@@ -89,7 +78,6 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun initialize(){
|
override fun initialize(){
|
||||||
cookMode = arguments?.getInt(COOK_MODE, 0) ?: 0
|
|
||||||
initViewModel()
|
initViewModel()
|
||||||
initUI()
|
initUI()
|
||||||
// addWeighListener()
|
// addWeighListener()
|
||||||
@@ -111,15 +99,15 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
*/
|
*/
|
||||||
private fun initUI() {
|
private fun initUI() {
|
||||||
loadQualitySpan(isEnable = false)
|
loadQualitySpan(isEnable = false)
|
||||||
when (cookMode) {
|
when (SpTool.cookMode) {
|
||||||
1 -> {
|
0 -> {
|
||||||
binding.rbModeCook.isChecked = true
|
binding.rbModeCook.isChecked = true
|
||||||
binding.rbModeSampling.isChecked = false
|
binding.rbModeSampling.isChecked = false
|
||||||
loadCookSpan(isClicked = true)
|
loadCookSpan(isClicked = true)
|
||||||
loadSamplingSpan()
|
loadSamplingSpan()
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
1 -> {
|
||||||
binding.rbModeCook.isChecked = false
|
binding.rbModeCook.isChecked = false
|
||||||
binding.rbModeSampling.isChecked = true
|
binding.rbModeSampling.isChecked = true
|
||||||
loadCookSpan()
|
loadCookSpan()
|
||||||
@@ -135,7 +123,7 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.rbModeCook.setOnClickListener {
|
binding.rbModeCook.setOnClickListener {
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 0)
|
SpTool.cookMode = 0
|
||||||
binding.rbModeCook.isChecked = true
|
binding.rbModeCook.isChecked = true
|
||||||
binding.rbModeSampling.isChecked = false
|
binding.rbModeSampling.isChecked = false
|
||||||
loadCookSpan(isClicked = true)
|
loadCookSpan(isClicked = true)
|
||||||
@@ -146,7 +134,7 @@ class DeviceConfigFragment : BaseFragment<FragmentDeviceConfigBinding>() {
|
|||||||
activity?.finish()
|
activity?.finish()
|
||||||
}
|
}
|
||||||
binding.rbModeSampling.setOnClickListener {
|
binding.rbModeSampling.setOnClickListener {
|
||||||
SpTool.put(SpTool.LAUNCH_PAGE_TYPE, 1)
|
SpTool.cookMode = 1
|
||||||
binding.rbModeCook.isChecked = false
|
binding.rbModeCook.isChecked = false
|
||||||
binding.rbModeSampling.isChecked = true
|
binding.rbModeSampling.isChecked = true
|
||||||
loadCookSpan()
|
loadCookSpan()
|
||||||
|
|||||||
@@ -2,21 +2,86 @@ package com.shuwei.dish.match.ui.fragment
|
|||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import com.google.android.flexbox.AlignItems
|
||||||
|
import com.google.android.flexbox.FlexDirection
|
||||||
|
import com.google.android.flexbox.FlexWrap
|
||||||
|
import com.google.android.flexbox.FlexboxLayoutManager
|
||||||
|
import com.shuwei.dish.match.adapter.Seasoning18GridAdapter
|
||||||
|
import com.shuwei.dish.match.adapter.Seasoning22GridAdapter
|
||||||
import com.shuwei.dish.match.base.BaseFragment
|
import com.shuwei.dish.match.base.BaseFragment
|
||||||
import com.shuwei.dish.match.databinding.FragmentSeasoningConfigBinding
|
import com.shuwei.dish.match.databinding.FragmentSeasoningConfigBinding
|
||||||
import com.shuwei.dish.match.ui.SettingActivity
|
import com.shuwei.dish.match.ui.SettingActivity
|
||||||
|
import com.shuwei.dish.match.utils.ext.dp
|
||||||
|
|
||||||
class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
||||||
|
|
||||||
override fun inflateBinding(
|
override fun inflateBinding(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?
|
container: ViewGroup?
|
||||||
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
|
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
|
||||||
private lateinit var settingActivity: SettingActivity
|
private lateinit var settingActivity: SettingActivity
|
||||||
|
// private lateinit var appViewModel: AppViewModel
|
||||||
|
|
||||||
|
private val adapter22 by lazy { buildAdapter22() }
|
||||||
|
private val adapter18 by lazy { Seasoning18GridAdapter() }
|
||||||
|
|
||||||
override fun initialize() {
|
override fun initialize() {
|
||||||
settingActivity = activity as SettingActivity
|
settingActivity = activity as SettingActivity
|
||||||
|
// initViewModel()
|
||||||
|
setupRecyclerViews()
|
||||||
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /** 初始化 ViewModel */
|
||||||
|
// private fun initViewModel() {
|
||||||
|
// val factory = AppFactory(AppRepository(BaseApp.instance!!.database.appDao()))
|
||||||
|
// appViewModel = ViewModelProvider(this, factory)[AppViewModel::class.java]
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
/** 构建上层(22格)Adapter,需要先计算格子尺寸 */
|
||||||
|
private fun buildAdapter22(): Seasoning22GridAdapter {
|
||||||
|
val usable = resources.displayMetrics.widthPixels - 8 * 4.dp - 10.dp
|
||||||
|
val smallSize = usable / 9
|
||||||
|
val largeSize = (usable - smallSize * 6) / 2
|
||||||
|
return Seasoning22GridAdapter(largeSize, smallSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 配置两个 RecyclerView */
|
||||||
|
private fun setupRecyclerViews() {
|
||||||
|
// 上层:FlexboxLayoutManager,仿 MasterScaleActivity 中 Scale22VH 的布局方式
|
||||||
|
// rvTop 高度 = 小格子尺寸 * 3行 + 3 * 间距,与 Scale22VH 保持一致
|
||||||
|
val screenWidth = resources.displayMetrics.widthPixels
|
||||||
|
val usable = screenWidth - 8 * 4.dp - 10.dp
|
||||||
|
val smallSize = usable / 9
|
||||||
|
val rvTopHeight = smallSize * 3 + 3 * 4.dp
|
||||||
|
binding.rvTop.apply {
|
||||||
|
layoutParams = layoutParams.also { it.height = rvTopHeight }
|
||||||
|
layoutManager = FlexboxLayoutManager(requireContext()).apply {
|
||||||
|
flexDirection = FlexDirection.COLUMN
|
||||||
|
flexWrap = FlexWrap.WRAP
|
||||||
|
alignItems = AlignItems.FLEX_START
|
||||||
|
}
|
||||||
|
itemAnimator = null
|
||||||
|
adapter = adapter22
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下层:GridLayoutManager 6列,仿 Scale18VH
|
||||||
|
binding.rvBottom.apply {
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), 6)
|
||||||
|
itemAnimator = null
|
||||||
|
adapter = adapter18
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 加载默认空数据,使两个列表完整展示所有格子 */
|
||||||
|
private fun loadData() {
|
||||||
|
adapter22.update(emptyList())
|
||||||
|
adapter18.update(emptyList())
|
||||||
|
// appViewModel.loadSeasoning { list ->
|
||||||
|
// adapter22.update(list ?: emptyList())
|
||||||
|
// adapter18.update(list ?: emptyList())
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,4 +31,10 @@ object SpTool {
|
|||||||
fun getBoolean(key: String, defValue: Boolean = false): Boolean {
|
fun getBoolean(key: String, defValue: Boolean = false): Boolean {
|
||||||
return pref.getBoolean(key, defValue)
|
return pref.getBoolean(key, defValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cookMode: Int
|
||||||
|
get() = getInt(LAUNCH_PAGE_TYPE, -1)
|
||||||
|
set(value) {
|
||||||
|
put(LAUNCH_PAGE_TYPE, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,42 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
android:background="@color/bg_color">
|
android:background="@color/bg_color">
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="上层"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/home_title"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="6dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvTop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:overScrollMode="never" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="下层"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/home_title"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginBottom="6dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvBottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:overScrollMode="never" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user