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

如何在运行时批量修改RecyclerView中所有条目的字体

代码失效原因
  • RecyclerView 本身只是列表容器,不持有所有子item的控件实例,你直接通过rv_work_preview.tv_work_content查找控件时,系统只会返回当前可视区域内第一个匹配该id的item控件,所以只会修改第一个条目的字体。
  • 每次点击都调用Typeface.createFromAsset属于重复加载字体资源,不仅会造成性能损耗,还会引发内存泄漏。
可行实现方案

步骤1:改造RecyclerView的Adapter

在Adapter内部声明全局字体变量,提供外部设置入口,设置后触发列表刷新:

class YourPreviewAdapter : RecyclerView.Adapter<YourPreviewAdapter.ViewHolder>() {
    // 全局字体变量,默认使用系统默认字体
    var currentTypeface: Typeface = Typeface.DEFAULT
        set(value) {
            field = value
            // 刷新列表触发所有item重新绑定
            notifyDataSetChanged()
        }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvWorkContent: TextView = itemView.findViewById(R.id.tv_work_content)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // 每次绑定item时都应用当前全局字体
        holder.tvWorkContent.typeface = currentTypeface
        // 其余原有绑定逻辑保持不变
    }

    // 其余原有Adapter方法保持不变
}

步骤2:提前缓存字体实例,点击按钮更新全局字体

在页面初始化时提前加载好字体资源,避免重复加载:

// 页面成员变量,提前缓存两种字体
private lateinit var aritaBuriTypeface: Typeface
private lateinit var cafe24Typeface: Typeface
// 列表Adapter实例
private lateinit var previewAdapter: YourPreviewAdapter

// 在onViewCreated等初始化方法中完成资源加载、Adapter初始化
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    // 仅加载一次字体资源
    aritaBuriTypeface = Typeface.createFromAsset(requireActivity().assets, "fonts/arita_buri.otf")
    cafe24Typeface = Typeface.createFromAsset(requireActivity().assets, "fonts/cafe24_surround_air.ttf")
    
    // 初始化Adapter并绑定到RecyclerView
    previewAdapter = YourPreviewAdapter()
    rv_work_preview.adapter = previewAdapter

    // 按钮点击逻辑
    rbAritaBuri.setOnClickListener {
        previewAdapter.currentTypeface = aritaBuriTypeface
    }
    rbCafe24.setOnClickListener {
        previewAdapter.currentTypeface = cafe24Typeface
    }
}
性能优化提示

如果觉得notifyDataSetChanged全量刷新性能损耗较大,可以仅刷新当前可见区域的item:

// 可以把字体设置逻辑挪到页面层,避免Adapter持有RecyclerView实例
rbAritaBuri.setOnClickListener {
    previewAdapter.currentTypeface = aritaBuriTypeface
    val layoutManager = rv_work_preview.layoutManager as LinearLayoutManager
    val firstVisible = layoutManager.findFirstVisibleItemPosition()
    val lastVisible = layoutManager.findLastVisibleItemPosition()
    previewAdapter.notifyItemRangeChanged(firstVisible, lastVisible - firstVisible + 1)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:21:04