RecyclerView项目的高度不固定,我需要为每个项目设置背景图片,所以我想获取recyclerview项目的高度来调整Image的大小,但itemView.getHeight()总是返回0。我试着搜索了很多问题或文章,但我仍然不能得到一个很好的解决方案。
itemView.getHeight()
6qfn3psc1#
短
手动测量视图
view.measure( View.MeasureSpec.makeMeasureSpec(recyclerViewWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
然后用view.getMeasuredHeight()得到高度
view.getMeasuredHeight()
背景
视图只有在测量后才会返回View.getHeight()的有效值。当视图即将显示在屏幕上时,系统会自动进行测量。当Android想要显示布局时,它将递归地为视图树中的每个视图调用view.layout()函数。每个父级都告诉其子级它们可能具有的约束(宽/高),并要求他们自己view.measure()。结果,该视图将根据指定成员中的约束存储测量值 BASED(MeasuredHeight/Width)。请注意,此时view.getMeasuredHeight()将保留值,而view.getHeight()仍然无效。view.getHeight()仅在视图在UI层次结构中具有实际高度时才会返回有效值。
View.getHeight()
view.layout()
view.measure()
view.getHeight()
回顾一下
因此,要在系统测量和布局视图元素之前知道它的高度,我们需要手动调用view.measure()函数。measure函数需要从视图LayoutParams +父约束导出的2个参数。在上面的代码示例中,我们正在测量视图,强制其宽度为EXACTLY父级(RecycleView)的宽度,高度不受限制。
c86crjj02#
我建议您定义多个具有预期高度的布局文件,并根据数据集中的某些标准对其进行膨胀。
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();
qvsjd97n3#
不如这样:
view.post(() -> { int width = view.getMeasuredWidth(); int height = view.getMeasuredHeight(); });
wz3gfoph4#
使用此代码获取回收器视图的项目高度:
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(); } });
fsi0uk1n5#
使用addOnGlobalLayoutListener()方法,在绘制TextView之前获得高度值。然后将其保存在成员变量中。关键是修改监听器实现内外的UI,这样就不会出现渲染问题(重绘视图时)。也就是说,您应该在侦听器内部使用getter;监听器内部和外部的设置器。
addOnGlobalLayoutListener()
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
5条答案
按热度按时间6qfn3psc1#
短
手动测量视图
然后用
view.getMeasuredHeight()
得到高度背景
视图只有在测量后才会返回
View.getHeight()
的有效值。当视图即将显示在屏幕上时,系统会自动进行测量。当Android想要显示布局时,它将递归地为视图树中的每个视图调用
view.layout()
函数。每个父级都告诉其子级它们可能具有的约束(宽/高),并要求他们自己view.measure()
。结果,该视图将根据指定成员中的约束存储测量值 BASED(MeasuredHeight/Width)。请注意,此时view.getMeasuredHeight()
将保留值,而view.getHeight()
仍然无效。view.getHeight()
仅在视图在UI层次结构中具有实际高度时才会返回有效值。回顾一下
因此,要在系统测量和布局视图元素之前知道它的高度,我们需要手动调用
view.measure()
函数。measure函数需要从视图LayoutParams +父约束导出的2个参数。
在上面的代码示例中,我们正在测量视图,强制其宽度为EXACTLY父级(RecycleView)的宽度,高度不受限制。
c86crjj02#
我建议您定义多个具有预期高度的布局文件,并根据数据集中的某些标准对其进行膨胀。
如here所示:初始化视图保持器时可以获得测量值
qvsjd97n3#
不如这样:
wz3gfoph4#
使用此代码获取回收器视图的项目高度:
fsi0uk1n5#
MyViewHolder.kt
使用
addOnGlobalLayoutListener()
方法,在绘制TextView之前获得高度值。然后将其保存在成员变量中。关键是修改监听器实现内外的UI,这样就不会出现渲染问题(重绘视图时)。
也就是说,您应该在侦听器内部使用getter;监听器内部和外部的设置器。
Source