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

Android开发:如何调整GridLayoutManager每行8个emoji大小适配屏幕宽度

问题原因

你当前的实现存在两个核心问题:

  1. 字号计算逻辑不合理:直接用屏幕宽度除以30得到的字号,没有考虑RecyclerView内边距、item间距、TextView内边距的影响,最终8个emoji的总宽度自然无法匹配屏幕宽度。
  2. 存在低级拼写错误:代码中的onCrateView应为onCreateView,dsiplayMetrics应为displayMetrics,错误的拼写会导致参数获取异常、逻辑不生效。

解决方案

你可以按照以下两种方案实现,优先推荐方案一,实现更简单也更稳定:

方案一:使用系统自带的自动字号适配

  1. 先保证RecyclerView的宽度为match_parent,同时给GridLayoutManager设置每行8列:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    ...
    binding.recycler.layoutManager = GridLayoutManager(mContext, 8)
    binding.recycler.setHasFixedSize(true)
    binding.recycler.adapter = EmojiAdapter(mContext, emojis)
}
  1. 修改emoji对应的TextView布局,开启自动字号适配,让系统自动调整emoji大小撑满控件:
<TextView
    android:id="@+id/emoji_text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:autoSizeTextType="uniform"
    android:autoSizeMinTextSize="1sp"
    android:autoSizeMaxTextSize="100sp"
    android:autoSizeStepGranularity="1sp"/>
  1. 在Adapter的onCreateViewHolder中,给itemView设置固定宽高,保证每个item平分屏幕宽度:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmojiViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.item_emoji, parent, false)
    // 计算每个item的宽度:(屏幕宽度 - RecyclerView左右内边距 - 水平item间距总和) / 列数
    val spanCount = 8
    val totalWidth = parent.measuredWidth
    val paddingLeft = parent.paddingLeft
    val paddingRight = parent.paddingRight
    // 如果设置了item水平间距,这里替换成你实际的间距值
    val itemHorizontalSpace = 0
    val itemWidth = (totalWidth - paddingLeft - paddingRight - itemHorizontalSpace * (spanCount - 1)) / spanCount
    // 给item设置正方形宽高,也可以根据需求调整高度
    view.layoutParams = RecyclerView.LayoutParams(itemWidth, itemWidth)
    return EmojiViewHolder(view)
}

做完以上修改后,系统会自动把emoji调整到适配item大小的尺寸,8个item刚好占满整行宽度。

方案二:手动计算适配字号

如果你不想用系统自动适配,可以手动测量emoji宽度调整字号:

override fun onBindViewHolder(holder: EmojiViewHolder, position: Int) {
    val emoji = emojis[position]
    val maxTextWidth = holder.emojiText.width - holder.emojiText.paddingLeft - holder.emojiText.paddingRight
    val paint = holder.emojiText.paint
    var textSize = maxTextWidth.toFloat()
    paint.textSize = textSize
    // 循环调整字号直到emoji宽度不超过控件可用宽度
    while (paint.measureText(emoji) > maxTextWidth) {
        textSize -= 1f
        paint.textSize = textSize
    }
    holder.emojiText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
    holder.emojiText.text = emoji
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 09:36:02