При прокрутке вниз между элементами RecyclerView образуется большой зазор

Я делаю приложение со списком ToDo, и во время его тестирования по какой-то причине возникает огромный разрыв между элементами, когда я пытаюсь прокрутить вниз. Это всегда происходит, когда я перетаскиваю элементы, но я не вижу никаких ошибок с моим адаптером ItemTouchHelper и классом обратного вызова. Было бы здорово, если бы ты мне помог.

До: До

После: После

RecyclerAdapter.java

public class RecyclerAdapter extends                                                                                                                                 

RecyclerView.Adapter<RecyclerAdapter.RecyclerVH> implements ItemTouchHelperAdapter{
private LayoutInflater layoutInflater;
ArrayList<Info> data;
Context context;

public RecyclerAdapter(Context context) {
    layoutInflater = LayoutInflater.from(context);
    this.context = context;
}

public void setData(ArrayList<Info> data) {
    this.data = data;
    notifyDataSetChanged();
}

@Override
public RecyclerVH onCreateViewHolder(ViewGroup viewGroup, int position) {
    View view = layoutInflater.inflate(R.layout.custom_row, viewGroup, false);
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("R.A onClick Owen", "onClick method triggered");
        }
    });
    RecyclerVH recyclerVH = new RecyclerVH(view);
    return recyclerVH;
}

@Override
public void onBindViewHolder(RecyclerVH recyclerVH, int position) {
    Log.d("RecyclerView", "onBindVH called: " + position);

    final Info currentObject = data.get(position);
    // Current Info object retrieved for current RecyclerView item - USED FOR DELETE
    recyclerVH.listTitle.setText(currentObject.title);
    recyclerVH.listContent.setText(currentObject.content);

    /*recyclerVH.listTitle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Open new Activity containing note content
            Toast.makeText(this, "Opening: " + currentObject.title, Toast.LENGTH_LONG).show();
        }
    });*/
}

public void deleteItem(int position) {
    DBInfo dbInfo = new DBInfo(context);
    dbInfo.deleteNote(data.get(position));
    // Deletes RV item/position's Info object

    data.remove(position);
    // Removes Info object at specified position

    notifyItemRemoved(position);
    // Notifies the RV that item has been removed
}


@Override
public int getItemCount() {
    return data.size();
}

// This is where the Swipe and Drag-And-Drog methods come into place
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    // Swapping positions
    // ATTEMPT TO UNDERSTAND WHAT IS GOING ON HERE
    Collections.swap(data, fromPosition, toPosition);
    notifyItemMoved(fromPosition, toPosition);
    return true;
}

@Override
public void onItemDismiss(int position) {
    // Deleting item from RV and DB
    deleteItem(position);
}

class RecyclerVH extends RecyclerView.ViewHolder implements View.OnClickListener{
    // OnClickListener is implemented here
    // Can also be added at onBindViewHolder above
    TextView listTitle, listContent;

    public RecyclerVH(View itemView) {
        super(itemView);

        listTitle = (TextView) itemView.findViewById(R.id.title);
        listContent = (TextView) itemView.findViewById(R.id.content);

        listTitle.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(context, "Opening: Note" + getLayoutPosition(), Toast.LENGTH_SHORT).show();
        // PS NEVER ADD listTitle VARIABLE AS PUBLIC VARIABLE ABOVE WHICH IS GIVEN VALUE AT ONBINDVH
        // THIS IS BECAUSE THE VALUE WILL CHANGE IF ITEM IS ADDED OR DELETED
    }
}
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:weightSum="1">

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/rounded_corners" />

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <com.melnykov.fab.FloatingActionButton
            android:id="@+id/fab_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginBottom="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginEnd="16dp"
            android:gravity="bottom|end"
            android:onClick="addNote"
            android:src="@drawable/fab_ic_add"
            fab:fab_colorNormal="@color/colorPrimary"
            fab:fab_colorPressed="@color/colorPrimaryDark"
            fab:fab_colorRipple="@color/colorPrimaryDark" />
    </RelativeLayout>
</FrameLayout>
</LinearLayout>

custom_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:id="@+id/main"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:padding="8dp"
        android:text="@string/test"
        android:textSize="18sp"
        android:textStyle="bold" />
</LinearLayout>
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/main"
    android:paddingLeft="8dp">
    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/test"
        android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>

Большое спасибо тем, кто может мне помочь. Я выдергиваю волосы, когда печатаю.

РЕДАКТИРОВАТЬ: Я подтвердил, что проблема не в моем классе ItemTouchHelper. (Пробовал работать без его вызова, проблема все еще возникает.) Кроме того, кажется, что когда отображается диалоговое окно и открывается клавиатура, RecyclerView в фоновом режиме решает проблему сам по себе. После удаления диалога проблема повторяется (например, при прокрутке между элементами появляется огромное пространство)


person PlanetAstro_William    schedule 05.03.2016    source источник
comment
Вероятно, дело не в вашем коде. Речь идет о ваших макетах. Покажите здесь макеты, которые вы используете.   -  person Doug Stevenson    schedule 05.03.2016
comment
@DougStevenson Я очень сомневаюсь, что это будут мои макеты, хотя до того, как возникла эта проблема, я их вообще не трогал. Тем не менее, я все равно буду благодарен за любую информацию, которую вы можете предоставить.   -  person PlanetAstro_William    schedule 05.03.2016
comment
возможно, это причина stackoverflow.com/questions/35728179/   -  person user    schedule 06.03.2016
comment
@Luksprog OMG ВЫ СОХРАНИЛИ МОЮ ЖИЗНЬ СПАСИБО СПАСИБО   -  person PlanetAstro_William    schedule 06.03.2016
comment
Удалите Match_parent с высоты относительного макета в файле custom.XML.   -  person S HemaNandhini    schedule 16.01.2017


Ответы (9)


Ответ Luksprog на ответ Габриэле Мариотти работает.

Согласно doc

В версии 2.3.0 в LayoutManager API появилась новая захватывающая функция: автоматическое измерение! Это позволяет RecyclerView изменять свой размер в зависимости от размера его содержимого. > Это означает, что теперь возможны ранее недоступные сценарии, такие как использование WRAP_CONTENT> для измерения RecyclerView. Вы обнаружите, что все встроенные менеджеры LayoutManager теперь поддерживают автоматическое измерение.

Из-за этого изменения не забудьте дважды проверить параметры макета представлений ваших элементов: ранее игнорировавшиеся параметры макета (например, MATCH_PARENT в прокрутке направление) теперь будет полностью соблюдаться.

В макете вашего элемента вы должны изменить:

android:layout_height="match_parent"

с участием

android:layout_height="wrap_content" 
person PlanetAstro_William    schedule 06.03.2016
comment
как сказал @mohit, нам также нужно иметь родительский макет item_layout как: xml android:layout_height="wrap_content" иначе он не будет работать - person Hissaan Ali; 03.08.2019

измените представление match_parent в Recycler на wrap_content:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

Также измените макет элемента xml

Сделайте высоту родительского макета match_parent на wrap_content

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        />

person mohit    schedule 21.12.2016

Это случалось со мной много раз!

Все, что вам нужно сделать, это ... сделать layout_height строкового файла wrap_content и ваша проблема решена ..

android:layout_height="wrap_content"

Удачного кодирования!

person Android Geek    schedule 03.05.2018

Это потому, что вы используете match_parent на высоте корневого представления элемента строки в вашем вертикально ориентированном представлении списка / recyclerview. Когда вы используете это, элемент полностью разворачивается по отношению к своему родителю. Используйте wrap_content для высоты, когда recyclerview ориентирован вертикально, и для ширины, когда он ориентирован горизонтально.

person saurabhlahoti    schedule 30.08.2017

Избегайте использования представления в макете элемента с таким контейнером:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

<data/>

<android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

<TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:listPreferredItemHeight"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</android.support.constraint.ConstraintLayout>
</layout>

поскольку в этом случае match_parent сделает свою работу, и проблема все равно останется! Скорее примите это так:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:listPreferredItemHeight"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</layout>

[Примечание. Код выше имеет привязку данных, не используйте теги <layout> & <data>, если не используете привязку данных]

Помимо этого, если вам необходимо использовать какие-либо контейнеры группы представлений, посмотрите атрибуты высоты и ширины в контейнере и попробуйте изменить их с match_parent на wrap_content. Это должно решить проблему. Для большей прозрачности можно попробовать задать цвет фона и увидеть сквозь него, чтобы определить настоящую проблему.

person Ashutosh Tiwari    schedule 05.12.2017

Для записи: так как в моем случае нам пришлось реализовать некий «сверхъестественный интерфейс» с перекрытием RecyclerView и панелью инструментов эффекта размытия, мне пришлось избавиться от clipToPadding="false" в RecyclerView-xml.

<android.support.v7.widget.RecyclerView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:paddingTop="@dimen/height_toolbar"
  android:paddingBottom="@dimen/height_bottom_bar_container"
  //android:clipToPadding="false" <-- remove this flag!
  android:scrollbars="vertical"
/>

paddingTopи paddingBottom работали, но мы заменили его некоторыми GapView (пустые представления, с высотой paddingTop и paddingBottom)

person longi    schedule 09.04.2018

если кто-то использует | recyclerViewObject.setHasFixedSize (true);

попробуйте удалить его, в моем случае это было причиной проблемы.

person Shaheryar Malik    schedule 04.07.2018

Вы можете попробовать настроить свою Viewgroup, удерживая recyclerview, чтобы обернуть контент

person amos godwin    schedule 10.02.2019
comment
если это не сработает, тогда ваш файл макета recyclerview android: layout_height = wrap_content - person amos godwin; 10.02.2019

у меня есть эта проблема, и я просто использую

android:layout_height="wrap_content"

для родителя каждого элемента.

person mohammad mobasher    schedule 31.08.2017