Android TV Item获焦时高度向上扩展(底部固定)问题求助
Android TV Item获焦时底部固定、高度向上扩展的解决方案
问题核心
当前修改LayoutParams仅调整宽高时,View默认会从顶部向下扩展,导致底部下移。要实现底部固定、高度向上扩展,需同时调整View的垂直位置偏移,抵消高度增加带来的底部位移。
解决方案步骤
- 保存原始布局参数:在Item的
ViewHolder中初始化保存View的原始宽高、上下margin,避免多次焦点切换时参数累加错误。 - 计算高度增量:获焦时计算新高度与原始高度的差值,该差值即为需要向上偏移的距离。
- 调整布局参数:修改高度的同时,通过减少
topMargin让View整体向上偏移,保持底部位置不变;失焦时恢复原始参数。
修改后的代码示例
第一步:在ViewHolder中保存原始参数
class MyItemViewHolder(view: View) : Presenter.ViewHolder(view) { // 保存View初始化时的原始布局参数 val originalWidth: Int val originalHeight: Int val originalTopMargin: Int val originalBottomMargin: Int init { val params = view.layoutParams as ViewGroup.MarginLayoutParams originalWidth = params.width originalHeight = params.height originalTopMargin = params.topMargin originalBottomMargin = params.bottomMargin } }
第二步:调整焦点监听逻辑
inner class ItemViewSelectedListener : OnItemViewSelectedListener { override fun onItemSelected( itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder?, row: Row? ) { if (item is MenuLabelI) { val indexOfItem = ((row as ListRow).adapter as ArrayObjectAdapter).indexOf(item) itemSelectedListener?.invoke(item) itemIndexSelectedListener?.invoke(indexOfItem) } itemViewHolder?.let { holder -> val view = holder.view view.setOnFocusChangeListener { _, hasFocus -> val layoutParams = view.layoutParams as ViewGroup.MarginLayoutParams val myHolder = holder as MyItemViewHolder if (hasFocus) { view.setBackgroundResource(R.color.selector_color_taj_trees) val newWidth = getWidthInPercent(view.context, 14) val newHeight = getHeightInPercent(view.context, 17) val heightDelta = newHeight - myHolder.originalHeight // 设置新宽高 layoutParams.width = newWidth layoutParams.height = newHeight // 向上偏移:顶部margin减少高度增量,底部margin保持原始值,确保底部固定 layoutParams.topMargin = myHolder.originalTopMargin - heightDelta layoutParams.bottomMargin = myHolder.originalBottomMargin } else { view.setBackgroundResource(R.color.item_color_taj_trees) // 恢复所有原始布局参数 layoutParams.width = myHolder.originalWidth layoutParams.height = myHolder.originalHeight layoutParams.topMargin = myHolder.originalTopMargin layoutParams.bottomMargin = myHolder.originalBottomMargin } view.layoutParams = layoutParams // 强制触发布局更新,确保参数生效 view.requestLayout() } } } }
关键注意点
- 必须基于原始参数进行修改,不能在上次修改后的参数基础上叠加,否则多次焦点切换会导致位置偏移错乱。
- 如果使用
HorizontalGridView作为父容器,需确保其clipToPadding属性设置为false,避免向上扩展的部分被容器裁剪。 - 不要使用
scaleX/scaleY:缩放仅改变内容显示比例,不会修改View的实际布局尺寸,无法满足需求。
内容的提问来源于stack exchange,提问作者Keyser Soze
相关产品推荐
相关产品推荐

