You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio(Kotlin&XML):RecyclerView卡片集成Switch及选中项同步至汇总页

医疗提醒App核心功能实现指导(选中治疗项同步至汇总页+提醒频率设置)

需求概述

我正在开发一款医疗提醒App,核心流程与待实现功能如下:

  1. 首页支持选择治疗类别
  2. 进入对应类别页后,通过RecyclerView卡片内的Switch选择具体治疗项
  3. 选中治疗项后,点击「医疗包」图标进入汇总页,需实现:
    • 开启Switch时,汇总页自动生成带对应治疗名称和颜色的卡片
    • 汇总页支持为每个治疗项设置提醒频率

项目资源

  • 项目仓库:medminder-android
  • 页面截图:
    • 首页:首页截图
    • 治疗页:治疗页截图
    • 汇总页:汇总页截图

分步实现方案

1. 定义数据模型与状态管理

首先统一治疗项的数据结构,确保跨页面数据一致性:

// 治疗项数据类,包含核心属性
data class TreatmentItem(
    val id: String,
    val name: String,
    val colorHex: String,
    var isSelected: Boolean = false,
    var reminderFrequency: Int = 0 // 可定义为小时/天单位,根据需求调整
)

使用全局ViewModel维护选中状态,实现跨页面实时同步:

class TreatmentViewModel : ViewModel() {
    private val _selectedTreatments = MutableLiveData<MutableList<TreatmentItem>>()
    val selectedTreatments: LiveData<MutableList<TreatmentItem>> = _selectedTreatments

    init {
        // 初始化时可加载本地存储数据(见下文持久化部分)
        _selectedTreatments.value = mutableListOf()
    }

    // 更新治疗项选中状态
    fun updateTreatmentSelection(item: TreatmentItem) {
        val currentList = _selectedTreatments.value ?: mutableListOf()
        if (item.isSelected) {
            currentList.add(item)
        } else {
            currentList.removeIf { it.id == item.id }
        }
        _selectedTreatments.postValue(currentList)
        // 同步保存到本地(见下文持久化部分)
        saveSelectedTreatments(currentList)
    }
}

2. 治疗页Switch状态绑定与监听

在治疗页的RecyclerView Adapter中,绑定Switch状态并同步到ViewModel:

class TreatmentAdapter(
    private val treatmentList: List<TreatmentItem>,
    private val viewModel: TreatmentViewModel
) : RecyclerView.Adapter<TreatmentAdapter.ViewHolder>() {

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val card: CardView = itemView.findViewById(R.id.treatment_card)
        val nameTv: TextView = itemView.findViewById(R.id.treatment_name)
        val selectSwitch: Switch = itemView.findViewById(R.id.select_switch)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_treatment_card, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = treatmentList[position]
        // 绑定UI属性
        holder.card.setCardBackgroundColor(Color.parseColor(item.colorHex))
        holder.nameTv.text = item.name
        holder.selectSwitch.isChecked = item.isSelected

        // 监听Switch状态变化
        holder.selectSwitch.setOnCheckedChangeListener { _, isChecked ->
            item.isSelected = isChecked
            viewModel.updateTreatmentSelection(item)
        }
    }

    override fun getItemCount() = treatmentList.size
}

3. 汇总页实时展示与频率设置

在汇总页监听ViewModel的LiveData,实时更新RecyclerView:

class SummaryActivity : AppCompatActivity() {
    private lateinit var viewModel: TreatmentViewModel
    private lateinit var adapter: SummaryAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_summary)
        viewModel = ViewModelProvider(this)[TreatmentViewModel::class.java]
        initRecyclerView()
        observeSelectedTreatments()
    }

    private fun observeSelectedTreatments() {
        viewModel.selectedTreatments.observe(this) { items ->
            adapter.updateItems(items)
        }
    }

    private fun initRecyclerView() {
        adapter = SummaryAdapter(mutableListOf()) { item, newFrequency ->
            // 更新治疗项的提醒频率
            item.reminderFrequency = newFrequency
            viewModel.updateTreatmentSelection(item)
        }
        findViewById<RecyclerView>(R.id.summary_recycler).apply {
            adapter = this@SummaryActivity.adapter
            layoutManager = LinearLayoutManager(this@SummaryActivity)
        }
    }
}

汇总页Adapter实现频率设置功能:

class SummaryAdapter(
    private var items: MutableList<TreatmentItem>,
    private val onFrequencyChanged: (TreatmentItem, Int) -> Unit
) : RecyclerView.Adapter<SummaryAdapter.ViewHolder>() {

    fun updateItems(newItems: MutableList<TreatmentItem>) {
        items = newItems
        notifyDataSetChanged()
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val card: CardView = itemView.findViewById(R.id.summary_card)
        val nameTv: TextView = itemView.findViewById(R.id.treatment_name)
        val frequencySpinner: Spinner = itemView.findViewById(R.id.frequency_spinner)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_summary_card, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = items[position]
        holder.card.setCardBackgroundColor(Color.parseColor(item.colorHex))
        holder.nameTv.text = item.name

        // 绑定频率选择器
        holder.frequencySpinner.setSelection(item.reminderFrequency)
        holder.frequencySpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                onFrequencyChanged(item, position)
            }
            override fun onNothingSelected(parent: AdapterView<*>?) {}
        }
    }

    override fun getItemCount() = items.size
}

4. 持久化存储(可选但推荐)

避免App重启后数据丢失,将选中项序列化存储到SharedPreferences:

// 保存选中项到本地
fun saveSelectedTreatments(items: List<TreatmentItem>) {
    val gson = Gson()
    val json = gson.toJson(items)
    getSharedPreferences("MedMinderPrefs", Context.MODE_PRIVATE)
        .edit()
        .putString("selected_treatments", json)
        .apply()
}

// 从本地加载选中项
fun loadSelectedTreatments(context: Context): List<TreatmentItem> {
    val json = context.getSharedPreferences("MedMinderPrefs", Context.MODE_PRIVATE)
        .getString("selected_treatments", "")
    return if (json.isNullOrEmpty()) {
        emptyList()
    } else {
        Gson().fromJson(json, object : TypeToken<List<TreatmentItem>>() {}.type)
    }
}

在ViewModel初始化时加载本地数据:

init {
    val savedItems = loadSelectedTreatments(context).toMutableList()
    _selectedTreatments.value = savedItems
}

内容的提问来源于stack exchange,提问作者MobileMilin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:55:30