Android开发:如何调整GridLayoutManager每行8个emoji大小适配屏幕宽度
问题原因
你当前的实现存在两个核心问题:
- 字号计算逻辑不合理:直接用屏幕宽度除以30得到的字号,没有考虑RecyclerView内边距、item间距、TextView内边距的影响,最终8个emoji的总宽度自然无法匹配屏幕宽度。
- 存在低级拼写错误:代码中的
onCrateView应为onCreateView,dsiplayMetrics应为displayMetrics,错误的拼写会导致参数获取异常、逻辑不生效。
解决方案
你可以按照以下两种方案实现,优先推荐方案一,实现更简单也更稳定:
方案一:使用系统自带的自动字号适配
- 先保证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) }
- 修改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"/>
- 在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
相关产品推荐
相关产品推荐

