Équivalent de ListView.setEmptyView dans RecyclerView

Réponses:

69

Avec la nouvelle fonctionnalité de liaison de données, vous pouvez également y parvenir directement dans votre mise en page:

<TextView
   android:text="No data to display."
   android:visibility="@{dataset.size() > 0 ? View.GONE : View.VISIBLE}" />

Dans ce cas, il vous suffit d'ajouter une variable et une importation dans la section data de votre XML:

<data>
<import type="android.view.View"/>
<variable
    name="dataset"
    type="java.util.List&lt;java.lang.String&gt;"
    />
</data>
André Diermann
la source
6
L'exemple ci-dessus est simplifié afin de mettre l'accent sur l'approche de liaison de données. La liaison de données est très flexible. Vous pouvez bien sûr importer le Adapterau lieu du jeu de données et utiliser son getItemCount()ou tout envelopper dans un ViewModelet définir android:visibilitysur viewModel.getEmptyViewVisibility().
André Diermann
4
Cela devrait être voté plus haut, c'est un excellent exemple des capacités de liaison de données
Ed George
1
@javmarina Non, pour moi, la mise en page n'a pas continué à se mettre à jour. Si mon adaptateur commence par la taille 0 et que plus tard l'ensemble de données augmente, la mise en page ne sera pas mise à jour comme vous le souhaitez. Il semble que la liaison de données ne fonctionnera pas pour moi. :-(
meisteg
3
Cela va-t-il être mis à jour même si l'adaptateur augmente ou diminue dynamiquement à zéro? Je doute que.
david
1
@ a11n Cela ne met pas à jour la mise en page lorsque la liste se réduit à 0 ou obtient des données, nous devons définir la valeur de la liaison de la classe chaque fois que nous apportons des modifications à la liste, existe-t-il un moyen de mettre à jour la mise en page par elle-même?
Om Infowave Developers
114

Voici une classe similaire à @dragon born's, mais plus complète. Basé sur cet essentiel .

public class EmptyRecyclerView extends RecyclerView {
    private View emptyView;
    final private AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIfEmpty();
        }
    };

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

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

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

    void checkIfEmpty() {
        if (emptyView != null && getAdapter() != null) {
            final boolean emptyViewVisible = getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
            setVisibility(emptyViewVisible ? GONE : VISIBLE);
        }
    }

    @Override
    public void setAdapter(Adapter adapter) {
        final Adapter oldAdapter = getAdapter();
        if (oldAdapter != null) {
            oldAdapter.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }

        checkIfEmpty();
    }

    public void setEmptyView(View emptyView) {
        this.emptyView = emptyView;
        checkIfEmpty();
    }
}
Marc Plano-Lesay
la source
pouvez-vous s'il vous plaît expliquer comment je peux utiliser ce cours?
Ololoking
Eh bien exactement comme vous le feriez avec un RecyclerView, il ajoute simplement la setEmptyViewméthode, que vous pouvez appeler chaque fois que vous souhaitez définir la vue vide. Voir la ListView.setEmptyViewdocumentation si ce n'est pas clair, c'est la même idée.
Marc Plano-Lesay
5
Une implémentation similaire de Google Samples: github.com/googlesamples/android-XYZTouristAttractions/blob/…
jase
2
Solution cool mais un nom de classe est étrange =)
Шах
1
@AJW Je suppose que c'est principalement une question de ce que vous voulez réaliser. La différence entre les deux implémentations est vraiment mineure, et il n'y en a plus dès qu'un adaptateur est défini. Si vous ne changez pas l'adaptateur (ce qui est très probablement le cas), il n'y a pas de différence.
Marc Plano-Lesay
26

Solution fournie dans ce lien semble parfaite. Il utilise viewType pour identifier quand afficher emptyView. Pas besoin de créer un RecyclerView personnalisé

Ajout de code à partir du lien ci-dessus:

package com.example.androidsampleproject;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class RecyclerViewActivity extends Activity {

RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recycler_view);
    recyclerView = (RecyclerView) findViewById(R.id.myList);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(new MyAdapter());
}


private class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<String> dataList = new ArrayList<String>();

    public class EmptyViewHolder extends RecyclerView.ViewHolder {
        public EmptyViewHolder(View itemView) {
            super(itemView);
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView data;

        public ViewHolder(View v) {
            super(v);
            data = (TextView) v.findViewById(R.id.data_view);
        }
    }

    @Override
    public int getItemCount() {
        return dataList.size() > 0 ? dataList.size() : 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (dataList.size() == 0) {
            return EMPTY_VIEW;
        }
        return super.getItemViewType(position);
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder vho, final int pos) {
        if (vho instanceof ViewHolder) {
            ViewHolder vh = (ViewHolder) vho;
            String pi = dataList.get(pos);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v;

        if (viewType == EMPTY_VIEW) {
            v = LayoutInflater.from(parent.getContext()).inflate(R.layout.empty_view, parent, false);
            EmptyViewHolder evh = new EmptyViewHolder(v);
            return evh;
        }

        v = LayoutInflater.from(parent.getContext()).inflate(R.layout.data_row, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    private static final int EMPTY_VIEW = 10;
}

}
Sudhasri
la source
6
Je pense que l'extension de RecyclerView est une solution plus appropriée que celle-ci car en général, j'ai beaucoup d'adaptateurs de recyclage et je veux éviter d'ajouter ce type de logique à chacun d'entre eux.
Gunhan
Cela a du sens @Gunhan, lorsque vous utilisez de nombreux adaptateurs de recyclage. Vous pouvez également essayer d'étendre un seul BaseAdapter personnalisé pour les choses courantes dans tous
Sudhasri
2
Même si vous n'avez qu'un seul adaptateur et une seule vue recycleur, ce n'est pas la responsabilité de l'adaptateur. L'adaptateur est là pour présenter des articles, pas l'absence d'articles.
Marc Plano-Lesay
@Kernald Dépend de votre cas d'utilisation. Personnellement, je pense que c'est beaucoup plus propre comme Sudhasri l'a fait. Surtout si vous souhaitez afficher une vue différente au cas où aucun article ne serait présenté comme: "Aucun article ici, allez faire du shopping!" ou des trucs comme ça
AgentKnopf
@Zainodis Comme vous l'avez dit, c'est un point de vue différent. Ce n'est pas la responsabilité de l'adaptateur, qui est d'afficher les éléments dans la vue de recyclage, rien d'autre. Je conviens que techniquement parlant, les deux solutions fonctionnent et sont à peu près égales. Mais les éléments de l'adaptateur ne sont pas conçus pour afficher des vues comme celle-ci.
Marc Plano-Lesay
10

Je préférerais simplement une solution simple comme,

avoir votre RecyclerView dans un FrameLayout ou RelativeLayout avec un TextView ou une autre vue avec affichage d'un message de données vide avec visibilité GONE par défaut, puis dans la classe d'adaptateur, appliquez la logique

Ici, j'ai un TextView avec un message sans données

@Override
public int getItemCount() {
    textViewNoData.setVisibility(data.size() > 0 ? View.GONE : View.VISIBLE);
    return data.size();
}
Lalit Poptani
la source
3

Essayez RVEmptyObserver:

C'est une implémentation d'un AdapterDataObserverqui vous permet de définir simplement un Viewcomme disposition vide par défaut pour votre RecylerView. De cette façon, au lieu d'utiliser une personnalisation RecyclerViewet de vous rendre la vie plus difficile, vous pouvez facilement l'utiliser avec votre code existant:


Exemple d'utilisation:

RVEmptyObserver observer = new RVEmptyObserver(recyclerView, emptyView)
rvAdapter.registerAdapterDataObserver(observer);

Vous pouvez voir le code et l' exemple d'utilisation dans une application réelle ici.


Classe:

public class RVEmptyObserver extends RecyclerView.AdapterDataObserver {
    private View emptyView;
    private RecyclerView recyclerView;

    public RVEmptyObserver(RecyclerView rv, View ev) {
        this.recyclerView = rv;
        this.emptyView    = ev;
        checkIfEmpty();
    }

    private void checkIfEmpty() {
        if (emptyView != null && recyclerView.getAdapter() != null) {
            boolean emptyViewVisible = recyclerView.getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? View.VISIBLE : View.GONE);
            recyclerView.setVisibility(emptyViewVisible ? View.GONE : View.VISIBLE);
        }
    }

    public void onChanged() { checkIfEmpty(); }
    public void onItemRangeInserted(int positionStart, int itemCount) { checkIfEmpty(); }
    public void onItemRangeRemoved(int positionStart, int itemCount) { checkIfEmpty(); }
}
Sheharyar
la source
2

Ma version, basée sur https://gist.github.com/adelnizamutdinov/31c8f054d1af4588dc5c

public class EmptyRecyclerView extends RecyclerView {
    @Nullable
    private View emptyView;

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

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

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

    private void checkIfEmpty() {
        if (emptyView != null && getAdapter() != null) {
            emptyView.setVisibility(getAdapter().getItemCount() > 0 ? GONE : VISIBLE);
        }
    }

    private final AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkIfEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIfEmpty();
        }
    };

    @Override
    public void setAdapter(@Nullable Adapter adapter) {
        final Adapter oldAdapter = getAdapter();
        if (oldAdapter != null) {
            oldAdapter.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }
        checkIfEmpty();
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (null != emptyView && (visibility == GONE || visibility == INVISIBLE)) {
            emptyView.setVisibility(GONE);
        } else {
            checkIfEmpty();
        }
    }

    public void setEmptyView(@Nullable View emptyView) {
        this.emptyView = emptyView;
        checkIfEmpty();
    }
}
localhost
la source
3
Bonne idée à réimplémenter setVisibilityaussi.
Marc Plano-Lesay
2

Je préférerais implémenter cette fonctionnalité dans Recycler.

Sur votre méthode getItemCount remplacée, injectez des codes de contrôle vides ici:

@Override
public int getItemCount() {
    if(data.size() == 0) listIsEmtpy();
    return data.size();
}
Bilal
la source
3
Ce n'est pas la responsabilité de l'adaptateur. L'adaptateur est là pour présenter des articles, pas l'absence d'articles.
Marc Plano-Lesay
@Kernald C'est notre code et sa propre manière, comment nous le personnalisons et l'utilisons.
Lalit Poptani
@LalitPoptani bien sûr. Mais c'est un site de questions / réponses, où les gens recherchent des réponses, la plupart du temps sans réfléchir plus que "quel est le raccourci de copie?". Indiquer que la solution est sémantiquement erronée (d'ailleurs quand vous avez aussi des solutions «droites») n'est pas vraiment inutile…
Marc Plano-Lesay
@Kernald eh bien, je pense que cette solution est la plus simple de toutes et c'est aussi une bonne solution, car chaque fois que l'adaptateur est notifié, cela sera appelé et peut être utilisé pour vérifier la taille des données!
Lalit Poptani du
1
@ MarcPlano-Lesay a raison. Cette réponse est incomplète car elle ne gère pas le cas où la vue vide doit être invisible une fois que les éléments sont remplis. Après avoir implémenté cette partie, cette solution devient inefficace car chaque fois que l'adaptateur interroge le nombre d'éléments, setVisibility()est appelé. Bien sûr, vous pouvez ajouter des indicateurs pour compenser, mais c'est à ce moment que cela devient plus complexe.
razzledazzle
2

Si vous souhaitez prendre en charge plus d'états tels que l'état de chargement, l'état d'erreur, vous pouvez vérifier https://github.com/rockerhieu/rv-adapter-states . Sinon, la prise en charge de la vue vide peut être facilement implémentée à l'aide RecyclerViewAdapterWrapperde ( https://github.com/rockerhieu/rv-adapter ). Le principal avantage de cette approche est que vous pouvez facilement prendre en charge la vue vide sans changer la logique de l'adaptateur existant:

public class StatesRecyclerViewAdapter extends RecyclerViewAdapterWrapper {
    private final View vEmptyView;

    @IntDef({STATE_NORMAL, STATE_EMPTY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
    }

    public static final int STATE_NORMAL = 0;
    public static final int STATE_EMPTY = 2;

    public static final int TYPE_EMPTY = 1001;

    @State
    private int state = STATE_NORMAL;

    public StatesRecyclerViewAdapter(@NonNull RecyclerView.Adapter wrapped, @Nullable View emptyView) {
        super(wrapped);
        this.vEmptyView = emptyView;
    }

    @State
    public int getState() {
        return state;
    }

    public void setState(@State int state) {
        this.state = state;
        getWrappedAdapter().notifyDataSetChanged();
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        switch (state) {
            case STATE_EMPTY:
                return 1;
        }
        return super.getItemCount();
    }

    @Override
    public int getItemViewType(int position) {
        switch (state) {
            case STATE_EMPTY:
                return TYPE_EMPTY;
        }
        return super.getItemViewType(position);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_EMPTY:
                return new SimpleViewHolder(vEmptyView);
        }
        return super.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (state) {
            case STATE_EMPTY:
                onBindEmptyViewHolder(holder, position);
                break;
            default:
                super.onBindViewHolder(holder, position);
                break;
        }
    }

    public void onBindEmptyViewHolder(RecyclerView.ViewHolder holder, int position) {
    }

    public static class SimpleViewHolder extends RecyclerView.ViewHolder {
        public SimpleViewHolder(View itemView) {
            super(itemView);
        }
    }
}

Usage:

Adapter adapter = originalAdapter();
StatesRecyclerViewAdapter statesRecyclerViewAdapter = new StatesRecyclerViewAdapter(adapter, emptyView);
rv.setAdapter(endlessRecyclerViewAdapter);

// Change the states of the adapter
statesRecyclerViewAdapter.setState(StatesRecyclerViewAdapter.STATE_EMPTY);
statesRecyclerViewAdapter.setState(StatesRecyclerViewAdapter.STATE_NORMAL);
Hieu Rocker
la source
J'ai utilisé votre code comme base pour une solution similaire. Merci!
Albert Vila Calvo
2

J'ai corrigé ceci:
Création du fichier layout layout_recyclerview_with_emptytext.xml.
Créé EmptyViewRecyclerView.java
---------

EmptyViewRecyclerView emptyRecyclerView = (EmptyViewRecyclerView) findViewById (R.id.emptyRecyclerViewLayout);
emptyRecyclerView.addAdapter (mPrayerCollectionRecyclerViewAdapter, "Il n'y a pas de prière pour la catégorie sélectionnée.");

fichier layout_recyclerview_with_emptytext.xml

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/switcher"
>

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

<com.ninestars.views.CustomFontTextView android:id="@+id/recyclerViewEmptyTextView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Empty Text"
    android:layout_gravity="center"
    android:gravity="center"
    android:textStyle="bold"
    />

    </merge>


EmptyViewRecyclerView.java

public class EmptyViewRecyclerView extends ViewSwitcher {
private RecyclerView mRecyclerView;
private CustomFontTextView mRecyclerViewExptyTextView;

public EmptyViewRecyclerView(Context context) {
    super(context);
    initView(context);
}

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


private void initView(Context context) {
    LayoutInflater.from(context).inflate(R.layout.layout_recyclerview_with_emptytext, this, true);
    mRecyclerViewExptyTextView = (CustomFontTextView) findViewById(R.id.recyclerViewEmptyTextView);
    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
}

public void addAdapter(final RecyclerView.Adapter<?> adapter) {
    mRecyclerView.setAdapter(adapter);
    adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            if(adapter.getItemCount() > 0) {
                if (R.id.recyclerView == getNextView().getId()) {
                    showNext();
                }
            } else {
                if (R.id.recyclerViewEmptyTextView == getNextView().getId()) {
                    showNext();
                }
            }
        }
    });
}

public void addAdapter(final RecyclerView.Adapter<?> adapter, String emptyTextMsg) {
    addAdapter(adapter);
    setEmptyText(emptyTextMsg);
}

public RecyclerView getRecyclerView() {
    return mRecyclerView;
}

public void setEmptyText(String emptyTextMsg) {
    mRecyclerViewExptyTextView.setText(emptyTextMsg);
}

}
Ashwani
la source
1
public class EmptyRecyclerView extends RecyclerView {
  @Nullable View emptyView;

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

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

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

  void checkIfEmpty() {
    if (emptyView != null) {
      emptyView.setVisibility(getAdapter().getItemCount() > 0 ? GONE : VISIBLE);
    }
  }

  final @NotNull AdapterDataObserver observer = new AdapterDataObserver() {
    @Override public void onChanged() {
      super.onChanged();
      checkIfEmpty();
    }
  };

  @Override public void setAdapter(@Nullable Adapter adapter) {
    final Adapter oldAdapter = getAdapter();
    if (oldAdapter != null) {
      oldAdapter.unregisterAdapterDataObserver(observer);
    }
    super.setAdapter(adapter);
    if (adapter != null) {
      adapter.registerAdapterDataObserver(observer);
    }
  }

  public void setEmptyView(@Nullable View emptyView) {
    this.emptyView = emptyView;
    checkIfEmpty();
  }
}

quelque chose comme ça pourrait aider

Munawwar Hussain Shelia
la source
2
Ceci est incomplet. Vous devrez probablement masquer le RecyclerViewlorsque le emptyViewest visible (et le contraire). Vous aurez également besoin d'appel checkIfEmpty()sur onItemRangeInserted()et onItemRangeRemoved(). Oh, et vous auriez pu citer votre source: gist.github.com/adelnizamutdinov/31c8f054d1af4588dc5c
Marc Plano-Lesay
1

Vous pouvez simplement peindre le texte sur le RecyclerViewlorsqu'il est vide. De la commande suivant les supports empty, failed, loading, et les offlinemodes. Pour une compilation réussie, ajoutez de la recyclerView_stateTextcouleur à vos ressources.

/**
 * {@code RecyclerView} that supports loading and empty states.
 */
public final class SupportRecyclerView extends RecyclerView
{
    public enum State
    {
        NORMAL,
        LOADING,
        EMPTY,
        FAILED,
        OFFLINE
    }

    public SupportRecyclerView(@NonNull Context context)
    {
        super(context);

        setUp(context);
    }

    public SupportRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);

        setUp(context);
    }

    public SupportRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);

        setUp(context);
    }

    private Paint textPaint;
    private Rect textBounds;
    private PointF textOrigin;

    private void setUp(Context c)
    {
        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(ContextCompat.getColor(c, R.color.recyclerView_stateText));

        textBounds = new Rect();
        textOrigin = new PointF();
    }

    private State state;

    public State state()
    {
        return state;
    }

    public void setState(State newState)
    {
        state = newState;
        calculateLayout(getWidth(), getHeight());
        invalidate();
    }

    private String loadingText = "Loading...";

    public void setLoadingText(@StringRes int resId)
    {
        loadingText = getResources().getString(resId);
    }

    private String emptyText = "Empty";

    public void setEmptyText(@StringRes int resId)
    {
        emptyText = getResources().getString(resId);
    }

    private String failedText = "Failed";

    public void setFailedText(@StringRes int resId)
    {
        failedText = getResources().getString(resId);
    }

    private String offlineText = "Offline";

    public void setOfflineText(@StringRes int resId)
    {
        offlineText = getResources().getString(resId);
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        String s = stringForCurrentState();
        if (s == null)
            return;

        canvas.drawText(s, textOrigin.x, textOrigin.y, textPaint);
    }

    private void calculateLayout(int w, int h)
    {
        String s = stringForCurrentState();
        if (s == null)
            return;

        textPaint.setTextSize(.1f * w);
        textPaint.getTextBounds(s, 0, s.length(), textBounds);

        textOrigin.set(
         w / 2f - textBounds.width() / 2f - textBounds.left,
         h / 2f - textBounds.height() / 2f - textBounds.top);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);

        calculateLayout(w, h);
    }

    private String stringForCurrentState()
    {
        if (state == State.EMPTY)
            return emptyText;
        else if (state == State.LOADING)
            return loadingText;
        else if (state == State.FAILED)
            return failedText;
        else if (state == State.OFFLINE)
            return offlineText;
        else
            return null;
    }
}
Aleks N.
la source
1

De mon point de vue, le moyen le plus simple de créer une vue vide est de créer un nouveau RecyclerView vide avec la disposition que vous souhaitez gonfler en arrière-plan. Et cet adaptateur vide est défini lorsque vous vérifiez la taille de votre ensemble de données.

user7108272
la source