【问题标题】:How to get the height of recyclerview item in "onBindViewHolder"如何在“onBindViewHolder”中获取recyclerview项目的高度
【发布时间】:2016-12-10 09:28:23
【问题描述】:

RecyclerView 项目的高度不固定,我需要为每个项目设置背景图像,所以我想获取 recyclerview 项目的高度来调整图像大小,但是itemView.getHeight()onBindViewHolder 中总是返回 0。

我已经尝试搜索了很多问题或文章,但我仍然无法找到一个好的解决方案。

【问题讨论】:

    标签: android kotlin android-recyclerview


    【解决方案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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-05
          • 1970-01-01
          • 2019-12-22
          • 2016-07-18
          相关资源
          最近更新 更多