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

Android TV Item获焦时高度向上扩展(底部固定)问题求助

Android TV Item获焦时底部固定、高度向上扩展的解决方案

问题核心

当前修改LayoutParams仅调整宽高时,View默认会从顶部向下扩展,导致底部下移。要实现底部固定、高度向上扩展,需同时调整View的垂直位置偏移,抵消高度增加带来的底部位移。

解决方案步骤

  1. 保存原始布局参数:在Item的ViewHolder中初始化保存View的原始宽高、上下margin,避免多次焦点切换时参数累加错误。
  2. 计算高度增量:获焦时计算新高度与原始高度的差值,该差值即为需要向上偏移的距离。
  3. 调整布局参数:修改高度的同时,通过减少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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:08:26