如何在MainActivity满足计时条件后修改RecyclerView中TextView的颜色?
问题分析与解决方案
核心问题
- Adapter错误创建Activity实例:
var adapterSeconds = MainActivity().getDuration()这行代码会新建一个无关的MainActivity对象,并非当前运行的Activity实例,根本拿不到正确的计时数据。 - 颜色转换冗余操作:把
ContextCompat.getColor返回的Int类型颜色值转成String再转回Int,完全没必要,直接使用原始Int值即可。 - 逻辑职责混乱:判断文字是否变红的逻辑应该在生成数据时完成,Adapter只负责根据已有数据渲染UI,不该依赖外部Activity的状态。
修正后的代码
Data Class
保留布尔字段用于标记是否需要变红,无需修改:
data class Seconds( var rvSeconds: Int, var isRed: Boolean )
MainActivity
在添加数据到列表时,直接完成是否超过5秒的判断,设置isRed的值:
class MainActivity : AppCompatActivity() { var startTime = SystemClock.elapsedRealtime() var displaySeconds = 0 private lateinit var binding: ActivityMainBinding private val secondsList = generateSecondsList() private val secondsAdapter = Adapter(secondsList) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.recyclerView.adapter = secondsAdapter binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.setHasFixedSize(false) binding.button.setOnClickListener { addSecondsToRecyclerView() } } private fun getDuration(): Int { val endTime = SystemClock.elapsedRealtime() val elapsedMilliSeconds: Long = endTime - startTime val elapsedSeconds = elapsedMilliSeconds / 1000.0 displaySeconds = elapsedSeconds.toInt() return displaySeconds } private fun generateSecondsList(): ArrayList<Seconds> { return ArrayList() } private fun addSecondsToRecyclerView() { val currentSeconds = getDuration() // 在这里直接判断计时是否超过5秒,设置isRed状态 val addSeconds = Seconds(currentSeconds, currentSeconds > 5) secondsList.add(addSeconds) secondsAdapter.notifyItemInserted(secondsList.size - 1) } }
Adapter
移除错误的Activity实例,直接根据数据类的isRed字段设置文字颜色:
class Adapter( private val rvDisplay: MutableList<Seconds> ) : RecyclerView.Adapter<Adapter.AdapterViewHolder>() { class AdapterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val textView1: TextView = itemView.tv_seconds } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AdapterViewHolder { val myItemView = LayoutInflater.from(parent.context).inflate( R.layout.rv_item, parent, false ) return AdapterViewHolder(myItemView) } override fun onBindViewHolder(holder: AdapterViewHolder, position: Int) { val currentDisplay = rvDisplay[position] holder.textView1.text = currentDisplay.rvSeconds.toString() // 直接用数据中的isRed状态判断,颜色值直接使用Int类型 val textColor = if (currentDisplay.isRed) { ContextCompat.getColor(holder.itemView.context, R.color.red) } else { ContextCompat.getColor(holder.itemView.context, R.color.black) } holder.textView1.setTextColor(textColor) } override fun getItemCount() = rvDisplay.size }
额外说明
如果后续需要动态更新已有列表项的颜色(比如计时持续增长,超过5秒后所有旧列表项也要变红),可以在MainActivity中维护实时计时状态,定时遍历列表更新所有Seconds的isRed值,再调用secondsAdapter.notifyDataSetChanged()刷新整个列表。
内容的提问来源于stack exchange,提问作者thatWaz96
相关产品推荐
相关产品推荐

