Entspricht ListView.setEmptyView in RecyclerView

Antworten:

68

Mit der neuen Datenbindungsfunktion können Sie dies auch direkt in Ihrem Layout erreichen:

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

In diesem Fall müssen Sie nur eine Variable und einen Import zum Datenabschnitt Ihres XML hinzufügen:

<data>
<import type="android.view.View"/>
<variable
    name="dataset"
    type="java.util.List&lt;java.lang.String&gt;"
    />
</data>
André Diermann
quelle
6
Das obige Beispiel wird vereinfacht, um den Datenbindungsansatz hervorzuheben. Die Datenbindung ist sehr flexibel. Sie könnten das natürlich importieren Adapteranstelle des Datensatzes und dessen Verwendung getItemCount()oder wickeln alles in einem ViewModelund Satz android:visibilityzu viewModel.getEmptyViewVisibility().
André Diermann
4
Dies sollte höher gewählt werden, es ist ein hervorragendes Beispiel für die Datenbindungsfähigkeiten
Ed George
1
@javmarina Nein, für mich wurde das Layout nicht weiter aktualisiert. Wenn mein Adapter mit der Größe 0 beginnt und später der Datensatz wächst, wird das Layout nicht wie gewünscht aktualisiert. Es scheint, dass die Datenbindung bei mir nicht funktioniert. :-(
meisteg
3
Wird dies aktualisiert, selbst wenn der Adapter dynamisch wächst oder auf Null schrumpft? Ich bezweifle das.
David
1
@ a11n Das Layout wird nicht aktualisiert, wenn die Liste auf 0 verkleinert wird oder Daten abgerufen werden. Wir müssen jedes Mal, wenn wir Änderungen an der Liste vornehmen, einen Wert für die Bindung der Klasse festlegen. Gibt es eine Möglichkeit, das Layout selbst zu aktualisieren?
Om Infowave Entwickler
114

Hier ist eine Klasse ähnlich der von @dragon born, aber vollständiger. Basierend auf diesem Kern .

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
quelle
Kannst du mir bitte erklären, wie ich diese Klasse benutzen kann?
Ololoking
Genau wie bei einer RecyclerView wird lediglich die setEmptyViewMethode hinzugefügt, die Sie aufrufen können, wann immer Sie die leere Ansicht definieren möchten. Lesen Sie die ListView.setEmptyViewDokumentation, wenn es unklar ist, es ist die gleiche Idee.
Marc Plano-Lesay
5
Eine ähnliche Implementierung von Google Samples: github.com/googlesamples/android-XYZTouristAttractions/blob/…
jase
2
Coole Lösung , sondern ein Klassenname ist seltsam =)
Шах
1
@AJW Ich denke, es ist hauptsächlich eine Frage dessen, was Sie erreichen wollen. Der Unterschied zwischen den beiden Implementierungen ist sehr gering, und sobald ein Adapter eingestellt ist, ist keiner mehr übrig. Wenn Sie den Adapter nicht wechseln (was höchstwahrscheinlich der Fall ist), gibt es keinen Unterschied.
Marc Plano-Lesay
26

Die in diesem Link bereitgestellte Lösung scheint perfekt zu sein. Mithilfe von viewType wird ermittelt, wann emptyView angezeigt werden soll. Sie müssen keine benutzerdefinierte RecyclerView erstellen

Hinzufügen von Code über den obigen Link:

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
quelle
6
Ich denke, die Erweiterung von RecyclerView ist eine geeignetere Lösung als diese, da ich im Allgemeinen viele Recycler-Adapter habe und vermeiden möchte, dass jeder von ihnen diese Art von Logik hinzufügt.
Gunhan
Das macht @Gunhan Sinn, wenn viele Recycler-Adapter verwendet werden. Sie können auch versuchen, einen einzelnen BaseAdapter zu erweitern, der für alle gängigen Dinge angepasst ist
Sudhasri
2
Selbst wenn Sie nur einen Adapter und eine Recycler-Ansicht haben, liegt dies nicht in der Verantwortung des Adapters. Der Adapter dient dazu, Elemente zu präsentieren, nicht das Fehlen von Elementen.
Marc Plano-Lesay
@Kernald Hängt von Ihrem Anwendungsfall ab. Persönlich denke ich, dass es viel sauberer ist, wie Sudhasri es getan hat. Vor allem, wenn Sie eine andere Ansicht zeigen möchten, wenn keine Artikel präsentiert werden, wie: "Keine Artikel hier, gehen Sie einkaufen!" oder
solche
@ Zainodis Wie Sie sagten, ist es eine andere Ansicht. Es liegt nicht in der Verantwortung des Adapters, Elemente in der Recyclingansicht anzuzeigen, sondern in nichts anderem. Ich stimme zu, dass beide Lösungen technisch gesehen funktionieren und ziemlich gleich sind. Die Elemente des Adapters sind jedoch nicht für die Anzeige solcher Ansichten vorgesehen.
Marc Plano-Lesay
10

Ich würde einfach eine einfache Lösung bevorzugen, wie:

Lassen Sie Ihre RecyclerView in einem FrameLayout oder RelativeLayout mit einer TextView oder einer anderen Ansicht mit der Anzeige leerer Datennachrichten mit der Sichtbarkeit GONE standardmäßig GEGEN und wenden Sie dann in der Adapterklasse die Logik an

Hier habe ich eine Textansicht mit Nachricht ohne Daten

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

Versuchen Sie RVEmptyObserver:

Es ist eine Implementierung von a AdapterDataObserver, mit der Sie einfach ein Viewals Standardleerlayout für Ihr Layout festlegen können RecylerView. Auf diese Weise können Sie einen benutzerdefinierten RecyclerViewCode problemlos verwenden , anstatt einen benutzerdefinierten Code zu verwenden und Ihr Leben zu erschweren:


Anwendungsbeispiel:

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

Sie können den Code und die Beispielverwendung in einer tatsächlichen App hier sehen.


Klasse:

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
quelle
2

Meine Version basiert auf 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
quelle
3
Gute Idee, auch neu setVisibilityzu implementieren .
Marc Plano-Lesay
2

Ich würde es vorziehen, diese Funktionalität in Recycler.Adapter zu implementieren

Fügen Sie bei Ihrer überschriebenen getItemCount-Methode dort leere Prüfcodes ein:

@Override
public int getItemCount() {
    if(data.size() == 0) listIsEmtpy();
    return data.size();
}
Bilal
quelle
3
Es liegt nicht in der Verantwortung des Adapters. Der Adapter dient dazu, Elemente zu präsentieren, nicht das Fehlen von Elementen.
Marc Plano-Lesay
@Kernald Es ist unser Code und unsere eigene Art, wie wir ihn anpassen und verwenden.
Lalit Poptani
@LalitPoptani sicher. Aber es ist eine Q & A-Website, auf der die Leute meistens nach Antworten suchen, ohne mehr als "Was ist die Kopierverknüpfung noch einmal?" Zu überlegen. Es ist nicht wirklich nutzlos
anzugeben,
@Kernald gut Ich denke, diese Lösung ist die einfachste von allen und es ist auch eine gute Lösung, denn jedes Mal, wenn der Adapter benachrichtigt wird, wird dies aufgerufen und kann verwendet werden, um die Größe der Daten zu überprüfen!
Lalit Poptani
1
@ MarcPlano-Lesay ist richtig. Diese Antwort ist unvollständig, da sie den Fall nicht behandelt, wenn die leere Ansicht unsichtbar sein muss, sobald die Elemente gefüllt sind. Nach der Implementierung dieses Teils wird diese Lösung ineffizient, da jedes Mal, wenn der Adapter die Anzahl der Elemente abfragt, setVisibility()aufgerufen wird. Sicher, Sie könnten einige Flags hinzufügen, um dies zu kompensieren, aber dann wird es komplexer.
Razzledazzle
2

Wenn Sie weitere Status wie Ladezustand und Fehlerstatus unterstützen möchten, können Sie https://github.com/rockerhieu/rv-adapter-states auschecken . Andernfalls kann die Unterstützung der leeren Ansicht einfach mithilfe RecyclerViewAdapterWrappervon ( https://github.com/rockerhieu/rv-adapter ) implementiert werden . Der Hauptvorteil dieses Ansatzes besteht darin, dass Sie die leere Ansicht problemlos unterstützen können, ohne die Logik des vorhandenen Adapters zu ändern:

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

Verwendung:

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
quelle
Ich habe Ihren Code als Grundlage für eine ähnliche Lösung verwendet. Vielen Dank!
Albert Vila Calvo
2

Ich habe
Folgendes behoben: Erstellt die Datei layout layout_recyclerview_with_emptytext.xml.
Erstellt EmptyViewRecyclerView.java
---------

EmptyViewRecyclerView emptyRecyclerView = (EmptyViewRecyclerView) findViewById (R.id.emptyRecyclerViewLayout);
emptyRecyclerView.addAdapter (mPrayerCollectionRecyclerViewAdapter, "Für die ausgewählte Kategorie gibt es kein Gebet.");

Datei 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
quelle
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();
  }
}

so etwas könnte helfen

Munawwar Hussain Shelia
quelle
2
Dies ist unvollständig. Sie müssen wahrscheinlich das ausblenden, RecyclerViewwenn das emptyViewsichtbar ist (und das Gegenteil). Lassen Sie sich bei Anruf müssen checkIfEmpty()auf onItemRangeInserted()und onItemRangeRemoved(). Oh, und Sie hätten Ihre Quelle zitieren können: gist.github.com/adelnizamutdinov/31c8f054d1af4588dc5c
Marc Plano-Lesay
1

Sie können den Text einfach auf malen, RecyclerViewwenn er leer ist. Die folgende benutzerdefinierte Unterklasse unterstützt empty, failed, loading, und offlineModi. Für eine erfolgreiche Kompilierung fügen Sie recyclerView_stateTextIhren Ressourcen Farbe hinzu.

/**
 * {@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.
quelle
1

Aus meiner Sicht besteht die einfachste Möglichkeit, eine leere Ansicht zu erstellen, darin, eine neue leere RecyclerView mit einem Layout zu erstellen, das Sie als Hintergrund aufblasen möchten. Und dieser leere Adapter wird festgelegt, wenn Sie die Größe Ihres Datensatzes überprüfen.

user7108272
quelle