Как установить RecyclerView Max Height

Я хочу установить максимальную высоту 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.

Как я могу установить это? Пожалуйста, помогите мне, я застрял с этим

6 ответов

Решение

Вот то, что вам нужно. Создайте подкласс 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.

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>

Я думаю, это сработает, по крайней мере, у меня это сработало

<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_max а также constraintHeight_min в соответствии с вашими потребностями.

Мы можем немного оптимизировать метод @Fattum. Мы можем использовать app:maxHeight установить maxHeight, Можно использовать dp или же px как вам нравится.

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>

Попробовав слишком много сложных предложений, я наконец понял это методом проб и ошибок.

Во-первых, оберните RecyclerView каким-нибудь макетом. В моем случае я использовал макет ограничения, и у меня даже были другие элементы в этом макете выше и ниже RecyclerView. Задайте высоту макета для автоматической настройки, установив его на 0dp, затем установите ограничение высоты макета по умолчанию как обтекание и определите ограничение максимальной высоты макета.

Затем в вашем 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>

Надеюсь это поможет!

Я добавлю свои 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>

Напиши эти заявления внутри, если еще и дай мне знать,

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

Если у вас есть 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);
}

Это работает как для линейных, так и для Grid RecyclerViews, вам просто нужно немного поиграть с числами на свой вкус. Не забудьте установить высоту WRAP_CONTENT после заполнения RecyclerView.

Возможно, вам также придется заново устанавливать высоту каждый раз, когда изменяется размер myElementList, но это не большая проблема.

Вы можете использовать WRAP_CONTENT в вашем RecyclerView. Он будет автоматически измерять ваш просмотрщик в соответствии с его содержанием.

Вы также можете рассчитать текущую высоту и установить максимальную высоту. Так что 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);
        }
    }

Самый простой способ - использовать 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, повторное просмотр не будет прокручиваться. В качестве решения добавьте приведенный ниже код в создание действия.

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;
    }

Это обеспечит фиксированную высоту только на поддерживаемых устройствах, а полный просмотр корзины будет отображаться на старых устройствах.

Дайте мне знать, если есть какой-нибудь лучший способ.

У меня была такая же проблема, и я хотел поделиться новым, актуальным ответом. Этот работает как минимум на Android 9 и Android Studio v. 4.0.

Оберните RecyclerView в ConstraintLayout, как предлагают некоторые из ответов здесь. Но не похоже, что вы можете установить максимальную высоту этого макета в XML. Вместо этого вы должны установить его в коде, как показано ниже: дайте ConstraintLayout идентификатор, а затем в своем методе 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, по-видимому, имеет атрибут XML с именем android:maxHeight, но этот атрибут не работает.

Вы можете просто установить конкретную высоту для любого значения в коде xml и установить видимость исчезнувшей. Затем вы устанавливаете видимость Visible в Java, когда хотите его накачать. Вот пример;

.xml

android:visibility="gone"

.Джава

recyclerView.setVisibility(View.VISIBLE);
Другие вопросы по тегам