如何在“onBindViewHolder”中获取recyclerview项目的高度
Posted
技术标签:
【中文标题】如何在“onBindViewHolder”中获取recyclerview项目的高度【英文标题】:How to get the height of recyclerview item in "onBindViewHolder" 【发布时间】:2016-12-10 09:28:23 【问题描述】:RecyclerView 项目的高度不固定,我需要为每个项目设置背景图像,所以我想获取 recyclerview 项目的高度来调整图像大小,但是itemView.getHeight()
在onBindViewHolder
中总是返回 0。
我已经尝试搜索了很多问题或文章,但我仍然无法找到一个好的解决方案。
【问题讨论】:
【参考方案1】:短
手动测量视图
view.measure(
View.MeasureSpec.makeMeasureSpec(recyclerViewWidth, View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
并使用view.getMeasuredHeight()
获取高度
背景
只有在测量之后,视图才会返回 View.getHeight()
的有效值。当视图即将显示在屏幕上时,系统会自动进行测量。
当android想要显示布局时,它会为视图树中的每个视图递归调用view.layout()
函数。每个父母都会告诉其孩子他们可能有的限制(宽度/高度)并要求他们自己view.measure()
。因此,视图将BASED 存储指定成员(MeasuredHeight/Width)中约束的测量值。请注意,此时view.getMeasuredHeight()
将保留该值,而view.getHeight()
仍然无效。 view.getHeight()
只会在视图在 UI 层次结构中具有实际高度时返回有效值。
回顾
因此,要知道视图元素的高度,在系统测量和布局之前,我们需要手动调用view.measure()
函数。
measure 函数需要 2 个参数,这些参数来自视图 LayoutParams + 父约束。
在上面的代码示例中,我们正在测量视图,强制其宽度完全等于父级(RecycleView)的宽度,并且高度不受限制。
【讨论】:
第一次返回0。滚动时返回值。有什么办法吗? 你怎么知道onBindViewHolder
中的recyclerViewWidth
?【参考方案2】:
我建议您定义多个具有预期高度的布局文件,并根据数据集中的某些标准对它们进行膨胀。
ViewHolder onCreateViewHolder (ViewGroup parent, int viewType)
if(some condition)
//inflate layout 1
else
//inflate layout 2
或回答here:您可以在初始化视图支架时获取测量值
itemView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
int width = itemView.getMeasuredWidth();
int height = itemView.getMeasuredHeight();
【讨论】:
ViewHolder 没有getMeasuredHeight()
或getMeasuredWidth()
方法。
他可能是指viewholder.itemView【参考方案3】:
这个怎么样:
view.post(() ->
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
【讨论】:
【参考方案4】:使用此代码获取回收站视图的项目高度:
view.getViewTreeObserver().addOnGlobalLayoutListener(new
ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
//don't forget remove this listener
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//get item height here
int itemHeight = v.getHeight();
);
【讨论】:
【参考方案5】:MyViewHolder.kt
使用addOnGlobalLayoutListener()
方法,在绘制TextView之前获取高度值。然后将其保存在成员变量中。
关键是修改监听器实现内外的UI,这样就不会出现渲染问题(重绘视图时)。
也就是说,您应该在侦听器中使用 getter,并且;侦听器内部和外部的设置器。
companion object
var maxHeight: Int = 0
fun create(mContext: Context): MyViewHolder
val view = LayoutInflater.from(mContext).inflate(R.layout.item_answer, null)
updateLayout(view)
view.viewTreeObserver.addOnGlobalLayoutListener
if (view.myTextView.height > maxHeight)
maxHeight = view.myTextView.height
updateLayout(view)
return MyViewHolder(mContext, view).apply
setIsRecyclable(false)
fun updateLayout(view: View)
if (maxHeight != 0 && view.myTextView.height != maxHeight)
view.myTextView.height = maxHeight
Source
【讨论】:
以上是关于如何在“onBindViewHolder”中获取recyclerview项目的高度的主要内容,如果未能解决你的问题,请参考以下文章
如何在回收站视图的 onBindViewHolder() 方法中调用 getString()?
未调用 RecyclerVIew onCreateViewHolder 和 onBindViewHolder
在 RecyclerView 适配器 notifyDataSetChanged() 之后未调用 onBindViewHolder
如何将 AsyncTask 从 Adapter onBindViewHolder() 移动到 Activity onChildEventListener