Используйте RecyclerView внутри ScrollView с гибкой высотой элемента Recycler

Я хочу знать, есть ли способ использовать RecyclerView?

До этого я использовал RecyclerView с фиксированной высотой внутри ScrollView, но на этот раз я не знаю высоту элемента.

Подсказка: я прочитал все вопросы и решения по вопросу о стеке, прежде чем задавать этот вопрос.

обновление: некоторые решения показывают, как прокручивать RecyclerView самостоятельно, но я хочу показать его расширенным.


person Ashkan    schedule 06.09.2015    source источник
comment
В чем твоя проблема?   -  person Omar Hassan    schedule 06.09.2015
comment
@OmarHassan Мне следует использовать более одного RecyclerView внутри ScrollView. только это   -  person Ashkan    schedule 07.09.2015
comment
ничего из вышеперечисленного не поможет мне... только этот ответ здесь: Recyclerview внутри scrollview   -  person Ester Kaufman    schedule 02.05.2016
comment
@EsterOr, что ты именно хочешь сделать? Я работаю над своей проблемой около 2 недель до. (тогда я не был экспертом)   -  person Ashkan    schedule 03.05.2016
comment
Просто хочу помочь другим с похожей проблемой... как и я....   -  person Ester Kaufman    schedule 03.05.2016
comment
вы можете попробовать flexbox в recyclerview для гибкой прокрутки yuvarockers.blogspot.in /2017/04/   -  person YLS    schedule 23.04.2017


Ответы (8)


Если вы хотите просто прокручивать, вы можете использовать NestedScrollView вместо ScrollView. Таким образом, вы можете изменить свой код следующим образом:

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

            //design your content here with RecyclerView 

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>
person Bhunnu Baba    schedule 15.10.2016
comment
NestedScrollView вместо ScrollView решил мою проблему, спасибо! - person careful7j; 30.03.2018
comment
Это должен быть принятый ответ. Нет ConstraintLayout, нет пользовательских подклассов. Это просто работает по назначению. - person Adam; 23.06.2018

Я ищу ответ на этот вопрос по всему миру, но не нашел прямого ответа на этот популярный вопрос. Наконец-то я смешал некоторые трюки и решил эту проблему!

Моя проблема началась, когда мой начальник попросил меня использовать RecyclerView внутри ScrollView, а, как вы знаете, мы не можем использовать два объекта Scrollable друг в друге. за исключением случаев, когда мы устанавливаем или знаем фиксировать высоту элемента для нашего RecyclerView. и это ответ:

Шаг 1: сначала вы должны найти высоту гибкого элемента RecyclerView, и это возможно из вашего RecyclerView>onBindViewHolder.

holder.itemView.post(new Runnable() {
        @Override
        public void run() {

            int cellWidth = holder.itemView.getWidth();// this will give you cell width dynamically
            int cellHeight = holder.itemView.getHeight();// this will give you cell height dynamically

            dynamicHeight.HeightChange(position, cellHeight); //call your iterface hear
        }
    });

с помощью этого кода вы определяете высоту своего элемента по мере их создания и отправляете высоту элемента в свою деятельность с помощью интерфейса.

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

public interface DynamicHeight {
    void HeightChange (int position, int height);
}

Шаг 2: мы нашли высоту нашего элемента, и теперь мы хотим установить высоту для нашего RecyclerView. сначала мы должны вычислить сумму высоты элемента. на этом шаге мы делаем это с помощью BitMap первого реализует последнего шага интерфейса и пишем этот код ниже внутри вашего Activity или Фрагмент, определяющий ваш RecyclerView:

@Override
public void HeightChange(int position, int height) {
    itemHeight.put(position, height);
    sumHeight = SumHashItem (itemHeight);

    float density = activity.getResources().getDisplayMetrics().density;
    float viewHeight = sumHeight * density;
    review_recyclerView.getLayoutParams().height = (int) sumHeight;

    int i = review_recyclerView.getLayoutParams().height;
}

int SumHashItem (HashMap<Integer, Integer> hashMap) {
    int sum = 0;

    for(Map.Entry<Integer, Integer> myItem: hashMap.entrySet())  {
        sum += myItem.getValue();
    }

    return sum;
}

Шаг 3: теперь у нас есть сумма вашей высоты RecyclerView. на последнем шаге мы должны просто отправить интерфейс, который мы написали на последнем шаге, в адаптер с таким кодом:

reviewRecyclerAdapter = new ReviewRecyclerAdapter(activity, reviewList, review_recyclerView, this);

когда вы реализуете интерфейс, вы должны отправить его в свой контекст, который я использую этот.

Наслаждайся этим

person Ashkan    schedule 11.09.2015
comment
я не могу понять это... получаю некоторые ошибки... не могли бы вы предоставить полный пример с классом адаптера и реализацией recyclerview - person H Raval; 26.10.2015
comment
@HetalUpadhyay, в какой части у вас ошибка? на этой неделе у меня не хватает времени, чтобы сделать это. но если ты не торопишься, я сделаю это за тебя - person Ashkan; 26.10.2015
comment
на самом деле я не получаю никакой ошибки, но когда я пробовал тот же код с горизонтальным просмотром ресайклера, он ничего не отображал... поэтому я буду вам благодарен, если вы можете предоставить код, который отлично работает как в случае горизонтальной, так и вертикальной прокрутки. - person H Raval; 26.10.2015
comment
@HetalUpadhyay, можешь объяснить, что ты хочешь сделать? потому что у меня есть код для расчета, сколько элементов должно быть в горизонтальной форме с фиксированной шириной - person Ashkan; 26.10.2015
comment
@HetalUpadhyay хорошо, понял. Постараюсь сделать это в пятницу. пришлите мне письмо: [email protected] - person Ashkan; 26.10.2015
comment
извините, я забыл упомянуть, что я использую GridLayoutManager не Linear - person H Raval; 26.10.2015
comment
спасибо... отлично сработало для меня, просто добавил android:fillViewport=true в scrollview, и он начал работать - person H Raval; 26.10.2015
comment
похоже, что переменная viewHeight никогда не используется - person hornet2319; 13.05.2016
comment
Это гораздо сложнее, чем необходимо. Посмотрите на ответ @Bhunnu Baba. - person Adam; 23.06.2018

Используйте эту строку для вашего recyclerview:

 android:nestedScrollingEnabled="false"

попробуйте, recyclerview будет плавно прокручиваться с гибкой высотой

person iDeveloper    schedule 20.12.2016
comment
просто для записей, он доступен из API 21 - person Ewoks; 11.07.2018

[РЕШЕНО] У меня такая же проблема с горизонтальным повторным просмотром. Изменить репозиторий Gradle для recycleview

 compile 'com.android.support:recyclerview-v7:23.2.1'

Напишите это: linearLayoutManager.setAutoMeasureEnabled(true);

Исправлены ошибки, связанные с различными методами измерения в обновлении.

Проверьте http://developer.android.com/intl/es/tools/support-library/features.html#v7-recyclerview

Я обнаружил проблему с библиотекой 23.2.1: когда элемент match_parent recycle view заполняет весь элемент для просмотра, всегда используйте min height or "wrap_content".

Спасибо

person Amit    schedule 01.04.2016

Чтобы исправить бросок в RecyclerView, вы должны переопределить canScrollVertically в LinearLayoutManager:

linearLayoutManager = new LinearLayoutManager(context) {
 @Override
 public boolean canScrollVertically() {
  return false;
 }
};
person Michał Ciołek    schedule 22.04.2016
comment
Чтобы добавить к этому ответу, вам также необходимо использовать NestedScrollView, один только этот ответ не работал на Android 7+:\ - person JustADev; 15.12.2017

Если установка фиксированной высоты для RecyclerView не сработала для кого-то (например, для меня), вот что я добавил к решению с фиксированной высотой:

   mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        int action = e.getAction();
        switch (action) {
        case MotionEvent.ACTION_MOVE:
            rv.getParent().requestDisallowInterceptTouchEvent(true);
            break;
    }
    return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {

}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

I

person John smith    schedule 06.09.2015
comment
Я еще не проверял это, но я думаю, что ваш код хочет прокручивать RecyclerView самостоятельно. Я попробую сегодня. спасибо дорогой друг - person Ashkan; 07.09.2015
comment
я не помог, как я уже говорил, это помогает прокручивать RecyclerView самостоятельно с фиксированной высотой. это не моя цель. - person Ashkan; 07.09.2015

Я полностью согласен с решением Ашкана, большое спасибо (проголосовал +1!), но есть одно но...

Если RecyclerView правильно прокручивается внутри ScrollView/NestedScrollView, НО он не сбрасывается (перехватывает его), тогда решение состоит в том, чтобы расширить RecyclerView и переопределить OnInterceptTouchEvent и OnTouchEvent. Если вам не нужны какие-либо действия по щелчку, но вы просто хотите представить элементы с рабочим переходом, просто верните false в обоих случаях, как показано ниже:

public class InterceptingRecyclerView extends RecyclerView {

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

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

    public InterceptingRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }
}

Или на самом деле это должно называться NonIntercepting... ;) Вот так просто.

person Darek Deoniziak    schedule 08.01.2016

Я решил эту проблему, используя NestedScrollView вместо ScrollView. И для RecyclerView

    <android.support.v7.widget.RecyclerView 
android:layout_width="match_parent"
  android:layout_height="match_parent" />

И в коде

recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);
person Arun PK    schedule 20.07.2018