diff --git a/app/src/main/java/com/shuwei/dish/match/db/DbRepository.kt b/app/src/main/java/com/shuwei/dish/match/db/DbRepository.kt index 58f9be8..d68d977 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/DbRepository.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/DbRepository.kt @@ -168,6 +168,60 @@ class DbRepository { suspend fun deleteAllSlotsByDeviceId(deviceId: String) = withContext(Dispatchers.IO) { db.seasoningSlotDao().deleteAllByDeviceId(deviceId) } + + // ---- 调试用:查询各表全量数据(含已删除记录)---- + + /** 查询 dm_cook_food 全部记录 */ + suspend fun getAllCookFood() = withContext(Dispatchers.IO) { + db.cookFoodDao().getAllCookFood() + } + + /** 查询 dm_cook_food_goods 全部记录 */ + suspend fun getAllCookFoodGoods() = withContext(Dispatchers.IO) { + db.cookFoodGoodsDao().getAllCookFoodGoods() + } + + /** 查询 dm_seasoning 全部记录 */ + suspend fun getAllSeasoning() = withContext(Dispatchers.IO) { + db.seasoningDao().getAllSeasoning() + } + + // ---- 调试用:分页查询(含 isDel 过滤)---- + + suspend fun getCookFoodPaged(showDel: Boolean, limit: Int, offset: Int) = + withContext(Dispatchers.IO) { + db.cookFoodDao().getCookFoodPaged(if (showDel) 1 else 0, limit, offset) + } + + suspend fun countCookFoodAll(showDel: Boolean) = withContext(Dispatchers.IO) { + db.cookFoodDao().countCookFoodAll(if (showDel) 1 else 0) + } + + suspend fun getCookFoodGoodsPaged(showDel: Boolean, limit: Int, offset: Int) = + withContext(Dispatchers.IO) { + db.cookFoodGoodsDao().getCookFoodGoodsPaged(if (showDel) 1 else 0, limit, offset) + } + + suspend fun countCookFoodGoodsAll(showDel: Boolean) = withContext(Dispatchers.IO) { + db.cookFoodGoodsDao().countCookFoodGoodsAll(if (showDel) 1 else 0) + } + + suspend fun getSeasoningPaged(showDel: Boolean, limit: Int, offset: Int) = + withContext(Dispatchers.IO) { + db.seasoningDao().getSeasoningPaged(if (showDel) 1 else 0, limit, offset) + } + + suspend fun countSeasoningAll(showDel: Boolean) = withContext(Dispatchers.IO) { + db.seasoningDao().countSeasoningAll(if (showDel) 1 else 0) + } + + suspend fun getSlotPaged(limit: Int, offset: Int) = withContext(Dispatchers.IO) { + db.seasoningSlotDao().getSlotPaged(limit, offset) + } + + suspend fun countSlotAll() = withContext(Dispatchers.IO) { + db.seasoningSlotDao().countSlotAll() + } } // //class SeasoningRepository(val seasoningDao: SeasoningDao) { diff --git a/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt b/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt index 5fb1785..a1aac88 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/DbViewModel.kt @@ -237,7 +237,139 @@ class DbViewModel : ViewModel() { suspend fun deleteAllSlotsByDeviceId(deviceId: String) = rep.deleteAllSlotsByDeviceId(deviceId) -// fun updateAll(list: MutableList) { + // ---- 数据库调试查看 ---- + + companion object { + /** 每页加载条数 */ + const val DB_INSPECT_PAGE_SIZE = 50 + } + + /** + * 数据库调试页面 UI 状态 + * @param items 当前已加载的记录列表,Pair.first=是否逻辑删除,Pair.second=格式化文本 + * @param totalCount 当前过滤条件下的总记录数 + * @param hasMore 是否还有更多数据可加载 + * @param isLoading 是否正在加载(首次加载或加载更多) + */ + data class DbInspectUiState( + val items: List> = emptyList(), + val totalCount: Int = 0, + val hasMore: Boolean = false, + val isLoading: Boolean = false + ) + + private val _dbInspectState = MutableStateFlow(DbInspectUiState()) + val dbInspectState: StateFlow = _dbInspectState.asStateFlow() + + /** + * 加载指定表的第一页数据(切换 Tab / 切换 isDel 过滤时调用) + * @param tableIndex 0=菜品 1=食材 2=调料 3=槽位 + * @param showDel true=包含已删除记录,false=只看有效记录 + */ + fun loadDbInspect(tableIndex: Int, showDel: Boolean) { + viewModelScope.launch { + // 立即清空旧数据并显示加载状态,避免切换 Tab 时旧数据闪现 + _dbInspectState.value = DbInspectUiState(isLoading = true) + val (items, total) = queryPage(tableIndex, showDel, offset = 0) + _dbInspectState.value = DbInspectUiState( + items = items, + totalCount = total, + hasMore = items.size < total, + isLoading = false + ) + } + } + + /** + * 追加加载下一页数据(点击"加载更多"时调用) + * @param tableIndex 0=菜品 1=食材 2=调料 3=槽位 + * @param showDel true=包含已删除记录 + */ + fun loadMoreDbInspect(tableIndex: Int, showDel: Boolean) { + viewModelScope.launch { + val current = _dbInspectState.value + // 已在加载中或无更多数据时直接返回,防止重复请求 + if (!current.hasMore || current.isLoading) return@launch + _dbInspectState.value = current.copy(isLoading = true) + val (newItems, total) = queryPage(tableIndex, showDel, offset = current.items.size) + val merged = current.items + newItems + _dbInspectState.value = DbInspectUiState( + items = merged, + totalCount = total, + hasMore = merged.size < total, + isLoading = false + ) + } + } + + /** + * 执行分页查询,返回格式化后的列表和总记录数 + */ + private suspend fun queryPage( + tableIndex: Int, + showDel: Boolean, + offset: Int + ): Pair>, Int> { + val limit = DB_INSPECT_PAGE_SIZE + return when (tableIndex) { + 0 -> { + val total = rep.countCookFoodAll(showDel) + val rows = rep.getCookFoodPaged(showDel, limit, offset).map { e -> + (e.isDel == 1) to fmt( + "id" to e.id, "foodId" to e.foodId, "foodName" to e.foodName, + "canteenId" to e.canteenId, "foodWeight" to e.foodWeight, "cookMode" to e.cookMode, + "dinnerType" to e.dinnerType, "isDel" to e.isDel, "createTime" to e.createTime + ) + } + rows to total + } + 1 -> { + val total = rep.countCookFoodGoodsAll(showDel) + val rows = rep.getCookFoodGoodsPaged(showDel, limit, offset).map { e -> + (e.isDel == 1) to fmt( + "id" to e.id, "pid" to e.pid, "goodsId" to e.goodsId, + "goodsName" to e.goodsName, "foodId" to e.foodId, "materialType" to e.materialType, + "relateionType" to e.relateionType, "allEdible" to e.allEdible, "useWeight" to e.useWeight, + "sort" to e.sort, "zjmCode" to e.zjmCode, "materId" to e.materId, + "isDel" to e.isDel, "createTime" to e.createTime + ) + } + rows to total + } + 2 -> { + val total = rep.countSeasoningAll(showDel) + val rows = rep.getSeasoningPaged(showDel, limit, offset).map { e -> + (e.isDel == 1) to fmt( + "id" to e.id, "goodsId" to e.goodsId, "goodsName" to e.goodsName, + "sort" to e.sort, "materialType" to e.materialType, "useWeight" to e.useWeight, + "zjmCode" to e.zjmCode, "materId" to e.materId, "isDel" to e.isDel, + "createTime" to e.createTime + ) + } + rows to total + } + 3 -> { + val total = rep.countSlotAll() + val rows = rep.getSlotPaged(limit, offset).map { e -> + false to "deviceId: ${e.deviceId}\naddress: ${e.address}\ngoodsId: ${e.goodsId}\ngoodsName: ${e.goodsName}" + } + rows to total + } + else -> emptyList>() to 0 + } + } + + /** + * 将字段列表格式化为每行 3 个的紧凑布局 + * 格式:key: value | key: value | key: value + */ + private fun fmt(vararg fields: Pair): String = + fields.toList().chunked(3).joinToString("\n") { row -> + row.joinToString(" | ") { (k, v) -> "$k: ${v ?: "null"}" } + } + + //-------------------------------------------------------------------------------------------------------- + // viewModelScope.launch { // list.forEach { // rep.updateSeasoning(it) diff --git a/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodDao.kt b/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodDao.kt index ed89bb1..84c8a6e 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodDao.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodDao.kt @@ -28,4 +28,16 @@ interface CookFoodDao { // @Query("DELETE FROM dm_cook_food WHERE canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode") @Query("UPDATE dm_cook_food SET isDel = 1 WHERE isDel = 0 AND canteenId = :canteenId AND foodId = :foodId AND cookMode = :cookMode") suspend fun deleteCookFood(canteenId: String, foodId: String, cookMode: Int) + + /** 查询全部菜品记录(含已删除),用于数据库调试查看 */ + @Query("SELECT * FROM dm_cook_food ORDER BY createTime DESC") + suspend fun getAllCookFood(): MutableList + + /** 分页查询菜品记录,showDel=true 时包含已删除记录 */ + @Query("SELECT * FROM dm_cook_food WHERE (:showDel = 1 OR isDel = 0) ORDER BY createTime DESC LIMIT :limit OFFSET :offset") + suspend fun getCookFoodPaged(showDel: Int, limit: Int, offset: Int): List + + /** 统计菜品记录总数,showDel=true 时包含已删除记录 */ + @Query("SELECT COUNT(*) FROM dm_cook_food WHERE (:showDel = 1 OR isDel = 0)") + suspend fun countCookFoodAll(showDel: Int): Int } diff --git a/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodGoodsDao.kt b/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodGoodsDao.kt index de9f4fa..7ae95f7 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodGoodsDao.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/dao/CookFoodGoodsDao.kt @@ -28,4 +28,16 @@ interface CookFoodGoodsDao { // @Query("DELETE FROM dm_cook_food_goods WHERE pid = :pid AND foodId = :foodId") @Query("UPDATE dm_cook_food_goods SET isDel = 1 WHERE isDel = 0 AND pid = :pid AND foodId = :foodId") suspend fun deleteCookFoodGoodsList(pid: Long, foodId: String) + + /** 查询全部食材记录(含已删除),用于数据库调试查看 */ + @Query("SELECT * FROM dm_cook_food_goods ORDER BY createTime DESC") + suspend fun getAllCookFoodGoods(): MutableList + + /** 分页查询食材记录,showDel=true 时包含已删除记录 */ + @Query("SELECT * FROM dm_cook_food_goods WHERE (:showDel = 1 OR isDel = 0) ORDER BY createTime DESC LIMIT :limit OFFSET :offset") + suspend fun getCookFoodGoodsPaged(showDel: Int, limit: Int, offset: Int): List + + /** 统计食材记录总数,showDel=true 时包含已删除记录 */ + @Query("SELECT COUNT(*) FROM dm_cook_food_goods WHERE (:showDel = 1 OR isDel = 0)") + suspend fun countCookFoodGoodsAll(showDel: Int): Int } diff --git a/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningDao.kt b/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningDao.kt index 0760229..4f2ee2e 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningDao.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningDao.kt @@ -41,4 +41,16 @@ interface SeasoningDao { // @Query("DELETE FROM dm_seasoning WHERE isDel = 0") @Query("UPDATE dm_seasoning SET isDel = 1 WHERE isDel = 0") suspend fun clearAllSeasoning(): Int + + /** 查询全部调料记录(含已删除),用于数据库调试查看 */ + @Query("SELECT * FROM dm_seasoning ORDER BY sort ASC") + suspend fun getAllSeasoning(): MutableList + + /** 分页查询调料记录,showDel=true 时包含已删除记录 */ + @Query("SELECT * FROM dm_seasoning WHERE (:showDel = 1 OR isDel = 0) ORDER BY sort ASC LIMIT :limit OFFSET :offset") + suspend fun getSeasoningPaged(showDel: Int, limit: Int, offset: Int): List + + /** 统计调料记录总数,showDel=true 时包含已删除记录 */ + @Query("SELECT COUNT(*) FROM dm_seasoning WHERE (:showDel = 1 OR isDel = 0)") + suspend fun countSeasoningAll(showDel: Int): Int } diff --git a/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningSlotDao.kt b/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningSlotDao.kt index 67b2216..5a052e4 100644 --- a/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningSlotDao.kt +++ b/app/src/main/java/com/shuwei/dish/match/db/dao/SeasoningSlotDao.kt @@ -38,6 +38,14 @@ interface SeasoningSlotDao { @Query("SELECT * FROM dm_seasoning_slot") suspend fun queryAll(): List + /** 分页查询槽位记录(槽位表无 isDel,showDel 参数忽略) */ + @Query("SELECT * FROM dm_seasoning_slot ORDER BY deviceId ASC, address ASC LIMIT :limit OFFSET :offset") + suspend fun getSlotPaged(limit: Int, offset: Int): List + + /** 统计槽位记录总数 */ + @Query("SELECT COUNT(*) FROM dm_seasoning_slot") + suspend fun countSlotAll(): Int + /** * 删除指定设备的指定槽位配置 * @param deviceId 目标设备 ID diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt index d04501d..c663187 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SettingActivity.kt @@ -76,6 +76,9 @@ class SettingActivity : BaseActivity() { binding.llFoodCollect.clickWithDebounce { checkCameraPermission() } + binding.llDbInspect.clickWithDebounce { + SingleFragmentActivity.start(this, SingleFragmentActivity.PageType.DB_INSPECT) + } } private fun openCollectPage() { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt b/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt index 9c85662..d7c016e 100644 --- a/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt +++ b/app/src/main/java/com/shuwei/dish/match/ui/SingleFragmentActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.os.Bundle import androidx.fragment.app.Fragment import com.shuwei.dish.match.base.BaseActivity +import com.shuwei.dish.match.ui.fragment.DbInspectFragment import com.shuwei.dish.match.ui.fragment.VectorCollectionFragment import com.shuwei.dish.match.ui.fragment.DeviceConfigFragment import com.shuwei.dish.match.ui.fragment.SeasoningConfigFragment @@ -35,6 +36,9 @@ class SingleFragmentActivity : BaseActivity() { /** 调料配置页 */ SEASONING_CONFIG, + + /** 数据库调试查看页 */ + DB_INSPECT, } companion object { @@ -96,6 +100,7 @@ class SingleFragmentActivity : BaseActivity() { PageType.FOOD_COLLECT -> "食材采集" PageType.COOK_MODE -> "菜品模式" PageType.SEASONING_CONFIG -> "调料区设置" + PageType.DB_INSPECT -> "数据库查看" } /** @@ -105,6 +110,7 @@ class SingleFragmentActivity : BaseActivity() { PageType.FOOD_COLLECT -> VectorCollectionFragment() PageType.COOK_MODE -> DeviceConfigFragment() PageType.SEASONING_CONFIG -> SeasoningConfigFragment() + PageType.DB_INSPECT -> DbInspectFragment() } override fun onResume() { diff --git a/app/src/main/java/com/shuwei/dish/match/ui/fragment/DbInspectFragment.kt b/app/src/main/java/com/shuwei/dish/match/ui/fragment/DbInspectFragment.kt new file mode 100644 index 0000000..ce79029 --- /dev/null +++ b/app/src/main/java/com/shuwei/dish/match/ui/fragment/DbInspectFragment.kt @@ -0,0 +1,229 @@ +package com.shuwei.dish.match.ui.fragment + +import android.graphics.Color +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.RadioButton +import android.widget.TextView +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.shuwei.dish.match.R +import com.shuwei.dish.match.base.BaseFragment +import com.shuwei.dish.match.databinding.FragmentDbInspectBinding +import com.shuwei.dish.match.db.DbViewModel +import com.shuwei.dish.match.ui.SingleFragmentActivity +import com.shuwei.dish.match.utils.ext.gone +import com.shuwei.dish.match.utils.ext.visible +import kotlinx.coroutines.launch + +/** + * 数据库调试查看页面 + * 支持按表切换、isDel 过滤开关、分页加载(每页 50 条) + * 已逻辑删除(isDel=1)的记录以灰色文字 + 半透明卡片区分 + * 槽位表无 isDel 字段,切换到该 Tab 时自动隐藏 isDel 控件 + */ +class DbInspectFragment : BaseFragment() { + + private lateinit var currentActivity: SingleFragmentActivity + + /** 当前选中的表索引:0=菜品 1=食材 2=调料 3=槽位 */ + private var currentTableIndex = 0 + + /** 是否显示已删除记录(槽位表忽略此参数) */ + private var showDel = true + + /** + * 防止在代码中设置 Switch 状态时触发监听器, + * 例如切换回非槽位 Tab 时恢复 Switch 状态 + */ + private var ignoreSwitch = false + + private val adapter = DbRecordAdapter() + + /** Tab RadioButton 列表,用于统一更新选中样式 */ + private val tabButtons = mutableListOf() + + override fun inflateBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentDbInspectBinding = FragmentDbInspectBinding.inflate(inflater, container, false) + + override fun initialize() { + currentActivity = requireActivity() as SingleFragmentActivity + + binding.rvRecords.layoutManager = LinearLayoutManager(requireContext()) + binding.rvRecords.adapter = adapter + + tabButtons.addAll( + listOf(binding.rbCookFood, binding.rbGoods, binding.rbSeasoning, binding.rbSlot) + ) + + // Tab 切换:重置到第一页 + binding.rgTabs.setOnCheckedChangeListener { _, checkedId -> + currentTableIndex = when (checkedId) { + R.id.rbCookFood -> 0 + R.id.rbGoods -> 1 + R.id.rbSeasoning -> 2 + R.id.rbSlot -> 3 + else -> 0 + } + updateTabStyles() + moveIndicator(currentTableIndex) + updateDelControlsVisibility() + loadFirstPage() + } + + // isDel 开关:切换后重新加载第一页 + binding.swShowDel.setOnCheckedChangeListener { _, isChecked -> + if (ignoreSwitch) return@setOnCheckedChangeListener + showDel = isChecked + loadFirstPage() + } + + // 刷新按钮:重新加载第一页 + binding.tvRefresh.setOnClickListener { loadFirstPage() } + + // 加载更多按钮 + binding.tvLoadMore.setOnClickListener { + currentActivity.appViewModel.loadMoreDbInspect(currentTableIndex, showDel) + } + + // 订阅 UI 状态 + viewLifecycleOwner.lifecycleScope.launch { + currentActivity.appViewModel.dbInspectState.collect { state -> + renderState(state) + } + } + + // 初始化 Tab 样式并加载默认表 + updateTabStyles() + updateDelControlsVisibility() + binding.vTabIndicator.post { moveIndicator(currentTableIndex) } + loadFirstPage() + } + + /** 重新从第一页开始加载当前表数据 */ + private fun loadFirstPage() { + currentActivity.appViewModel.loadDbInspect(currentTableIndex, showDel) + } + + /** + * 根据 UI 状态更新计数文字、加载更多按钮和列表 + */ + private fun renderState(state: DbViewModel.DbInspectUiState) { + // 计数文字 + binding.tvCount.text = when { + state.isLoading && state.items.isEmpty() -> "加载中..." + state.hasMore -> "已加载 ${state.items.size} / 共 ${state.totalCount} 条" + else -> "共 ${state.totalCount} 条" + } + + // 加载更多按钮:有更多数据时显示,加载中时显示"加载中..."并禁用点击 + when { + state.isLoading && state.hasMore -> { + binding.tvLoadMore.visible() + binding.tvLoadMore.text = "加载中..." + binding.tvLoadMore.isClickable = false + } + state.hasMore -> { + binding.tvLoadMore.visible() + binding.tvLoadMore.text = "加载更多" + binding.tvLoadMore.isClickable = true + } + else -> binding.tvLoadMore.gone() + } + + adapter.setData(state.items) + } + + /** + * 槽位表(index=3)没有 isDel 字段,切换到该 Tab 时隐藏 isDel 相关控件; + * 切换回其他 Tab 时恢复,并同步 Switch 状态 + */ + private fun updateDelControlsVisibility() { + val isSlot = currentTableIndex == 3 + if (isSlot) { + binding.tvDelLabel.gone() + binding.swShowDel.gone() + } else { + binding.tvDelLabel.visible() + binding.swShowDel.visible() + // 恢复 Switch 显示状态(防止误触发监听器) + ignoreSwitch = true + binding.swShowDel.isChecked = showDel + ignoreSwitch = false + } + } + + /** + * 更新所有 Tab 的文字颜色和加粗状态 + */ + private fun updateTabStyles() { + tabButtons.forEachIndexed { index, btn -> + val selected = index == currentTableIndex + btn.setTextColor(if (selected) Color.parseColor("#5C77F7") else Color.parseColor("#888888")) + btn.setTypeface(null, if (selected) Typeface.BOLD else Typeface.NORMAL) + } + } + + /** + * 将下方指示条平移到选中 Tab 的正下方(150ms 动画) + */ + private fun moveIndicator(index: Int) { + val btn = tabButtons.getOrNull(index) ?: return + val tabWidth = btn.width.toFloat() + val indicatorWidth = tabWidth / 2f + val indicatorX = btn.x + (tabWidth - indicatorWidth) / 2f + + binding.vTabIndicator.animate() + .translationX(indicatorX) + .setDuration(150) + .start() + + binding.vTabIndicator.post { + val lp = binding.vTabIndicator.layoutParams + lp.width = indicatorWidth.toInt() + binding.vTabIndicator.layoutParams = lp + } + } + + // ---- 内部 Adapter ---- + + /** 数据库记录列表适配器 */ + private inner class DbRecordAdapter : RecyclerView.Adapter() { + + private val data = mutableListOf>() + + fun setData(list: List>) { + data.clear() + data.addAll(list) + notifyDataSetChanged() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.list_item_db_record, parent, false) + return VH(view) + } + + override fun onBindViewHolder(holder: VH, position: Int) { + val (isDeleted, content) = data[position] + holder.tvContent.text = content + // isDel=1 的记录用灰色标识,正常记录用深色 + holder.tvContent.setTextColor( + if (isDeleted) Color.parseColor("#BBBBBB") else Color.parseColor("#333333") + ) + // 已删除记录卡片略微透明 + holder.itemView.alpha = if (isDeleted) 0.6f else 1.0f + } + + override fun getItemCount() = data.size + + inner class VH(itemView: View) : RecyclerView.ViewHolder(itemView) { + val tvContent: TextView = itemView.findViewById(R.id.tvContent) + } + } +} diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml index 607df6e..29a9e6d 100644 --- a/app/src/main/res/layout/activity_setting.xml +++ b/app/src/main/res/layout/activity_setting.xml @@ -109,6 +109,37 @@ tools:ignore="ContentDescription" /> + + + + + + + diff --git a/app/src/main/res/layout/fragment_db_inspect.xml b/app/src/main/res/layout/fragment_db_inspect.xml new file mode 100644 index 0000000..0cf2857 --- /dev/null +++ b/app/src/main/res/layout/fragment_db_inspect.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_item_db_record.xml b/app/src/main/res/layout/list_item_db_record.xml new file mode 100644 index 0000000..3b5b1dd --- /dev/null +++ b/app/src/main/res/layout/list_item_db_record.xml @@ -0,0 +1,21 @@ + + + + + +