refactor: 统一时钟管理并优化状态栏显示逻辑
- 在 BaseActivity 中实现统一的时钟管理机制,避免各子类重复实现 - LogActivity 和 ShelfActivity 覆写 onClockTick() 自定义状态栏显示 - HomeActivity 移除重复的时间更新逻辑,启用右侧状态栏菜单 - 提取协议常量到 ProtocolConstants,提高代码可维护性 - 优化开锁逻辑判断,改为基于 deviceId 的动态判断 - 新增右侧状态栏弹出菜单布局文件 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
3e5c7c6caa
commit
133f309d4b
@@ -43,18 +43,16 @@ import com.shuwei.intelligent.shelves.utils.ext.toast
|
||||
import com.shuwei.intelligent.shelves.utils.ext.visible
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class HomeActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
private const val MM_DD_EEEE__HH_MM_SS = "MM月dd日 EEEE HH:mm:ss"
|
||||
}
|
||||
companion object {}
|
||||
|
||||
override val enableRightStatusMenu: Boolean = true
|
||||
|
||||
// 货架列表数据
|
||||
private val list: MutableList<ShelfModel> = mutableListOf()
|
||||
@@ -68,8 +66,8 @@ class HomeActivity : BaseActivity() {
|
||||
// 当前湿度
|
||||
private var showHumidity = "0"
|
||||
|
||||
// 是否在点击货架时发送开锁指令;有门锁的部署点(如1楼餐厅)为 true,无门锁的部署点(如401室)为 false
|
||||
private var isNeedOpenLock = true
|
||||
// 仅特定 deviceId 的部署点需要发送开锁指令
|
||||
private fun isNeedOpenLock() = App.deviceId == "4787e213-90ab-3e32-88e0-ac271a937751"
|
||||
|
||||
private var deviceName = ""
|
||||
|
||||
@@ -304,7 +302,7 @@ class HomeActivity : BaseActivity() {
|
||||
noDataWarningDialog?.dismiss()
|
||||
noDataWarningDialog = null
|
||||
|
||||
SerialPortManager.close()
|
||||
runBlocking { SerialPortManager.close() }
|
||||
saveTaskJob?.cancel()
|
||||
overdueTaskJob?.cancel()
|
||||
EventBus.getDefault().unregister(this)
|
||||
@@ -325,7 +323,7 @@ class HomeActivity : BaseActivity() {
|
||||
private fun onShelfItemClicked(position: Int) {
|
||||
shelfIndex = position
|
||||
lifecycleScope.launch {
|
||||
if (isNeedOpenLock) {
|
||||
if (isNeedOpenLock()) {
|
||||
val openCmd = if (list[position].deviceNo in 1..5)
|
||||
LEFT_SHELF_OPEN_CMD
|
||||
else
|
||||
@@ -374,31 +372,17 @@ class HomeActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private val dateTimeFormatter by lazy { SimpleDateFormat(MM_DD_EEEE__HH_MM_SS, Locale.CHINA) }
|
||||
|
||||
private fun updateDateTime() {
|
||||
updateRightStatus(dateTimeFormatter.format(Date()))
|
||||
}
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val updateTask = object : Runnable {
|
||||
override fun run() {
|
||||
updateDateTime()
|
||||
handler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
hideStatusBar()
|
||||
handler.post(updateTask)
|
||||
// 启动无数据看门狗(每30秒检查一次)
|
||||
handler.postDelayed(noDataWatchdogTask, 30 * 1000L)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
handler.removeCallbacks(updateTask)
|
||||
// 停止无数据看门狗
|
||||
handler.removeCallbacks(noDataWatchdogTask)
|
||||
}
|
||||
|
||||
@@ -1,28 +1,53 @@
|
||||
package com.shuwei.intelligent.shelves.activity
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.widget.TextView
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.shuwei.intelligent.shelves.adapter.LogAdapter
|
||||
import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||
import com.shuwei.intelligent.shelves.databinding.ActivityLogListBinding
|
||||
import com.shuwei.intelligent.shelves.dialog.CommonDialog
|
||||
import com.shuwei.intelligent.shelves.utils.ext.copyTextToClipboard
|
||||
import com.shuwei.intelligent.shelves.utils.ext.dp
|
||||
import com.shuwei.intelligent.shelves.utils.ext.gone
|
||||
import com.shuwei.intelligent.shelves.utils.ext.startActivity
|
||||
import com.shuwei.intelligent.shelves.utils.ext.toast
|
||||
import com.shuwei.intelligent.shelves.serial.ProtocolConstants
|
||||
import com.shuwei.intelligent.shelves.utils.ext.visible
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class LogActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
const val IS_LOG_DIR = "isLogDir"
|
||||
const val LOG_DATE = "logDate"
|
||||
const val YYYY_MM_DD__EEEE_HH_MM_SS = "yyyy年MM月dd日 EEEE***HH:mm:ss"
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆写时钟回调:左侧状态栏显示年月日星期,右侧状态栏显示时分秒
|
||||
*/
|
||||
override fun onClockTick() {
|
||||
val sdf = SimpleDateFormat(YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA)
|
||||
val arr = sdf.format(Date()).split("***")
|
||||
updateLeftStatus(arr[0])
|
||||
updateRightStatus(arr[1])
|
||||
}
|
||||
|
||||
private lateinit var binding:ActivityLogListBinding
|
||||
private var isLogDir = false
|
||||
private var logDate = ""
|
||||
private val logList = mutableListOf<String>()
|
||||
private val originalLogList = mutableListOf<String>() // 原始日志备份
|
||||
private val logAdapter by lazy {
|
||||
LogAdapter(logList).apply {
|
||||
setOnItemClickListener { _, _, position ->
|
||||
@@ -62,24 +87,20 @@ class LogActivity : BaseActivity() {
|
||||
logAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
if (isLogDir) {
|
||||
logList.addAll(fileLogger.getLogFiles())
|
||||
} else {
|
||||
logList.addAll(fileLogger.readLogsByName(logDate))
|
||||
}
|
||||
|
||||
binding.rvLogList.let {
|
||||
it.layoutManager = LinearLayoutManager(this)
|
||||
it.adapter = logAdapter
|
||||
}
|
||||
|
||||
setupSearch()
|
||||
setupJumpButton()
|
||||
|
||||
binding.btnFind.run {
|
||||
if (isLogDir) gone() else visible()
|
||||
}
|
||||
binding.btnFind.setOnClickListener {
|
||||
if (isLogDir) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
val list = logList.filter { it.contains("${HomeActivity.HEADER}1001") }
|
||||
if (isLogDir) return@setOnClickListener
|
||||
val list = logList.filter { it.contains("${ProtocolConstants.HEADER}${ProtocolConstants.CMD_TEMP_REPORT}") }
|
||||
if (list.isEmpty()) {
|
||||
toast("未找到到1001指令")
|
||||
return@setOnClickListener
|
||||
@@ -88,6 +109,95 @@ class LogActivity : BaseActivity() {
|
||||
logList.addAll(list)
|
||||
logAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// 后台加载日志数据
|
||||
lifecycleScope.launch {
|
||||
binding.progressBar.visible()
|
||||
val data = withContext(Dispatchers.IO) {
|
||||
if (isLogDir) fileLogger.getLogFiles()
|
||||
else fileLogger.readLogsByName(logDate)
|
||||
}
|
||||
logList.addAll(data)
|
||||
originalLogList.addAll(data)
|
||||
logAdapter.notifyDataSetChanged()
|
||||
binding.progressBar.gone()
|
||||
setupTimeNavigation()
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索功能
|
||||
private fun setupSearch() {
|
||||
binding.etSearch.addTextChangedListener(afterTextChanged = { s ->
|
||||
val keyword = s?.toString() ?: ""
|
||||
logList.clear()
|
||||
logList.addAll(if (keyword.isEmpty()) originalLogList else originalLogList.filter { it.contains(keyword, ignoreCase = true) })
|
||||
logAdapter.notifyDataSetChanged()
|
||||
})
|
||||
}
|
||||
|
||||
// 快速跳转功能
|
||||
private fun setupJumpButton() {
|
||||
var isAtTop = true
|
||||
binding.fabJump.setOnClickListener {
|
||||
if (isAtTop) {
|
||||
binding.rvLogList.scrollToPosition(logList.size - 1)
|
||||
} else {
|
||||
binding.rvLogList.scrollToPosition(0)
|
||||
}
|
||||
isAtTop = !isAtTop
|
||||
}
|
||||
}
|
||||
|
||||
// 时间导航功能
|
||||
private fun setupTimeNavigation() {
|
||||
if (isLogDir) {
|
||||
binding.hsvTimeNav.gone()
|
||||
return
|
||||
}
|
||||
|
||||
val timeMap = mutableMapOf<String, Int>()
|
||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
|
||||
|
||||
originalLogList.forEachIndexed { index, log ->
|
||||
val timeStr = log.substringAfter("[").substringBefore("]")
|
||||
try {
|
||||
val date = dateFormat.parse(timeStr)
|
||||
date?.let {
|
||||
val hourKey = SimpleDateFormat("HH:00", Locale.getDefault()).format(it)
|
||||
if (!timeMap.containsKey(hourKey)) {
|
||||
timeMap[hourKey] = index
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// 忽略解析失败的日志
|
||||
}
|
||||
}
|
||||
|
||||
if (timeMap.isEmpty()) {
|
||||
binding.hsvTimeNav.gone()
|
||||
return
|
||||
}
|
||||
|
||||
timeMap.toSortedMap().forEach { (hour, position) ->
|
||||
val btn = TextView(this).apply {
|
||||
text = hour
|
||||
textSize = 14f
|
||||
setTextColor(Color.BLACK)
|
||||
setPadding(12.dp, 8.dp, 12.dp, 8.dp)
|
||||
gravity = Gravity.CENTER
|
||||
setBackgroundColor(Color.parseColor("#E0E0E0"))
|
||||
setOnClickListener {
|
||||
binding.rvLogList.scrollToPosition(position)
|
||||
}
|
||||
}
|
||||
val params = android.widget.LinearLayout.LayoutParams(
|
||||
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
android.widget.LinearLayout.LayoutParams.MATCH_PARENT
|
||||
).apply {
|
||||
marginEnd = 8.dp
|
||||
}
|
||||
binding.llTimeNav.addView(btn, params)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package com.shuwei.intelligent.shelves.activity
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.widget.LinearLayout
|
||||
import androidx.activity.viewModels
|
||||
@@ -18,7 +16,7 @@ import com.chad.library.adapter4.util.setOnDebouncedItemClick
|
||||
import com.scwang.smart.refresh.layout.constant.RefreshState
|
||||
import com.shuwei.intelligent.shelves.App
|
||||
import com.shuwei.intelligent.shelves.R
|
||||
import com.shuwei.intelligent.shelves.activity.HomeActivity.Companion.DEVICE_INFO_CMD
|
||||
import com.shuwei.intelligent.shelves.serial.ProtocolConstants
|
||||
import com.shuwei.intelligent.shelves.adapter.SearchAdapter
|
||||
import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||
import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding
|
||||
@@ -148,7 +146,7 @@ class ShelfActivity : BaseActivity() {
|
||||
//binding.tvFoodWeight.text = "0克"
|
||||
EventBus.getDefault().post(ClearShelfEvent(shelfModel!!.deviceNo, tempWeight))
|
||||
}
|
||||
sendCmd(DEVICE_INFO_CMD)
|
||||
sendCmd(ProtocolConstants.DEVICE_INFO_CMD)
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
viewModel.getGoodsListUiState.collect { state ->
|
||||
@@ -305,31 +303,23 @@ class ShelfActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateDateTime() {
|
||||
/**
|
||||
* 覆写时钟回调:左侧状态栏显示年月日星期,右侧状态栏显示时分秒
|
||||
*/
|
||||
override fun onClockTick() {
|
||||
val sdf = SimpleDateFormat(YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA)
|
||||
val dateTime = sdf.format(Date())
|
||||
val arr = dateTime.split("***")
|
||||
val arr = sdf.format(Date()).split("***")
|
||||
updateLeftStatus(arr[0])
|
||||
updateRightStatus(arr[1])
|
||||
}
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val updateTask = object : Runnable {
|
||||
override fun run() {
|
||||
updateDateTime()
|
||||
handler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
hideStatusBar()
|
||||
handler.post(updateTask)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
handler.removeCallbacks(updateTask)
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@@ -371,17 +361,17 @@ class ShelfActivity : BaseActivity() {
|
||||
val shelfNo = shelfModel?.deviceNo ?: 0
|
||||
val hex = shelfNo.toString(16).padStart(2, '0').uppercase()
|
||||
Log.d(TAG, "onCreate: hex=$hex")
|
||||
val zeroClearingCmd = "${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}"
|
||||
val zeroClearingCmd = "${ProtocolConstants.HEADER}0401${hex}${ProtocolConstants.FOOTER}"
|
||||
log("编号${shelfNo}货架执行清零指令:${zeroClearingCmd}")
|
||||
sendCmd(zeroClearingCmd)
|
||||
sendCmd(
|
||||
if (shelfNo in 1..5) HomeActivity.LEFT_SHELF_OPEN_CMD else HomeActivity.RIGHT_SHELF_OPEN_CMD
|
||||
if (shelfNo in 1..5) ProtocolConstants.LEFT_SHELF_OPEN_CMD else ProtocolConstants.RIGHT_SHELF_OPEN_CMD
|
||||
)
|
||||
//清零
|
||||
realWeight = 0
|
||||
// binding.tvFoodWeight.text = "${realWeight}克"
|
||||
|
||||
sendCmd(DEVICE_INFO_CMD)
|
||||
sendCmd(ProtocolConstants.DEVICE_INFO_CMD)
|
||||
startTime = System.currentTimeMillis()
|
||||
Loading.show(this@ShelfActivity)
|
||||
// window.decorView.postDelayed({ Loading.dismiss() }, 5000)
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.shuwei.intelligent.shelves.serial.ProtocolConstants.LIGHT_OPEN
|
||||
import com.shuwei.intelligent.shelves.serial.SerialPortManager
|
||||
import com.shuwei.intelligent.shelves.utils.FileLogger
|
||||
import com.shuwei.intelligent.shelves.utils.ext.clickWithDebounce
|
||||
import com.shuwei.intelligent.shelves.utils.ext.dp
|
||||
import com.shuwei.intelligent.shelves.utils.ext.startActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -29,6 +30,9 @@ import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import com.shuwei.intelligent.shelves.utils.ext.setOnDoubleClickListener
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
open class BaseActivity : AppCompatActivity() {
|
||||
@@ -67,10 +71,13 @@ open class BaseActivity : AppCompatActivity() {
|
||||
finish()
|
||||
}
|
||||
binding.tvRightStatus.setOnDoubleClickListener {
|
||||
showRightStatusPopup(binding.tvRightStatus)
|
||||
if (enableRightStatusMenu) showRightStatusPopup(binding.tvRightStatus)
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否允许右侧状态栏双击弹出菜单,默认关闭,仅 HomeActivity 开启 */
|
||||
protected open val enableRightStatusMenu: Boolean = false
|
||||
|
||||
fun hideStatusBar() {}
|
||||
|
||||
fun statusBarDarkFont() {
|
||||
@@ -107,6 +114,26 @@ open class BaseActivity : AppCompatActivity() {
|
||||
onUserInactive()
|
||||
}
|
||||
|
||||
// ---- 右侧状态栏时钟 ----
|
||||
// 默认时间格式:月日星期 时:分:秒
|
||||
private val CLOCK_FORMAT = "MM月dd日 EEEE HH:mm:ss"
|
||||
private val clockFormatter by lazy { SimpleDateFormat(CLOCK_FORMAT, Locale.CHINA) }
|
||||
|
||||
/**
|
||||
* 每秒时钟回调,默认将当前时间显示在右侧状态栏。
|
||||
* 子类可覆写以自定义格式或同时更新左侧状态栏。
|
||||
*/
|
||||
open fun onClockTick() {
|
||||
updateRightStatus(clockFormatter.format(Date()))
|
||||
}
|
||||
|
||||
private val clockTask = object : Runnable {
|
||||
override fun run() {
|
||||
onClockTick()
|
||||
mHandler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户超时无操作时回调,默认空实现,子类按需覆写
|
||||
*/
|
||||
@@ -128,14 +155,18 @@ open class BaseActivity : AppCompatActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// 启动定时器
|
||||
// 启动超时定时器
|
||||
mHandler.postDelayed(mTimeoutRunnable, TIME_OUT)
|
||||
// 启动右侧状态栏时钟
|
||||
mHandler.post(clockTask)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
// 取消定时器
|
||||
// 取消超时定时器
|
||||
mHandler.removeCallbacks(mTimeoutRunnable)
|
||||
// 停止右侧状态栏时钟
|
||||
mHandler.removeCallbacks(clockTask)
|
||||
}
|
||||
|
||||
fun switchLight(isOpen: Boolean) {
|
||||
@@ -159,8 +190,8 @@ open class BaseActivity : AppCompatActivity() {
|
||||
val menuBinding = PopupRightStatusMenuBinding.inflate(LayoutInflater.from(this))
|
||||
val popup = PopupWindow(
|
||||
menuBinding.root,
|
||||
android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
120.dp,
|
||||
101.dp,
|
||||
true
|
||||
)
|
||||
menuBinding.tvEnvSwitch.setOnClickListener {
|
||||
|
||||
@@ -69,7 +69,7 @@ object SerialPortManager {
|
||||
}
|
||||
|
||||
// 关闭串口
|
||||
fun close() {
|
||||
suspend fun close() {
|
||||
scope.cancel()
|
||||
serialPort?.close()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@@ -39,8 +44,55 @@
|
||||
android:text="查找1001指令"/>
|
||||
</FrameLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@android:color/white"
|
||||
android:hint="搜索日志..."
|
||||
android:paddingHorizontal="12dp"
|
||||
android:textSize="14sp"
|
||||
android:singleLine="true"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/hsvTimeNav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llTimeNav"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="12dp" />
|
||||
</HorizontalScrollView>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvLogList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabJump"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@android:drawable/ic_menu_sort_by_size"
|
||||
app:fabSize="normal"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/white"
|
||||
android:elevation="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_env_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:gravity="center"
|
||||
android:text="切换环境"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:background="#E0E0E0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:gravity="center"
|
||||
android:text="查看日志"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user