【问题标题】:How to set RecyclerView Max Height如何设置 RecyclerView 最大高度
【发布时间】:2017-07-30 09:06:58
【问题描述】:

我想设置 RecylerView 的最大高度。我可以使用下面的代码设置最大高度。下面的代码使高度为当前屏幕的 60%。

     DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int a = (displaymetrics.heightPixels * 60) / 100;
    recyclerview1.getLayoutParams().height = a;

但现在的问题是,如果它没有项目,那么它的高度也是 60%。 所以我想在没有项目时将其高度设置为0。

我想实现类似的目标。

    if(recyclerview's height > maxHeight)
then set recyclerview's height to maxHeight
    else dont change the height of recyclerview.

如何设置? 请帮帮我,我坚持下去了

【问题讨论】:

  • RecyclerView 显然自带了一个 XML 中称为 maxHeight 的参数,但它不起作用

标签: android android-recyclerview


【解决方案1】:

这里有一些东西,你需要。继承 RecyclerView 并覆盖 onMeasure 如下:

@Override
protected void onMeasure(int widthSpec, int heightSpec) {
    heightSpec = MeasureSpec.makeMeasureSpec(Utils.dpsToPixels(240), MeasureSpec.AT_MOST);
    super.onMeasure(widthSpec, heightSpec);
}

请确保在makeMeasureSpec() 中将正确数量的像素作为第一个参数。我个人需要 RecyclerView,最多 240dps。

【讨论】:

  • 请问你是如何子类化 RecyclerView 的?
  • @Dusan 创建了一个扩展 RecyclerView 的新类。
  • 此解决方案在您向 Array 中添加元素时有效,但在您从数组中删除元素时无效。这意味着一旦我们增加了高度,我们就不能减少 RecyclerView 的高度。
  • 这实际上是拥有最大高度的回收站视图的唯一方法。糟糕的谷歌。
【解决方案2】:

ConstraintLayout 为其子级提供最大高度。

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_max="300dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

【讨论】:

  • 看起来是最好的解决方案。可悲的是,但它不起作用。
  • 确保更新约束布局依赖,否则旧版本中存在一个错误,当回收器视图变为可滚动时,回收器视图被隐藏
【解决方案3】:

我们可以稍微优化@Fattum 的方法。 我们可以使用app:maxHeight 来设置maxHeight。可以随意使用dppx

public class MaxHeightRecyclerView extends RecyclerView {
    private int mMaxHeight;

    public MaxHeightRecyclerView(Context context) {
        super(context);
    }

    public MaxHeightRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs);
    }

    public MaxHeightRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize(context, attrs);
    }

    private void initialize(Context context, AttributeSet attrs) {
        TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        mMaxHeight = arr.getLayoutDimension(R.styleable.MaxHeightScrollView_maxHeight, mMaxHeight);
        arr.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mMaxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

值/attrs.xml

<declare-styleable name="MaxHeightScrollView">
    <attr name="maxHeight" format="dimension" />
</declare-styleable>

【讨论】:

  • 此解决方案在您向 Array 中添加元素时有效,但在您从数组中删除元素时无效。这意味着一旦我们增加了高度,我们就不能减少 RecyclerView 的高度。
【解决方案4】:

我认为这至少对我有用

<androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/Id_const_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
               >
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/Id_my_recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/margin_top_space"
            android:scrollbars="vertical"
            app:layout_constrainedHeight="true"
            app:layout_constraintBottom_toBottomOf="@+id/Id_const_layout"
            app:layout_constraintEnd_toEndOf="@+id/Id_const_layout"
            app:layout_constraintHeight_max="150dp"
            app:layout_constraintHeight_min="30dp"
            app:layout_constraintStart_toStartOf="@+id/Id_const_layout"
            app:layout_constraintTop_toTopOf="@+id/Id_const_layout"
            >
        </androidx.recyclerview.widget.RecyclerView>
            </androidx.constraintlayout.widget.ConstraintLayout>

您可以根据需要更改constraintHeight_maxconstraintHeight_min

【讨论】:

    【解决方案5】:

    在尝试了太多复杂的建议后,我终于通过反复试验弄明白了。

    首先,将 RecyclerView 包装在某种布局中。在我的例子中,我使用了约束布局,我什至在 RecyclerView 上方和下方的布局中都有其他元素。通过将布局高度设置为 0dp 将其设置为自动调整,然后将默认布局高度约束设置为 wrap 并定义布局最大高度约束。

    然后,在您的 RecyclerView 上,将高度设置为 wrap_content 并将 layout_constrainedHeight 设置为 true。

    它应该是这样的:

    <android.support.constraint.ConstraintLayout
        android:layout_width="600px"
        android:layout_height="0dp"
        app:layout_constraintHeight_default="wrap"
        app:layout_constraintHeight_max="450px">
    
        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constrainedHeight="true"
            app:layout_constraintTop_ToTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
    
    </android.support.constraint.ConstraintLayout>
    

    希望这会有所帮助!

    【讨论】:

    • 我也认为这是最好的答案,虽然你有一个错字:app:layout_constraintTop_ToTopOf 应该是app:layout_constraintTop_toTopOf
    • 给出明确的最大高度是否适用于具有不同尺寸的不同设备?
    • 另外,我们需要使用dp,而不是px
    【解决方案6】:

    在 if else 里面写下这个语句 让我知道,

    ViewGroup.LayoutParams params=recyclerview.getLayoutParams();
    params.height=100;
    recyclerview.setLayoutParams(params);
    

    【讨论】:

    • > 当其中没有项目时将其高度设置为 0。你怎么能确定这个?@Maulik009,在那个地方。是的@Piyush,bhai :)
    【解决方案7】:

    加上我的 2 美分,我需要一个具有最大高度和最小高度的回收站视图,并在 2 美分之间包装内容

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:id="@+id/group_card_recycler_view_holder"
                app:layout_constraintHeight_default="wrap"
                app:layout_constraintHeight_max="@dimen/group_recycler_view_height"
                app:layout_constraintHeight_min="@dimen/card_sentence_height"
                android:layout_marginTop="@dimen/activity_horizontal_margin_8dp"
                app:layout_constraintTop_toBottomOf="@id/group_name_container"
                app:layout_constraintBottom_toTopOf="@id/myButtonLayout">
    
    
                <androidx.recyclerview.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:layout_constrainedHeight="true"
                    android:id="@+id/group_card_recycler_view"/>
    
    
            </androidx.constraintlayout.widget.ConstraintLayout>
    

    【讨论】:

      【解决方案8】:

      您可以在 RecyclerView 中使用 WRAP_CONTENT。它将根据其内容自动测量您的回收站视图。

      您还可以计算当前高度并设置最大高度。所以 Recyclerview 将使用 wrap_content 属性值直到最大高度。

      public static void getTotalHeightofRecyclerView(RecyclerView recyclerView) {
      
              RecyclerView.Adapter mAdapter = recyclerView.getAdapter();
      
              int totalHeight = 0;
      
              for (int i = 0; i < mAdapter.getItemCount(); i++) {
                  View mView = recyclerView.findViewHolderForAdapterPosition(i).itemView
      
                  mView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                          View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
      
                  totalHeight += mView.getMeasuredHeight();
              }
      
              if (totalHeight > 100) {
                  ViewGroup.LayoutParams params = recyclerView.getLayoutParams();
                  params.height = 100;
                  recyclerView.setLayoutParams(params);
              }
          }
      

      【讨论】:

      • 我在布局中保留了 wrap_content。但我想设置它的最大高度,以便它只在当前屏幕中滚动。因为我在它下面有我想一直显示的按钮。
      • 引起:java.lang.NullPointerException:尝试从字段'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView'读取空对象引用错误在线查看 mView = recyclerView.findViewHolderForAdapterPosition(i).itemView
      • 可以分享代码吗?看起来您在 findViewHolderForAdapterPosition 之前调用 notifyDataSetChange()。
      • 不,我没有调用 notifyDataSetChange。
      • recyclerview1.setAdapter(sectionAdapter1); recyclerview1.setLayoutManager(new LinearLayoutManager(this)); RecyclerView.Adapter mAdapter = recyclerview1.getAdapter(); getTotalHeightofRecyclerView(recyclerview1);
      【解决方案9】:

      最简单的方法是使用 ConstraintLayout 并在 Recycleview 上设置高度限制。

      <android.support.constraint.ConstraintLayout
          android:id="@+id/CL_OUTER_RV_Choose_Categories "
          android:layout_width="match_parent"
          android:layout_height="200dp">
      
         <android.support.v7.widget.RecyclerView
              android:id="@+id/RV_Choose_Categories"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:scrollbars="vertical"
              app:layout_constrainedHeight="true" >
          </android.support.v7.widget.RecyclerView>
      
      </android.support.constraint.ConstraintLayout>
      

      请注意,在 Lollipop 之前,recycleview 不会滚动。作为解决方案,在 Activity 的 oncreate 中添加以下代码。

      if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
              ConstraintLayout CL_OUTER_RV_Choose_Categories = findViewById(R.id.CL_OUTER_RV_Choose_Categories);
              LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) CL_OUTER_RV_Choose_Categories.getLayoutParams();
              lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
          }
      

      这将确保仅在受支持的设备上固定高度,并且在旧设备上显示完整的回收视图。

      如果有更好的方法,请告诉我。

      【讨论】:

        【解决方案10】:

        如果您的 RecyclerView 旨在容纳相同物理大小的项目,并且您想要一种简单的方法来限制其高度而不扩展 RecyclerView,请尝试以下操作:

        int maxRecyclerViewHeightPixels = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            MAX_RECYCLERVIEW_HEIGHT_DP,
            getResources().getDisplayMetrics()
        );
        
        MyRecyclerViewAdapter myRecyclerViewAdapter = new MyRecyclerViewAdapter(getContext(), myElementList);
        myRecyclerView.setAdapter(myRecyclerViewAdapter);
        
        ViewGroup.LayoutParams params = myRecyclerView.getLayoutParams();
        
        if (myElementList.size() <= MAX_NUMBER_OF_ELEMENTS_TO_DISPLAY_AT_ONE_TIME) {
            myRecyclerView.setLayoutParams(new LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.MATCH_PARENT,
                 LinearLayout.LayoutParams.WRAP_CONTENT));
            //LinearLayout must be replaced by whatever layout type encloses your RecyclerView
        }
        else {
            params.height = maxRecyclerViewHeightPixels;
            myRecyclerView.setLayoutParams(params);
        }
        

        这适用于 Linear 和 Grid RecyclerViews,您只需要稍微调整一下数字以适应您的口味。填充 RecyclerView 后不要忘记将高度设置为 WRAP_CONTENT。

        您可能还必须在每次 myElementList 的大小发生变化时再次设置高度,但这不是什么大问题。

        【讨论】:

          【解决方案11】:

          我刚遇到同样的问题,想分享一个新的、最新的答案。这个至少适用于 Android 9 和 Android Studio v. 4.0。

          将 RecyclerView 包装在 ConstraintLayout 中,正如此处的一些答案所建议的那样。但是您似乎无法在 XML 中设置该布局的最大高度。相反,您必须在代码中设置它,如下所示:为 ConstraintLayout 提供一个 ID,然后分别在相关活动或片段的 onCreate 或 onViewCreated 方法中设置 - 例如,将最大高度设置为 200 dp:

          findViewById<ConstraintLayout>(R.id.[YOUR ID]).maxHeight = 200 // activity
          view.findViewById<ConstraintLayout>(R.id.[YOUR ID]).maxHeight = 200 // fragment
          

          令人讨厌的是,ConstraintLayout确实公开了一个 XML 属性 android:minHeight没有 android:maxHeight

          更烦人的是,RecyclerView 本身显然带有一个名为android:maxHeightXML 属性,但该属性不起作用

          【讨论】:

            【解决方案12】:

            您可以在 xml 代码中将特定高度设置为任何值,并将可见性设置为 gone。然后,当您想要对其进行膨胀时,您可以在 Java 中将可见性设置为 Visible。这是一个例子;

            .xml

            android:visibility="gone"
            

            .java

            recyclerView.setVisibility(View.VISIBLE);
            

            【讨论】:

              猜你喜欢
              • 2017-05-22
              • 1970-01-01
              • 2021-07-27
              • 2021-02-23
              • 2011-04-04
              • 2019-04-09
              • 1970-01-01
              • 1970-01-01
              • 2020-02-10
              相关资源
              最近更新 更多