接口联调

This commit is contained in:
2025-08-08 13:34:18 +08:00
parent eb66c2d2ff
commit 65199f4c70
32 changed files with 689 additions and 115 deletions
+10 -5
View File
@@ -10,7 +10,7 @@ android {
defaultConfig { defaultConfig {
applicationId = "com.shuwei.intelligent.shelves" applicationId = "com.shuwei.intelligent.shelves"
minSdk = 25 minSdk = 25
//noinspection ExpiredTargetSdkVersion //noinspection EditedTargetSdkVersion,ExpiredTargetSdkVersion
targetSdk = 30 targetSdk = 30
versionCode = 1 versionCode = 1
versionName = "1.0" versionName = "1.0"
@@ -41,6 +41,7 @@ android {
ndkVersion = "29.0.13846066" ndkVersion = "29.0.13846066"
} }
//noinspection UseTomlInstead
dependencies { dependencies {
//implementation(fileTree("libs") { include("*.jar", "*.aar") }) //implementation(fileTree("libs") { include("*.jar", "*.aar") })
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
@@ -54,16 +55,20 @@ dependencies {
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.2") implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.2")
implementation("com.squareup.okhttp3:okhttp:4.9.1")
implementation("com.google.code.gson:gson:2.10.1")
implementation("io.github.jeadyx:kmp-serialport:1.0.0") implementation("io.github.jeadyx:kmp-serialport:1.0.0")
// 基础依赖包,必须要依赖 // 基础依赖包,必须要依赖
implementation("com.geyifeng.immersionbar:immersionbar:3.2.2") implementation("com.geyifeng.immersionbar:immersionbar:3.2.2")
// kotlin扩展(可选) // kotlin扩展(可选)
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2") implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
implementation("com.squareup.okhttp3:okhttp:4.9.1")
implementation("com.google.code.gson:gson:2.10.1")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2")
// implementation("io.github.jeremyliao:live-event-bus-x:1.8.0") // implementation("io.github.jeremyliao:live-event-bus-x:1.8.0")
// implementation("com.hoho:android-usb-serial:1.3.0") // implementation("com.hoho:android-usb-serial:1.3.0")
// implementation("io.github.jeadyx:jserialport:1.5") // implementation("io.github.jeadyx:jserialport:1.5")
+8 -3
View File
@@ -2,9 +2,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USB_PERMISSION" /> <uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application <application
android:name=".App" android:name=".App"
@@ -13,9 +16,11 @@
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.IntelligentShelves"> android:theme="@style/Theme.IntelligentShelves"
android:usesCleartextTraffic="true">
<activity <activity
android:name=".HomeActivity" android:name=".HomeActivity"
android:exported="true" android:exported="true"
@@ -8,6 +8,11 @@ import android.app.Application
*/ */
class App : Application() { class App : Application() {
//暂时固定,后续从接口获取
var accessToken: String = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjYW50ZWVuSWQiOiIiLCJ0eXBlIjoiNiIsInVzZXJJZCI6IjE2NzgyMjY1NTI5MzE1NDkxODYifQ.CQmbELpqT6QzvVCgCeirwvSvPp8Mhft_h6b1Af574Co"
var androidId:String = ""
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
app = this app = this
@@ -5,25 +5,37 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.provider.Settings
import android.util.Log import android.util.Log
import android.util.SparseArray
import android.util.SparseIntArray import android.util.SparseIntArray
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter4.util.setOnDebouncedItemClick import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.shuwei.intelligent.shelves.adapter.ShelfAdapter import com.shuwei.intelligent.shelves.adapter.ShelfAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding import com.shuwei.intelligent.shelves.databinding.ActivityHomeBinding
import com.shuwei.intelligent.shelves.model.ShelfModel import com.shuwei.intelligent.shelves.model.ShelfModel
import com.shuwei.intelligent.shelves.model.ShelfResult
import com.shuwei.intelligent.shelves.net.Loading
import com.shuwei.intelligent.shelves.net.NetViewModel
import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.serial.SerialPortManager
import com.shuwei.intelligent.shelves.task.TaskManager import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.UIUtils import com.shuwei.intelligent.shelves.utils.UIUtils
import com.shuwei.intelligent.shelves.utils.f2C import com.shuwei.intelligent.shelves.utils.f2C
import com.shuwei.intelligent.shelves.utils.hexToDec import com.shuwei.intelligent.shelves.utils.hexToDec
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import kotlin.getValue
class HomeActivity : BaseActivity() { class HomeActivity : BaseActivity() {
@@ -52,13 +64,15 @@ class HomeActivity : BaseActivity() {
private lateinit var binding: ActivityHomeBinding private lateinit var binding: ActivityHomeBinding
@SuppressLint("NotifyDataSetChanged") private val viewModel: NetViewModel by viewModels()
@SuppressLint("NotifyDataSetChanged", "HardwareIds")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityHomeBinding.inflate(layoutInflater) binding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
updateLeftStatus("1-1冷藏柜 0°C / 0%") updateLeftStatus("1-1冷藏柜 -°C / -%")
initList() initList()
initRecyclerView() initRecyclerView()
@@ -77,18 +91,95 @@ class HomeActivity : BaseActivity() {
//SerialPortManager.send(DEVICE_INFO_CMD) //SerialPortManager.send(DEVICE_INFO_CMD)
} }
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.getShelfListUiState.collect { state ->
when (state) {
is UiState.Loading -> showProgress()
is UiState.Success<*> -> updateUI(state.data)
is UiState.Error -> showError(state.msg)
else -> {}
}
}
}
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.getAccessTokenUiState.collect { state ->
when (state) {
is UiState.Loading -> {}
is UiState.Success<*> -> getTokenSuccess(state.data)
is UiState.Error -> UIUtils.toast(state.msg)
else -> {}
}
}
}
} }
TaskManager.startTask() TaskManager.startTask()
App.get().androidId = "53babf69-0d2f-3875-a649-f2e12f80ad4c1"
// Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
Log.d(TAG, "onCreate: androidId=${App.get().androidId}")
val swDpValue = resources?.configuration?.smallestScreenWidthDp
Log.d(TAG, "onCreate: swDpValue=$swDpValue")
viewModel.getShelfList(deviceId = App.get().androidId)
viewModel.getAccessToken(App.get().androidId)
// repeat(100) { // repeat(100) {
// lifecycleScope.launch { // lifecycleScope.launch {
// var data = "D6DADEDB01010C6102000000000000010000000500008000000000060000000500000004000080060000000100000010190080701800800000000000000000000000000000000000000000000000005037414645333633333334333731373056322E313069FFFF" // val data = "D6DADEDB01010C6102000000000000010000000500008000000000060000000500000004000080060000000100000010190080701800800000000000000000000000000000000000000000000000005037414645333633333334333731373056322E313069FFFF"
// receiveSerialPortData(data) // receiveSerialPortData(data)
// delay(100) // delay(500)
// } // }
// } // }
} }
private fun getTokenSuccess(data: RespData<*>) {
Log.d(TAG, "getTokenSuccess: $data")
data.result?.let {
//App.get().accessToken = it.toString()
}
}
private fun showProgress() {
Loading.show(this)
}
@SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) {
Loading.dismiss()
if (data.result !is ShelfResult) {
UIUtils.toast("数据错误")
return
}
val tempList = data.result.containerGoodsList
if (tempList.isNullOrEmpty()) {
UIUtils.toast("数据为空")
return
}
if (tempList.size < 10) {
UIUtils.toast("数据错误")
return
}
list.clear()
val subList01 = tempList.subList(0, 5)
val subList02 = tempList.subList(5, 10)
repeat(5) { index ->
list.add(subList01[index])
list.add(subList02[index])
}
shelfAdapter.notifyDataSetChanged()
}
private fun showError(message: String) {
Loading.dismiss()
UIUtils.toast(message)
}
private val serialReader by lazy { StringBuilder() } private val serialReader by lazy { StringBuilder() }
private fun receiveSerialPortData(srcData: String) { private fun receiveSerialPortData(srcData: String) {
@@ -103,7 +194,7 @@ class HomeActivity : BaseActivity() {
serialReader.clear() serialReader.clear()
serialReader.append(srcData) serialReader.append(srcData)
return return
} else if (srcData.contains(FOOTER).not()){ } else if (srcData.contains(FOOTER).not()) {
serialReader.append(srcData) serialReader.append(srcData)
return return
} else { } else {
@@ -151,9 +242,9 @@ class HomeActivity : BaseActivity() {
val temperatureHex = data.substring(temperatureStartIndex, temperatureEndIndex) val temperatureHex = data.substring(temperatureStartIndex, temperatureEndIndex)
val temperature = hexToDec(temperatureHex) val temperature = hexToDec(temperatureHex)
val tempC = f2C(temperature.toDouble()) val tempC = f2C(temperature.toDouble())
val showTemp = "%.1f".format(tempC.toDouble()) val showTemp = "%.1f".format(tempC)
val percent = 10 * list.count { it.foodName.isNullOrBlank().not() } val percent = 10 * list.count { it.goodsName.isNullOrBlank().not() }
updateLeftStatus("1-1冷藏柜 ${showTemp}°C / ${percent}%") updateLeftStatus("1-1冷藏柜 ${showTemp}°C / ${percent}%")
}.onFailure { }.onFailure {
@@ -175,18 +266,17 @@ class HomeActivity : BaseActivity() {
if (weightHex.first() in '8'..'F') { if (weightHex.first() in '8'..'F') {
//负数 //负数
val weightHex2 = "0${weightHex.substring(1)}" val weightHex2 = "0${weightHex.substring(1)}"
realWeight = -1*weightHex2.toInt() realWeight = -1 * weightHex2.toInt()
//-1*hexToDec(weightHex2)
} else { } else {
//整数 //整数
realWeight = weightHex.toInt() realWeight = weightHex.toInt()
//hexToDec(weightHex)
} }
weightArray.put(index, realWeight) val realWeightDouble = realWeight / 1000.0
weightArray.put(index, realWeightDouble)
if (index <= 10) { if (index <= 10) {
list.first { it.shelfNo == index }.let { list.firstOrNull { it.deviceNo == index }?.let {
it.foodWeight = realWeight it.weight = realWeightDouble
} }
shelfAdapter.notifyItemChanged(index) shelfAdapter.notifyItemChanged(index)
} }
@@ -216,7 +306,7 @@ class HomeActivity : BaseActivity() {
// sendBroadcast(intent) // sendBroadcast(intent)
} }
private val weightArray by lazy { SparseIntArray() } private val weightArray by lazy { SparseArray<Double?>() }
private var clickIndex = 0 private var clickIndex = 0
override fun onDestroy() { override fun onDestroy() {
@@ -234,13 +324,13 @@ class HomeActivity : BaseActivity() {
setOnDebouncedItemClick { adapter, view, position -> setOnDebouncedItemClick { adapter, view, position ->
this@HomeActivity.clickIndex = position this@HomeActivity.clickIndex = position
lifecycleScope.launch { lifecycleScope.launch {
val openCmd = if (list[position].shelfNo in 1..5) val openCmd = if (list[position].deviceNo in 1..5)
LEFT_SHELF_OPEN_CMD LEFT_SHELF_OPEN_CMD
else else
RIGHT_SHELF_OPEN_CMD RIGHT_SHELF_OPEN_CMD
val openState = SerialPortManager.send(openCmd) val openState = SerialPortManager.send(openCmd)
if (openState.not()) { if (openState.not()) {
UIUtils.toast("${list[position].foodName}柜门开启失败") UIUtils.toast("${list[position].goodsName}柜门开启失败")
return@launch return@launch
} }
launch(Intent(this@HomeActivity, ShelfActivity::class.java).also { launch(Intent(this@HomeActivity, ShelfActivity::class.java).also {
@@ -250,9 +340,9 @@ class HomeActivity : BaseActivity() {
val model = val model =
getSerializableExtra(ShelfActivity.SHELF_MODEL) as ShelfModel getSerializableExtra(ShelfActivity.SHELF_MODEL) as ShelfModel
list[position].apply { list[position].apply {
foodName = model.foodName goodsName = model.goodsName
foodWeight = model.foodWeight weight = model.weight
storeDate = model.storeDate createTime = model.createTime
} }
notifyItemChanged(position) notifyItemChanged(position)
} }
@@ -271,18 +361,18 @@ class HomeActivity : BaseActivity() {
} }
private fun initList() { private fun initList() {
// val list: MutableList<ShelfModel> = mutableListOf() //// val list: MutableList<ShelfModel> = mutableListOf()
list.add(ShelfModel(shelfNo = 1)) // list.add(ShelfModel(deviceNo = 1))
list.add(ShelfModel(shelfNo = 6)) // list.add(ShelfModel(deviceNo = 6))
list.add(ShelfModel(shelfNo = 2)) // list.add(ShelfModel(deviceNo = 2))
list.add(ShelfModel(shelfNo = 7)) // list.add(ShelfModel(deviceNo = 7))
list.add(ShelfModel(shelfNo = 3)) // list.add(ShelfModel(deviceNo = 3))
list.add(ShelfModel(shelfNo = 8)) // list.add(ShelfModel(deviceNo = 8))
list.add(ShelfModel(shelfNo = 4)) // list.add(ShelfModel(deviceNo = 4))
list.add(ShelfModel(shelfNo = 9)) // list.add(ShelfModel(deviceNo = 9))
list.add(ShelfModel(shelfNo = 5)) // list.add(ShelfModel(deviceNo = 5))
list.add(ShelfModel(shelfNo = 10)) // list.add(ShelfModel(deviceNo = 10))
// viewModel.updateItems(list) //// viewModel.updateItems(list)
} }
private val MM_DD_EEEE__HH_MM_SS = "MM月dd日 EEEE HH:mm:ss" private val MM_DD_EEEE__HH_MM_SS = "MM月dd日 EEEE HH:mm:ss"
@@ -5,34 +5,39 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter4.util.setOnDebouncedItemClick import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.shuwei.intelligent.shelves.HomeActivity.Companion.ACTIVE_CMD
import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD
import com.shuwei.intelligent.shelves.utils.ext.addOnActionSearchListener
import com.shuwei.intelligent.shelves.utils.ext.clickWithDebounce
import com.shuwei.intelligent.shelves.utils.ext.toast
import com.shuwei.intelligent.shelves.adapter.SearchAdapter import com.shuwei.intelligent.shelves.adapter.SearchAdapter
import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.base.BaseActivity
import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding
import com.shuwei.intelligent.shelves.model.SearchModel import com.shuwei.intelligent.shelves.model.GoodsModel
import com.shuwei.intelligent.shelves.model.GoodsRecord
import com.shuwei.intelligent.shelves.model.ShelfModel import com.shuwei.intelligent.shelves.model.ShelfModel
import com.shuwei.intelligent.shelves.net.Loading
import com.shuwei.intelligent.shelves.net.NetViewModel
import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.serial.SerialPortManager
import com.shuwei.intelligent.shelves.utils.DateTimeUtil import com.shuwei.intelligent.shelves.utils.DateTimeUtil
import com.shuwei.intelligent.shelves.utils.KeyboardUtil import com.shuwei.intelligent.shelves.utils.KeyboardUtil
import com.shuwei.intelligent.shelves.utils.decToHex import com.shuwei.intelligent.shelves.utils.UIUtils
import com.shuwei.intelligent.shelves.utils.ext.addOnActionSearchListener
import com.shuwei.intelligent.shelves.utils.ext.clickWithDebounce
import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import com.shuwei.intelligent.shelves.utils.ext.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import kotlin.random.Random
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
class ShelfActivity : BaseActivity() { class ShelfActivity : BaseActivity() {
@@ -53,6 +58,9 @@ class ShelfActivity : BaseActivity() {
private var realWeight: Int = 0 private var realWeight: Int = 0
private val viewModel: NetViewModel by viewModels()
@SuppressLint("UnspecifiedRegisterReceiverFlag") @SuppressLint("UnspecifiedRegisterReceiverFlag")
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -64,8 +72,8 @@ class ShelfActivity : BaseActivity() {
shelfModel?.let { shelfModel?.let {
binding.tvShelfName.text = it.shelfName binding.tvShelfName.text = it.shelfName
binding.tvFoodName.text = if (it.foodName.isNullOrBlank()) "-" else it.foodName binding.tvFoodName.text = if (it.goodsName.isNullOrBlank()) "-" else it.goodsName
realWeight = it.foodWeight ?: 0 realWeight = ((it.weight ?: 0.0) * 1000).toInt()
binding.tvFoodWeight.text = "${realWeight}" binding.tvFoodWeight.text = "${realWeight}"
} }
@@ -77,7 +85,11 @@ class ShelfActivity : BaseActivity() {
toast(hint.toString()) toast(hint.toString())
return@addOnActionSearchListener return@addOnActionSearchListener
} }
loadSearchData() // loadSearchData()
viewModel.getGoodsList(
canteenId = "1599670511042785282",
goodsName = text.toString().trim()
)
KeyboardUtil.hideKeyboard(context, this) KeyboardUtil.hideKeyboard(context, this)
} }
} }
@@ -89,9 +101,9 @@ class ShelfActivity : BaseActivity() {
} }
val data = ShelfModel( val data = ShelfModel(
shelfName = shelfModel?.shelfName, shelfName = shelfModel?.shelfName,
foodName = list[clickIndex].foodName, goodsName = list[clickIndex].goodsName,
foodWeight = realWeight, weight = realWeight / 1000.0,
storeDate = DateTimeUtil.formatDateTime(dateTime = Date()) createTime = DateTimeUtil.formatDateTime(dateTime = Date())
) )
val intent = Intent().apply { val intent = Intent().apply {
putExtra(SHELF_MODEL, data) putExtra(SHELF_MODEL, data)
@@ -104,7 +116,7 @@ class ShelfActivity : BaseActivity() {
} }
binding.btnClearZero.setOnClickListener { v -> binding.btnClearZero.setOnClickListener { v ->
lifecycleScope.launch { lifecycleScope.launch {
val shelfNo = shelfModel?.shelfNo ?: 0 val shelfNo = shelfModel?.deviceNo ?: 0
val hex = shelfNo.toString(16).padStart(2, '0').uppercase() val hex = shelfNo.toString(16).padStart(2, '0').uppercase()
Log.d(TAG, "onCreate: hex=$hex") Log.d(TAG, "onCreate: hex=$hex")
val zeroClearingCmd = val zeroClearingCmd =
@@ -117,9 +129,51 @@ class ShelfActivity : BaseActivity() {
lifecycleScope.launch { lifecycleScope.launch {
SerialPortManager.send(DEVICE_INFO_CMD) SerialPortManager.send(DEVICE_INFO_CMD)
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.getGoodsListUiState.collect { state ->
when (state) {
is UiState.Loading -> showProgress()
is UiState.Success<*> -> updateUI(state.data)
is UiState.Error -> showError(state.msg)
else -> {}
}
}
}
} }
registerReceiver(receiver, IntentFilter(RECEIVER_DEVICE_INFO)) registerReceiver(receiver, IntentFilter(RECEIVER_DEVICE_INFO))
viewModel.getGoodsList(
canteenId = "1599670511042785282"
)
}
private fun showProgress() {
Loading.show(this)
}
@SuppressLint("NotifyDataSetChanged")
private fun updateUI(data: RespData<*>) {
Loading.dismiss()
Log.d(TAG, "updateUI: ${data.toJsonString()}")
if (data.result !is GoodsRecord) {
UIUtils.toast("数据错误")
return
}
if (data.result.records.isNullOrEmpty()) {
UIUtils.toast("数据错误")
return
}
list.clear()
list.addAll(data.result.records)
searchAdapter.notifyDataSetChanged()
}
private fun showError(message: String) {
Loading.dismiss()
UIUtils.toast(message)
} }
private val receiver = object : BroadcastReceiver() { private val receiver = object : BroadcastReceiver() {
@@ -127,7 +181,8 @@ class ShelfActivity : BaseActivity() {
intent?.let { intent?.let {
val data = it.getStringExtra(RECEIVER_DEVICE_INFO) val data = it.getStringExtra(RECEIVER_DEVICE_INFO)
Log.d(TAG, "onReceive: $data") Log.d(TAG, "onReceive: $data")
realWeight = it.getIntExtra(SHELF_WEIGHT, 0) val weight = it.getDoubleExtra(SHELF_WEIGHT, 0.0)
realWeight = (weight * 1000).toInt()
binding.tvFoodWeight.text = "${realWeight}" binding.tvFoodWeight.text = "${realWeight}"
} }
} }
@@ -142,28 +197,28 @@ class ShelfActivity : BaseActivity() {
// realWeight = Random.nextInt(1, 5001) // realWeight = Random.nextInt(1, 5001)
// } // }
private fun loadSearchData() { // private fun loadSearchData() {
list.add(SearchModel(foodId = 1000, foodName = "菲律宾乳猪五花肉")) // list.add(SearchModel(foodId = 1000, foodName = "菲律宾乳猪五花肉"))
list.add(SearchModel(foodId = 1001, foodName = "金针菇")) // list.add(SearchModel(foodId = 1001, foodName = "金针菇"))
list.add(SearchModel(foodId = 1002, foodName = "大菠菜")) // list.add(SearchModel(foodId = 1002, foodName = "大菠菜"))
list.add(SearchModel(foodId = 1003, foodName = "清远麻鸡块")) // list.add(SearchModel(foodId = 1003, foodName = "清远麻鸡块"))
list.add(SearchModel(foodId = 1004, foodName = "普罗旺斯番茄")) // list.add(SearchModel(foodId = 1004, foodName = "普罗旺斯番茄"))
list.add(SearchModel(foodId = 1005, foodName = "长条茄子")) // list.add(SearchModel(foodId = 1005, foodName = "长条茄子"))
list.add(SearchModel(foodId = 1006, foodName = "得莫利鱼")) // list.add(SearchModel(foodId = 1006, foodName = "得莫利鱼"))
list.add(SearchModel(foodId = 1007, foodName = "土豆丝")) // list.add(SearchModel(foodId = 1007, foodName = "土豆丝"))
list.add(SearchModel(foodId = 1008, foodName = "辣椒炒肉")) // list.add(SearchModel(foodId = 1008, foodName = "辣椒炒肉"))
list.add(SearchModel(foodId = 1009, foodName = "雪菜烧豆腐")) // list.add(SearchModel(foodId = 1009, foodName = "雪菜烧豆腐"))
list.add(SearchModel(foodId = 1010, foodName = "冬虫夏草炝拌芥兰苗")) // list.add(SearchModel(foodId = 1010, foodName = "冬虫夏草炝拌芥兰苗"))
list.add( // list.add(
SearchModel( // SearchModel(
foodId = 1011, // foodId = 1011,
foodName = "蘑菇玉米山药莲藕胡萝卜红枣莲子枸杞清炖排骨汤" // foodName = "蘑菇玉米山药莲藕胡萝卜红枣莲子枸杞清炖排骨汤"
) // )
) // )
searchAdapter.notifyDataSetChanged() // searchAdapter.notifyDataSetChanged()
} // }
private val list: MutableList<SearchModel> = mutableListOf() private val list: MutableList<GoodsModel> = mutableListOf()
private val searchAdapter by lazy { private val searchAdapter by lazy {
SearchAdapter(list).apply { SearchAdapter(list).apply {
setOnDebouncedItemClick { adapter, v, position -> setOnDebouncedItemClick { adapter, v, position ->
@@ -171,7 +226,7 @@ class ShelfActivity : BaseActivity() {
list.forEach { it.isClicked = false } list.forEach { it.isClicked = false }
list[position].isClicked = true list[position].isClicked = true
notifyDataSetChanged() notifyDataSetChanged()
binding.tvFoodName.text = list[position].foodName binding.tvFoodName.text = list[position].goodsName
KeyboardUtil.hideKeyboard(v.context, v) KeyboardUtil.hideKeyboard(v.context, v)
} }
} }
@@ -11,10 +11,10 @@ import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.shuwei.intelligent.shelves.R import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.databinding.ListItemSearchBinding import com.shuwei.intelligent.shelves.databinding.ListItemSearchBinding
import com.shuwei.intelligent.shelves.model.SearchModel import com.shuwei.intelligent.shelves.model.GoodsModel
class SearchAdapter(list: MutableList<SearchModel>) : class SearchAdapter(list: MutableList<GoodsModel>) :
BaseQuickAdapter<SearchModel, SearchAdapter.VH>(list) { BaseQuickAdapter<GoodsModel, SearchAdapter.VH>(list) {
inner class VH(var binding: ListItemSearchBinding) : QuickViewHolder(binding.root) inner class VH(var binding: ListItemSearchBinding) : QuickViewHolder(binding.root)
@@ -24,10 +24,10 @@ class SearchAdapter(list: MutableList<SearchModel>) :
return VH(binding) return VH(binding)
} }
override fun onBindViewHolder(holder: VH, position: Int, item: SearchModel?) { override fun onBindViewHolder(holder: VH, position: Int, item: GoodsModel?) {
val binding = holder.binding val binding = holder.binding
binding.btnFoodName.run { binding.btnFoodName.run {
text = " ${item!!.foodName}" text = " ${item!!.goodsName}"
setTextColor( setTextColor(
getColor(if (item.isClicked) R.color.shelf_name_blue else R.color.black999) getColor(if (item.isClicked) R.color.shelf_name_blue else R.color.black999)
) )
@@ -23,17 +23,17 @@ class ShelfAdapter(list: MutableList<ShelfModel>) :
} }
override fun onBindViewHolder(holder: VH, position: Int, item: ShelfModel?) { override fun onBindViewHolder(holder: VH, position: Int, item: ShelfModel?) {
val shelfNo = item!!.shelfNo val shelfNo = item!!.deviceNo
item.shelfName = "货架-${if (shelfNo < 10) "0${shelfNo}" else "$shelfNo" }" item.shelfName = "货架-${if (shelfNo < 10) "0${shelfNo}" else "$shelfNo" }"
val weight = item.foodWeight ?: 0 val weight = item.weight ?: 0.toDouble()
val binding = holder.binding val binding = holder.binding
binding.tvFoodWeight.run { binding.tvFoodWeight.run {
setTextColor(getColor(R.color.food_weight_orange)) setTextColor(getColor(R.color.food_weight_orange))
val showWeight = if(weight == 0) "0" else "%.3f".format(weight/1000F) val showWeight = if(weight == 0.toDouble()) "0" else "%.3f".format(weight)
text = "${showWeight}千克" text = "${showWeight}千克"
} }
//val isBlankShelf = weight <= 0 //val isBlankShelf = weight <= 0
val isBlankShelf = item.foodName.isNullOrBlank() val isBlankShelf = item.goodsName.isNullOrBlank()
if (isBlankShelf) { if (isBlankShelf) {
binding.layoutCard.setCardBackgroundColor(getColor(R.color.bg_card_blue)) binding.layoutCard.setCardBackgroundColor(getColor(R.color.bg_card_blue))
binding.tvShelfName.run { binding.tvShelfName.run {
@@ -61,7 +61,7 @@ class ShelfAdapter(list: MutableList<ShelfModel>) :
} }
binding.tvFoodName.run { binding.tvFoodName.run {
setTextColor(getColor(R.color.food_name_black)) setTextColor(getColor(R.color.food_name_black))
text = item.foodName text = item.goodsName
} }
// binding.tvFoodWeight.run { // binding.tvFoodWeight.run {
// setTextColor(getColor(R.color.food_weight_orange)) // setTextColor(getColor(R.color.food_weight_orange))
@@ -70,7 +70,7 @@ class ShelfAdapter(list: MutableList<ShelfModel>) :
// } // }
binding.tvStoreDate.run { binding.tvStoreDate.run {
setTextColor(getColor(R.color.black999)) setTextColor(getColor(R.color.black999))
text = item.storeDate text = item.createTime
} }
} }
@@ -2,8 +2,8 @@ package com.shuwei.intelligent.shelves.model
import java.io.Serializable import java.io.Serializable
data class SearchModel( data class GoodsModel(
var foodId: Int? = null, var goodsId: String? = null,
var foodName: String? = null, var goodsName: String? = null,
var isClicked: Boolean = false var isClicked: Boolean = false
) : Serializable ) : Serializable
@@ -0,0 +1,8 @@
package com.shuwei.intelligent.shelves.model
data class GoodsRecord(
val total: Int = 0,
val size: Int = 0,
val page: Int = 0,
val records: MutableList<GoodsModel>? = null
)
@@ -0,0 +1,9 @@
package com.shuwei.intelligent.shelves.model
class ShelfBody {
var deviceId: String = ""
var canteenId: String = ""
var goodsList: List<ShelfModel>? = null
}
@@ -3,9 +3,11 @@ package com.shuwei.intelligent.shelves.model
import java.io.Serializable import java.io.Serializable
data class ShelfModel( data class ShelfModel(
var shelfNo: Int = 0, var id: String? = null,
var deviceNo: Int = 0,
var shelfName: String? = null, var shelfName: String? = null,
var foodName: String? = null, var goodsId: Int = 0,
var foodWeight: Int? = null, var goodsName: String? = null,
var storeDate: String? = null var weight: Double? = null,
var createTime: String? = null
) : Serializable ) : Serializable
@@ -0,0 +1,7 @@
package com.shuwei.intelligent.shelves.model
data class ShelfResult(
val canteenId: String = "",
val canteenName: String = "",
val containerGoodsList: List<ShelfModel>? = null
)
@@ -0,0 +1,33 @@
package com.shuwei.intelligent.shelves.net
import com.shuwei.intelligent.shelves.model.GoodsRecord
import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.model.ShelfResult
import retrofit2.http.Body
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
interface ApiService {
@GET(UrlConfig.GET_ACCESS_TOKEN)
suspend fun getAccessToken(@Query("qrcodeId") qrcodeId: String): RespData<String?>
@GET(UrlConfig.GET_SHELF_LIST)
suspend fun getShelfList(@Query("deviceId") deviceId: String): RespData<ShelfResult>
@GET(UrlConfig.GET_GOODS_LIST)
suspend fun getGoodsList(
@Query("canteenId") canteenId: String = "0",
@Query("goodsName") goodsName: String? = null,
@Query("pageNo") pageNo: Int = 1,
@Query("pageSize") pageSize: Int = 50,
): RespData<GoodsRecord>
@FormUrlEncoded
@POST(UrlConfig.SAVE_SHELF_GOODS_LIST)
suspend fun saveShelfGoodsList(@Body body: ShelfBody): RespData<Any?>
}
@@ -0,0 +1,89 @@
package com.shuwei.intelligent.shelves.net
import android.annotation.SuppressLint
import android.util.Log
import com.shuwei.intelligent.shelves.App
import okhttp3.Call
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
import javax.net.ssl.*
import java.security.SecureRandom
import java.security.cert.X509Certificate
import kotlin.apply
val apiService: ApiService = Retrofit.Builder()
.baseUrl(UrlConfig.BASE_URL)
.client(HttpManager.instance.client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
class HttpManager private constructor() {
val client: OkHttpClient by lazy {
OkHttpClient.Builder()
.apply {
connectTimeout(15, TimeUnit.SECONDS)
readTimeout(30, TimeUnit.SECONDS)
writeTimeout(15, TimeUnit.SECONDS)
sslSocketFactory(createSSLSocketFactory(), TrustAllCerts())
hostnameVerifier { _, _ -> true }
addInterceptor(LoggingInterceptor())
addInterceptor { chain ->
val request = chain.request().newBuilder()
.header("x-access-token", App.get().accessToken)
.build()
chain.proceed(request)
}
}
.build()
}
companion object {
val instance by lazy { HttpManager() }
}
// fun newCall(request: Request): Call = client.newCall(request)
inner class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
// 打印请求日志
Log.d("OkHttp", "--> ${request.method},${request.url}")
val response = chain.proceed(request)
// 打印响应日志
Log.d("OkHttp", "<-- ${response.code},${response.request.url}")
return response
}
}
// 信任所有证书的TrustManager实现
@SuppressLint("CustomX509TrustManager")
class TrustAllCerts : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
}
@SuppressLint("TrustAllX509TrustManager")
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
}
override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
}
// 创建信任所有证书的SSLSocketFactory
fun createSSLSocketFactory(): SSLSocketFactory {
val sslContext = SSLContext.getInstance("TLS").apply {
init(null, arrayOf(TrustAllCerts()), SecureRandom())
}
return sslContext.socketFactory
}
}
@@ -0,0 +1,62 @@
package com.shuwei.intelligent.shelves.net
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.WindowManager
import androidx.core.graphics.drawable.toDrawable
import com.shuwei.intelligent.shelves.R
import com.shuwei.intelligent.shelves.databinding.DialogLoadingBinding
import kotlin.let
import kotlin.run
object Loading {
private var dialog: LoadingDialog? = null
fun show(context: Context) {
if (dialog?.isShowing == true) {
dialog?.dismiss()
}
if (dialog == null) {
dialog = LoadingDialog(context)
}
dialog?.show()
}
fun dismiss() {
dialog?.let {
if (it.isShowing) {
it.dismiss()
}
}
dialog = null
}
}
class LoadingDialog(
context: Context,
message: String = "加载中……",
private var onDismiss: () -> Unit = {}
) : Dialog(context, R.style.LoadingDialog) {
init {
val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
binding.tvMessage.text = message
setContentView(binding.root)
setCancelable(true)
window?.run {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
);
}
setOnDismissListener {
onDismiss()
}
}
}
@@ -0,0 +1,109 @@
package com.shuwei.intelligent.shelves.net
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.net.HttpManager.Companion.instance
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class NetViewModel : ViewModel() {
// val apiService: ApiService = HttpManager.instance.apiService
// val apiService: ApiService = Retrofit.Builder()
// .baseUrl(UrlConfig.BASE_URL)
// .client(HttpManager.instance.client)
// .addConverterFactory(GsonConverterFactory.create())
// .build()
// .create(ApiService::class.java)
private val _getShelfListUiState = MutableStateFlow<UiState>(UiState.Loading)
val getShelfListUiState: StateFlow<UiState> = _getShelfListUiState
private val _saveShelfGoodsListUiState = MutableStateFlow<UiState>(UiState.Loading)
val saveShelfGoodsListUiState: StateFlow<UiState> = _saveShelfGoodsListUiState
private val _getGoodsListUiState = MutableStateFlow<UiState>(UiState.Loading)
val getGoodsListUiState: StateFlow<UiState> = _getGoodsListUiState
private val _getAccessTokenUiState = MutableStateFlow<UiState>(UiState.Loading)
val getAccessTokenUiState: StateFlow<UiState> = _getAccessTokenUiState
fun getAccessToken(deviceId: String) {
viewModelScope.launch {
_getAccessTokenUiState.value = UiState.Loading
runCatching {
val response = apiService.getAccessToken(deviceId)
if (response.success) {
_getAccessTokenUiState.value = UiState.Success(response)
} else {
_getAccessTokenUiState.value = UiState.Error(response.message ?: "请求失败")
}
}.onFailure {
_getAccessTokenUiState.value = UiState.Error(it.message ?: "请求异常")
}
}
}
fun getShelfList(deviceId: String) {
viewModelScope.launch {
_getShelfListUiState.value = UiState.Loading
runCatching {
val response = apiService.getShelfList(deviceId)
if (response.success) {
_getShelfListUiState.value = UiState.Success(response)
} else {
_getShelfListUiState.value = UiState.Error(response.message ?: "请求失败")
}
}.onFailure {
_getShelfListUiState.value = UiState.Error(it.message ?: "请求异常")
}
}
}
fun saveShelfGoodsList(body: ShelfBody) {
viewModelScope.launch {
_saveShelfGoodsListUiState.value = UiState.Loading
runCatching {
val response = apiService.saveShelfGoodsList(body)
if (response.success) {
_saveShelfGoodsListUiState.value = UiState.Success(response)
} else {
_saveShelfGoodsListUiState.value = UiState.Error(response.message ?: "请求失败")
}
}.onFailure {
_saveShelfGoodsListUiState.value = UiState.Error(it.message ?: "请求异常")
}
}
}
fun getGoodsList(
canteenId: String = "",
goodsName: String = "",
pageNo: Int = 1,
pageSize: Int = 50,
) {
viewModelScope.launch {
_getGoodsListUiState.value = UiState.Loading
runCatching {
val response = apiService.getGoodsList(
canteenId = canteenId,
goodsName = goodsName,
pageNo = pageNo,
pageSize = pageSize
)
if (response.success) {
_getGoodsListUiState.value = UiState.Success(response)
} else {
_getGoodsListUiState.value = UiState.Error(response.message ?: "请求失败")
}
}.onFailure {
_getGoodsListUiState.value = UiState.Error(it.message ?: "请求异常")
}
}
}
}
@@ -0,0 +1,8 @@
package com.shuwei.intelligent.shelves.net
data class RespData<T>(
val success: Boolean = false,
val message: String? = null,
val code: Int = 0,
val result: T? = null
)
@@ -0,0 +1,7 @@
package com.shuwei.intelligent.shelves.net
sealed class UiState {
object Loading : UiState()
data class Success<T>(val data: RespData<T>) : UiState()
data class Error(val msg: String) : UiState()
}
@@ -0,0 +1,12 @@
package com.shuwei.intelligent.shelves.net
object UrlConfig {
const val BASE_URL = "http://192.168.1.7:9002"
const val GET_ACCESS_TOKEN = "/restaurant/equipment/stEquipment/getEquipmentToken"
const val GET_SHELF_LIST = "/inventory/smartShelves/app/getShelvesListByDeviceId"
const val GET_GOODS_LIST = "/inventory/smartShelves/app/getGoodsPageList"
const val SAVE_SHELF_GOODS_LIST = "/inventory/smartShelves/app/saveShelvesGoodsList"
}
@@ -5,6 +5,9 @@ import android.util.Log
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.shuwei.intelligent.shelves.HomeActivity import com.shuwei.intelligent.shelves.HomeActivity
import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.net.HttpManager
import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.utils.ext.toJsonString import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -34,6 +37,14 @@ class SyncTask(appContext: Context, workerParams: WorkerParameters) :
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val list = HomeActivity.list val list = HomeActivity.list
Log.d(TAG, "performSync: list:${list.toJsonString()}") Log.d(TAG, "performSync: list:${list.toJsonString()}")
val submitList = list.sortedBy { it.deviceNo }
val body = ShelfBody().also {
it.deviceId = ""
it.canteenId = ""
it.goodsList = submitList
}
val resp = apiService.saveShelfGoodsList(body)
Log.d(TAG, "performSync: resp:${resp.toJsonString()}")
} }
} }
@@ -1,19 +0,0 @@
//package com.shuwei.intelligent.shelves.viewmodel
//
//import androidx.lifecycle.LiveData
//import androidx.lifecycle.MutableLiveData
//import androidx.lifecycle.ViewModel
//import com.shuwei.intelligent.shelves.model.ShelfModel
//
//class ShelfDataViewModel : ViewModel() {
//
// private val _shelfItems = MutableLiveData<MutableList<ShelfModel>>()
// val shelfItems: LiveData<MutableList<ShelfModel>> = _shelfItems
//
// fun updateItems(newItems: MutableList<ShelfModel>) {
// _shelfItems.value = newItems
// }
//
// fun getCurrentItems(): MutableList<ShelfModel> = _shelfItems.value ?: mutableListOf()
//
//}
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#90000000"/>
<corners android:radius="5dp"/>
</shape>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingTop="5dp"
android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:background="@drawable/shape_dialog_small"
tools:ignore="MissingDefaultResource">
<ProgressBar
android:layout_width="26dp"
android:layout_height="26dp"
android:indeterminateTint="@color/white_f6" />
<TextView
android:id="@+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="加载中……"
android:textColor="@color/white_f6"
android:textSize="14sp"
tools:ignore="HardcodedText" />
</LinearLayout>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:background="@drawable/shape_dialog"
tools:ignore="MissingDefaultResource">
<ProgressBar
android:layout_width="60dp"
android:layout_height="60dp"
android:indeterminateTint="@color/white_f6" />
<TextView
android:id="@+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="加载中……"
android:textColor="@color/white_f6"
android:textSize="26sp"
tools:ignore="HardcodedText" />
</LinearLayout>
@@ -34,6 +34,8 @@
android:insetTop="0dp" android:insetTop="0dp"
android:insetBottom="0dp" android:insetBottom="0dp"
android:maxLines="1" android:maxLines="1"
app:paddingStart="5dp"
app:paddingEnd="5dp"
android:insetRight="0dp" android:insetRight="0dp"
android:insetLeft="0dp" android:insetLeft="0dp"
android:paddingHorizontal="8dp" android:paddingHorizontal="8dp"
+4
View File
@@ -13,4 +13,8 @@
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item> <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
</style> </style>
<style name="LoadingDialog" parent="Theme.AppCompat.Dialog">
<item name="android:windowIsFloating">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
</resources> </resources>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.1.7</domain>
</domain-config>
</network-security-config>