feat(activity): 新增已采集食材列表页,支持搜索、删除及空视图展示
This commit is contained in:
@@ -115,6 +115,11 @@
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||
<activity
|
||||
android:name="com.shuwei.dish.match.ui.CollectedFoodActivity"
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
android:screenOrientation="portrait"
|
||||
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
|
||||
<activity
|
||||
android:name="com.shuwei.dish.match.ui.SlaveActivity"
|
||||
android:theme="@style/Theme.DishMatch.NoSplash"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.shuwei.dish.match.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.databinding.ListItemCollectedFoodBinding
|
||||
import com.shuwei.dish.match.entity.CollectedFoodItem
|
||||
|
||||
/**
|
||||
* 已采集食材列表适配器
|
||||
* 展示食材名称和已采集数量,支持删除操作
|
||||
*/
|
||||
class CollectedFoodAdapter(list: MutableList<CollectedFoodItem>) :
|
||||
BaseQuickAdapter<CollectedFoodItem, CollectedFoodAdapter.VH>(list) {
|
||||
|
||||
/** ViewHolder,持有列表项 ViewBinding */
|
||||
inner class VH(val binding: ListItemCollectedFoodBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val binding = ListItemCollectedFoodBinding.inflate(LayoutInflater.from(context), parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodItem?) {
|
||||
item ?: return
|
||||
holder.binding.tvFoodName.text = item.foodName.split("WP").first()
|
||||
holder.binding.tvCollectCount.text = "已采集${item.collectCount}"
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,6 @@ open class BaseActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityBaseBinding
|
||||
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// 提前隐藏系统栏,避免窗口创建时导航栏闪烁
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.shuwei.dish.match.db
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.shuwei.dish.match.entity.CollectedFoodItem
|
||||
import com.shuwei.dish.match.entity.CookFoodEntity
|
||||
import com.shuwei.dish.match.objbox.ObjectBox
|
||||
import com.shuwei.dish.match.entity.CookFoodGoodsEntity
|
||||
import com.shuwei.dish.match.entity.SeasoningEntity
|
||||
import com.shuwei.dish.match.entity.SeasoningSlotEntity
|
||||
@@ -248,4 +250,39 @@ class DbViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 已采集食材列表 UI 状态流
|
||||
* 元素为按名称分组后的(名称,数量)数据
|
||||
*/
|
||||
private val _collectedFoodListState = MutableStateFlow<List<CollectedFoodItem>>(emptyList())
|
||||
val collectedFoodListState: StateFlow<List<CollectedFoodItem>> = _collectedFoodListState.asStateFlow()
|
||||
|
||||
/**
|
||||
* 加载已采集食材列表,按名称分组统计数量
|
||||
* 使用属性查询只读 name 字段,不加载 foodVector,节省内存
|
||||
* @param nameFilter 名称过滤关键词,为空时加载全部
|
||||
*/
|
||||
fun loadCollectedFoodList(nameFilter: String? = null) {
|
||||
viewModelScope.launch {
|
||||
val result = ObjectBox.queryFoodNameCounts(nameFilter)
|
||||
_collectedFoodListState.value = result.map { (name, count) ->
|
||||
CollectedFoodItem(foodName = name, collectCount = count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定名称的所有采集记录,删除完成后刷新列表
|
||||
* @param foodName 食材名称
|
||||
* @param nameFilter 当前搜索关键词,用于删除后刷新列表
|
||||
*/
|
||||
fun removeCollectedFood(foodName: String, nameFilter: String? = null) {
|
||||
viewModelScope.launch {
|
||||
ObjectBox.remove(foodName)
|
||||
loadCollectedFoodList(nameFilter)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
@@ -23,7 +23,7 @@ open class CommonDialog(
|
||||
private lateinit var binding: DialogCommonBinding
|
||||
|
||||
private var titleText: String? = null
|
||||
private var contentText: String? = null
|
||||
private var contentText: CharSequence? = null
|
||||
private var negativeText = "取消"
|
||||
private var positiveText = "确认"
|
||||
private var neutralText: String? = null
|
||||
@@ -36,7 +36,7 @@ open class CommonDialog(
|
||||
fun setTitle(text: String): CommonDialog = apply { titleText = text }
|
||||
|
||||
/** 设置内容,为空时隐藏 */
|
||||
fun setContent(text: String): CommonDialog = apply { contentText = text }
|
||||
fun setContent(text: CharSequence): CommonDialog = apply { contentText = text }
|
||||
|
||||
/** 设置左侧取消按钮文字及点击回调(3按钮模式下对应顶部按钮) */
|
||||
fun setNegativeButton(text: String, onClick: (() -> Unit)? = null): CommonDialog = apply {
|
||||
|
||||
@@ -101,7 +101,7 @@ class FoodSearchDialog(
|
||||
}
|
||||
|
||||
binding.ivSearch.setOnClickListener { searchGoods(it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it.context, it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it) }
|
||||
|
||||
initObserver()
|
||||
|
||||
@@ -142,7 +142,7 @@ class FoodSearchDialog(
|
||||
}
|
||||
pageNo = 1
|
||||
getGoodsList()
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.shuwei.dish.match.utils.ext.buildSpannableString
|
||||
import com.shuwei.dish.match.utils.ext.dp
|
||||
import com.shuwei.dish.match.utils.ext.roundedDecimalPlace
|
||||
import com.shuwei.dish.match.utils.ext.toast
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
@@ -133,7 +132,7 @@ class SeasoningSearchDialog(
|
||||
}
|
||||
|
||||
binding.ivSearch.setOnClickListener { searchGoods(it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it.context, it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it) }
|
||||
|
||||
// 去皮按钮
|
||||
binding.tvClear.setOnClickListener {
|
||||
@@ -193,7 +192,7 @@ class SeasoningSearchDialog(
|
||||
}
|
||||
pageNo = 1
|
||||
getGoodsList()
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,7 +106,7 @@ class SeasoningSelectDialog(
|
||||
}
|
||||
|
||||
binding.ivSearch.setOnClickListener { searchGoods(it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it.context, it) }
|
||||
binding.root.setOnClickListener { KeyboardUtil.hideKeyboard(it) }
|
||||
}
|
||||
|
||||
/** 弹窗显示时自动加载默认调料列表 */
|
||||
@@ -126,7 +126,7 @@ class SeasoningSelectDialog(
|
||||
}
|
||||
pageNo = 1
|
||||
getGoodsList()
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard( v)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.shuwei.dish.match.entity
|
||||
|
||||
/**
|
||||
* 已采集食材列表项数据模型
|
||||
* @param foodName 食材名称
|
||||
* @param collectCount 已采集数量
|
||||
*/
|
||||
data class CollectedFoodItem(
|
||||
val foodName: String = "",
|
||||
val collectCount: Int = 0
|
||||
)
|
||||
@@ -213,6 +213,31 @@ object ObjectBox {
|
||||
getBox<Food>()?.query(Food_.name.equal(name))?.build()?.remove()
|
||||
}
|
||||
|
||||
/**
|
||||
* 按名称分组统计采集数量
|
||||
* 使用属性查询只加载 name 字段,不加载 foodVector,节省大量内存
|
||||
* @param nameFilter 名称过滤关键词,为空时查询全部
|
||||
* @return 按名称分组后的 (名称, 数量) 列表,按名称排序
|
||||
*/
|
||||
suspend fun queryFoodNameCounts(nameFilter: String? = null) = safeDbOp {
|
||||
val box = getBox<Food>() ?: return@safeDbOp emptyList<Pair<String, Int>>()
|
||||
val query = if (!nameFilter.isNullOrBlank()) {
|
||||
box.query(Food_.name.contains(nameFilter)).build()
|
||||
} else {
|
||||
box.query().build()
|
||||
}
|
||||
try {
|
||||
// 只查 name 字段,完全不加载 foodVector
|
||||
query.property(Food_.name).findStrings()
|
||||
.groupingBy { it }
|
||||
.eachCount()
|
||||
.map { (name, count) -> Pair(name, count) }
|
||||
.sortedBy { it.first }
|
||||
} finally {
|
||||
query.close()
|
||||
}
|
||||
} ?: emptyList()
|
||||
|
||||
private val dbMutex = Mutex() // 协程并发锁,保证写入操作原子性
|
||||
private const val DB_DIR_NAME = "objectbox" // ObjectBox 默认数据库目录
|
||||
private const val BACKUP_DIR_NAME = "objectbox_backup" // 备份目录
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.shuwei.dish.match.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.adapter.CollectedFoodAdapter
|
||||
import com.shuwei.dish.match.base.BaseActivity
|
||||
import com.shuwei.dish.match.databinding.ActivityCollectedFoodBinding
|
||||
import com.shuwei.dish.match.databinding.LayoutEmptyViewBinding
|
||||
import com.shuwei.dish.match.dialog.CommonDialog
|
||||
import com.shuwei.dish.match.entity.CollectedFoodItem
|
||||
import com.shuwei.dish.match.utils.KeyboardUtil
|
||||
import com.shuwei.dish.match.utils.ext.appendText
|
||||
import com.shuwei.dish.match.utils.ext.buildSpannableString
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.toast
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* 已采集食材列表页面
|
||||
* 展示所有已采集的食材及其采集数量,支持搜索和删除
|
||||
*/
|
||||
class CollectedFoodActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityCollectedFoodBinding
|
||||
|
||||
private val foodList = mutableListOf<CollectedFoodItem>()
|
||||
|
||||
private var emptyViewBinding: LayoutEmptyViewBinding? = null
|
||||
|
||||
private val adapter by lazy {
|
||||
CollectedFoodAdapter(foodList).apply {
|
||||
isStateViewEnable = true
|
||||
// 点击删除按钮,移除对应食材
|
||||
addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
|
||||
showDeleteDialog(foodList[position].foodName)
|
||||
}
|
||||
setOnItemClickListener { _, view, _ ->
|
||||
KeyboardUtil.hideKeyboard(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除弹窗
|
||||
*/
|
||||
private fun showDeleteDialog(foodName: String) {
|
||||
val showFoodName = foodName.split("WP").first()
|
||||
val separator = if (showFoodName.length <= 10) "\n" else ""
|
||||
val content = buildSpannableString {
|
||||
appendText("食材:")
|
||||
appendText(showFoodName, StyleSpan(Typeface.BOLD), ForegroundColorSpan(Color.BLACK))
|
||||
appendText(" 删除后无法恢复,${separator}确认要删除吗?")
|
||||
}
|
||||
CommonDialog(this)
|
||||
.setTitle("温馨提示")
|
||||
.setContent(content)
|
||||
.setNegativeButton("取消")
|
||||
.setPositiveButton("确认") {
|
||||
appViewModel.removeCollectedFood(
|
||||
foodName = foodName,
|
||||
nameFilter = binding.editSearch.text.toString()
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
statusBarDarkFont(enable = true)
|
||||
binding = ActivityCollectedFoodBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setHeaderBackground()
|
||||
binding.root.setOnClickListener { v ->
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
setTitleBar(titleBarAction = {
|
||||
it.visible()
|
||||
it.setOnClickListener { v ->
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
}, titleAction = {
|
||||
it.text = "已采集食材"
|
||||
}, rightIconActon = {
|
||||
it.gone()
|
||||
}, backAction = {
|
||||
it.visible()
|
||||
it.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
})
|
||||
initRecyclerView()
|
||||
initSearch()
|
||||
initObserver()
|
||||
loadCollectedFoodList()
|
||||
}
|
||||
|
||||
private fun loadCollectedFoodList(name: String = "") {
|
||||
appViewModel.loadCollectedFoodList(nameFilter = name)
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集 searchFoodState,统一处理 Loading / Success / Error 状态
|
||||
*/
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun initObserver() {
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
appViewModel.collectedFoodListState.collect { items ->
|
||||
foodList.clear()
|
||||
foodList.addAll(items)
|
||||
adapter.notifyDataSetChanged()
|
||||
if (items.isEmpty()) {
|
||||
loadEmptyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 展示空视图 */
|
||||
private fun loadEmptyView() {
|
||||
if (emptyViewBinding == null) {
|
||||
emptyViewBinding = LayoutEmptyViewBinding.inflate(
|
||||
LayoutInflater.from(this), binding.rvCollectedFood, false
|
||||
)
|
||||
}
|
||||
emptyViewBinding!!.tvContent.text = "暂无数据"
|
||||
emptyViewBinding!!.tvSubContent.text = "未查询到食材信息"
|
||||
adapter.stateView = emptyViewBinding!!.root
|
||||
}
|
||||
|
||||
/** 初始化列表 */
|
||||
private fun initRecyclerView() {
|
||||
binding.rvCollectedFood.run {
|
||||
layoutManager = LinearLayoutManager(this@CollectedFoodActivity)
|
||||
adapter = this@CollectedFoodActivity.adapter
|
||||
}
|
||||
}
|
||||
|
||||
/** 初始化搜索栏交互 */
|
||||
private fun initSearch() {
|
||||
binding.btnSearch.setOnClickListener { v ->
|
||||
performSearch {
|
||||
toast(binding.editSearch.hint.toString())
|
||||
}
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
binding.editSearch.run {
|
||||
addTextChangedListener {
|
||||
performSearch {
|
||||
loadCollectedFoodList()
|
||||
}
|
||||
}
|
||||
setOnEditorActionListener { v, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
performSearch {
|
||||
toast(binding.editSearch.hint.toString())
|
||||
}
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 根据关键词过滤食材列表 */
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun performSearch(action: () -> Unit) {
|
||||
val keyword = binding.editSearch.text.toString().trim()
|
||||
if (keyword.isEmpty()) {
|
||||
action()
|
||||
return
|
||||
}
|
||||
// 根据关键词从数据库查询并刷新列表
|
||||
loadCollectedFoodList(keyword)
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ class DishSamplingActivity : BaseActivity() {
|
||||
setSelection(text.length)
|
||||
}
|
||||
}
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
|
||||
private fun searchDishType() {
|
||||
|
||||
@@ -119,7 +119,7 @@ class FoodSearchActivity : BaseActivity() {
|
||||
binding.ivDishSearch.setOnClickListener { v ->
|
||||
pageNo = 1
|
||||
getInputAndSearch()
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
binding.refreshLayout.setEnableRefresh(true)
|
||||
binding.refreshLayout.setEnableLoadMore(false)
|
||||
@@ -136,13 +136,13 @@ class FoodSearchActivity : BaseActivity() {
|
||||
queryListInfo(foodName!!)
|
||||
}
|
||||
binding.root.setOnClickListener { v ->
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
binding.etInputDish.let { v ->
|
||||
v.addOnActionSearchListener {
|
||||
pageNo = 1
|
||||
getInputAndSearch()
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard( v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ class PrepareCookActivity : BaseActivity() {
|
||||
setSelection(text.length)
|
||||
}
|
||||
}
|
||||
KeyboardUtil.hideKeyboard(v.context, v)
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -120,7 +120,7 @@ class SelectDishActivity : BaseActivity() {
|
||||
putExtra(FoodSearchActivity.DINNER_TYPE, dinnerType)
|
||||
putExtra(FoodSearchActivity.FOOD_NAME, searchText)
|
||||
}
|
||||
KeyboardUtil.hideKeyboard(this, binding.etInputDish)
|
||||
KeyboardUtil.hideKeyboard(binding.etInputDish)
|
||||
}
|
||||
|
||||
private fun loadFragment() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.shuwei.dish.match.ui.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
@@ -22,6 +23,7 @@ import com.shuwei.dish.match.databinding.LayoutCameraPreviewBinding
|
||||
import com.shuwei.dish.match.dialog.Loading
|
||||
import com.shuwei.dish.match.objbox.FoodCollectionBean
|
||||
import com.shuwei.dish.match.objbox.FoodModule
|
||||
import com.shuwei.dish.match.ui.CollectedFoodActivity
|
||||
import com.shuwei.dish.match.ui.SingleFragmentActivity
|
||||
import com.shuwei.dish.match.utils.BitmapSaver
|
||||
import com.shuwei.dish.match.utils.CameraUtils
|
||||
@@ -243,7 +245,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>(){
|
||||
}
|
||||
|
||||
binding.btnCollectedFood.setOnClickListener {
|
||||
// startActivity(Intent(requireActivity(), CollectedFoodActivity::class.java))
|
||||
startActivity(Intent(requireActivity(), CollectedFoodActivity::class.java))
|
||||
}
|
||||
binding.btnTakePhoto.clickWithDebounce {
|
||||
val count = foodCollectionList.count { it.bitmap != null }
|
||||
|
||||
@@ -7,7 +7,8 @@ import android.view.inputmethod.InputMethodManager
|
||||
|
||||
object KeyboardUtil {
|
||||
|
||||
fun hideKeyboard(context: Context, view: View) {
|
||||
fun hideKeyboard(view: View) {
|
||||
val context = view.context
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(view.windowToken, 0)
|
||||
view.clearFocus() // 清除焦点避免键盘再次弹出
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 红色圆形背景 + 白色 X 图标,用于列表项删除按钮 -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
|
||||
<!-- 红色圆形背景 #FFEE4444 -->
|
||||
<path
|
||||
android:fillColor="#00BC71"
|
||||
android:pathData="M24,2C11.85,2 2,11.85 2,24C2,36.15 11.85,46 24,46C36.15,46 46,36.15 46,24C46,11.85 36.15,2 24,2Z" />
|
||||
|
||||
<!-- 白色 X 图标 -->
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M33,16.41L31.59,15L24,22.59L16.41,15L15,16.41L22.59,24L15,31.59L16.41,33L24,25.41L31.59,33L33,31.59L25.41,24L33,16.41Z" />
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:background="@color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/editSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/setting_border_gray3"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="输入食材名称"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="47dp"
|
||||
android:paddingEnd="80dp"
|
||||
android:textColor="@color/black"
|
||||
android:textColorHint="#FFC4CFDA"
|
||||
android:textSize="36sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btnSearch"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:padding="10dp"
|
||||
android:src="@drawable/ic_search2"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<!-- 已采集食材列表 -->
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvCollectedFood"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:overScrollMode="never"
|
||||
tools:itemCount="5"
|
||||
tools:listitem="@layout/list_item_collected_food" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -20,7 +20,7 @@
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:drawablePadding="17dp"
|
||||
android:text="餐品采集"
|
||||
android:text="食材采集"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
@@ -35,7 +35,7 @@
|
||||
android:layout_marginEnd="32dp"
|
||||
android:gravity="center_vertical"
|
||||
android:includeFontPadding="false"
|
||||
android:text="已采集餐品"
|
||||
android:text="已采集食材"
|
||||
android:textColor="#ff5e7585"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?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="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="32dp"
|
||||
android:paddingVertical="24dp">
|
||||
|
||||
<!-- 食材名称和采集数量 -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFoodName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="三河小炒" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCollectCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="#ff5e7585"
|
||||
android:textSize="26sp"
|
||||
tools:text="已采集153" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
<ImageView
|
||||
android:id="@+id/ivDelete"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:padding="25dp"
|
||||
android:src="@drawable/ic_close_red"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 分割线 -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="32dp"
|
||||
android:background="#FFE8EDF2" />
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user