web-dev-qa-db-fra.com

Grands espaces entre les éléments RecyclerView lors du défilement vers le bas

Je crée une application de liste de tâches et, tout en la testant, un énorme espace se forme entre les éléments lorsque j'essaie de faire défiler l'écran. Cela se produit toujours lorsque je déplace les éléments par glisser-déposer, mais je ne vois aucune erreur avec mon adaptateur ItemTouchHelper et ma classe de rappel. Ce serait génial si vous pouviez m'aider.

Avant:Before

Après:After

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>

Merci beaucoup à quiconque peut m'aider. Je tire mes cheveux pendant que je tape.

EDIT: J'ai confirmé que ce n'est pas ma classe ItemTouchHelper qui est le problème. (Un problème persiste.) Il semble également que, lorsqu'une boîte de dialogue est affichée et que le clavier est affiché, le RecyclerView en arrière-plan résout le problème par lui-même. Une fois la boîte de dialogue supprimée, le problème se répète (c.-à-d. Que le défilement place un espace énorme entre les éléments).

32

La réponse de Luksprog à la réponse de Gabriele Mariotti fonctionne.

Selon le doc

Avec la version 2.3.0, l'API LayoutManager propose une nouvelle fonctionnalité intéressante: mesure automatique! Cela permet à un RecyclerView de se redimensionner lui-même en fonction de la taille de son contenu. > Cela signifie que des scénarios précédemment indisponibles, tels que l'utilisation de WRAP_CONTENT> pour une dimension de RecyclerView, sont désormais possibles . Vous constaterez que tous les gestionnaires de mise en forme intégrés prennent désormais en charge la mesure automatique.

En raison de cette modification, veillez à bien vérifier les paramètres de mise en page des vues de vos éléments: les paramètres de mise en page précédemment ignorés (tels que MATCH_PARENT dans le sens du défilement) seront désormais pleinement respectés..

Dans la disposition de votre article, vous devez changer:

Android:layout_height="match_parent"

avec

Android:layout_height="wrap_content" 
76

changement dans la vue Recycler match_parent to wrap_content :

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

Changement également dans la disposition des éléments xml 

Définir la hauteur de disposition parent match_parent to 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"
        />

31
mohit

Cela m'est arrivé plusieurs fois!

Tout ce que vous avez à faire est de ... faire en sorte que layout_height du fichier de lignes soit wrap_content et que votre problème soit résolu ..

Android:layout_height="wrap_content"

Bonne codage!

3
Android Geek

C'est parce que vous utilisez match_parent in height de la vue racine de l'élément de ligne dans votre vue de liste/vue de recyclage orientée verticalement. Lorsque vous l'utilisez, l'élément se développe complètement par rapport à son parent . Utilisez wrap_content pour hauteur lorsque la vue recyclée est orientée verticalement et pour la largeur lorsqu'elle est orientée horizontalement.

2
saurabhlahoti

Pour mémoire, étant donné que dans mon cas, nous avons dû implémenter une "interface utilisateur super-fonctionnelle" avec le chevauchement de RecyclerView et de la barre d’outils pour les effets de flou, je devais me débarrasser de clipToPadding="false" dans 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"
/>

paddingTopet paddingBottom a fonctionné, mais nous l'avons remplacé par certains GapViews (vues vides, avec la hauteur de paddingTop et paddingBottom)

0
longilong

Vous pouvez essayer de configurer votre Viewgroup contenant la vue recyclée pour envelopper le contenu. 

0
amos godwin

Évitez de prendre la vue dans la disposition des éléments avec un conteneur comme celui-ci:

<?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>

comme dans ce cas, match_parent fera son travail et le problème restera! Prenez plutôt cela comme ça:

<?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>

[Remarque: la liaison de données est associée au code ci-dessus, n'utilisez pas les balises <layout> & <data> si vous n'utilisez pas la liaison de données]

Sinon, si vous devez utiliser des conteneurs de groupe de vues, examinez les attributs height et width du conteneur et essayez de remplacer ceux de match_parent par wrap_content. Cela devrait résoudre le problème. Pour plus de transparence, on peut essayer de donner des couleurs d'arrière-plan et de voir à travers pour identifier le problème réel.

0
Ashutosh Tiwari

j'ai ce problème et je viens d'utilisateur 

Android:layout_height="wrap_content"

pour parent de chaque article.

0
user2591714

si quelqu'un utilise | recyclerViewObject.setHasFixedSize (true);

essayez de l'enlever, cela causait le problème dans mon cas.

0
Shaheryar Malik