【发布时间】:2016-12-10 09:28:23
【问题描述】:
RecyclerView 项目的高度不固定,我需要为每个项目设置背景图像,所以我想获取 recyclerview 项目的高度来调整图像大小,但是itemView.getHeight()在onBindViewHolder 中总是返回 0。
我已经尝试搜索了很多问题或文章,但我仍然无法找到一个好的解决方案。
【问题讨论】:
标签: android kotlin android-recyclerview
RecyclerView 项目的高度不固定,我需要为每个项目设置背景图像,所以我想获取 recyclerview 项目的高度来调整图像大小,但是itemView.getHeight()在onBindViewHolder 中总是返回 0。
我已经尝试搜索了很多问题或文章,但我仍然无法找到一个好的解决方案。
【问题讨论】:
标签: android kotlin android-recyclerview
短
手动测量视图
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)的宽度,并且高度不受限制。
【讨论】:
onBindViewHolder中的recyclerViewWidth?
我建议您定义多个具有预期高度的布局文件,并根据数据集中的某些标准对它们进行膨胀。
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();
【讨论】:
getMeasuredHeight() 或getMeasuredWidth() 方法。
这个怎么样:
view.post(() -> {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
【讨论】:
使用此代码获取回收站视图的项目高度:
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();
}
});
【讨论】:
使用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
}
}
【讨论】: