RecyclerView ile boş bir görünüm nasıl gösterilir?


271

Ben düzen dosyası içinde bir özel görünüm koymak için alışkınım açıklanan ListActivitybelgelere edilecek hiçbir veri yokken görüntülenen . Bu görünüm kimliğe sahip "android:id/empty".

<TextView
    android:id="@android:id/empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/no_data" />

Acaba bu yeni ile nasıl yapılabilir RecyclerView?


2
Github.com/rockerhieu/rv-adapter-states kullanabilirsiniz , sadece boş görünümü değil, aynı zamanda görünüm ve hata görünümünü yüklemeyi de destekler. Ve mevcut bağdaştırıcının mantığını değiştirmeden kullanabilirsiniz.
Hieu Rocker

20
Bir şey setEmptyView()karşı basit bir yöntem gibi görünmüyor büyüleyici bir şey değil RecyclerView...
Subby

İşte cevabım, lütfen bu bağlantıyı kontrol edin stackoverflow.com/a/58411351/5449220
Rakesh Verma

@Subby, katılıyorum, ama setEmptyView()aynı zamanda dezavantajı da vardı. Verileri yüklerken, içinde boş görünüm göstermek istemedik ListView, ancak gösterdi. Bu yüzden biraz mantık uygulamak zorunda kaldık. Şu anda stackoverflow.com/a/48049142/2914140 kullanıyorum .
CoolMind

Yanıtlar:


305

Tanımlı aynı düzende şunu RecyclerViewekleyin TextView:

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

<TextView
    android:id="@+id/empty_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:visibility="gone"
    android:text="@string/no_data_available" />

At onCreatebeslemeleri veri kümesi senin eğer veya uygun callback'inde kontrol RecyclerViewboştur. Veri kümesi boşsa, RecyclerViewboştur. Bu durumda, mesaj ekranda belirir. Değilse, görünürlüğünü değiştirin:

private RecyclerView recyclerView;
private TextView emptyView;

// ...

recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
emptyView = (TextView) rootView.findViewById(R.id.empty_view);

// ...

if (dataset.isEmpty()) {
    recyclerView.setVisibility(View.GONE);
    emptyView.setVisibility(View.VISIBLE);
}
else {
    recyclerView.setVisibility(View.VISIBLE);
    emptyView.setVisibility(View.GONE);
}

11
Bu benim için işe yaramaz çünkü geri dönüşümcü görünüm düzeni parçada şişirilirken, adaptörde normal bir öğe düzeni veya öğe içermeyen bir düzen gösterme kararı verilir.
JJD

1
Bir Parça kullanırken @JJD de aynı şey geçerlidir. Parça görünümünüzü şişirdiğinizde geri dönüşüm görünümüne ve ardından boş görünümünüz için kullanılacak başka bir düzene sahip olursunuz. Genellikle parçalarımda şu görünümlere sahip olacağım: 1) geri dönüşüm görünümü, 2) boş görünüm ve 3) ilerleme çubuğu görünümü. Genellikle liste ne olursa olsun bağdaştırıcıyı geçiyorum, ancak listenin boyutuna göre ya geri dönüşüm görünümünü gizleyeceğim ve boş göstereceğim ya da tam tersi. Bir geri dönüşüm görünümünde boş bir liste varsa, listeyle hiçbir şey yapmaz. Sadece boş bir manzara görüyorsunuz.
Ray Hunter

1
@stackex Doğrulama, Parçanın onCreateView geri çağrısında veya Aktivitenin Özgeçmişinde olmalıdır. Bu şekilde, doğrulama ekranın kullanıcıya gösterilmesinden hemen önce yapılacak ve veri kümesindeki satırların miktarını artırarak veya azaltarak her ikisi için de çalışacaktır.
slellis

2
@Zapnologica Bunu başka bir şekilde yapabilirsiniz: Bir Eventbus (greenrobots Eventbus veya Otto gibi) kullanın, ardından veri kümesi değiştiğinde eventbus'ta Adaptör postası bulundurun. Parçada tek yapmanız gereken, Parametreler Bağdaştırıcı'nın Eventbus.post yöntemine ilettiği şeye karşılık gelen bir yöntem oluşturmak ve ardından düzeni buna göre değiştirmek. Daha basit ama aynı zamanda daha birleşimli bir yaklaşım, adaptörde bir geri arama arayüzü oluşturmaktır ve adaptör oluşturulduktan sonra parçayı uygular.
AgentKnopf

2
Düzende birden çok kök etiketi alıyorum. Tam düzen dosyanız neye benziyor?
powder366

192

Benim projeler için ben (bu çözümü yapılmış RecyclerViewolan setEmptyViewyöntemle):

public class RecyclerViewEmptySupport extends RecyclerView {
    private View emptyView;

    private AdapterDataObserver emptyObserver = new AdapterDataObserver() {


        @Override
        public void onChanged() {
            Adapter<?> adapter =  getAdapter();
            if(adapter != null && emptyView != null) {
                if(adapter.getItemCount() == 0) {
                    emptyView.setVisibility(View.VISIBLE);
                    RecyclerViewEmptySupport.this.setVisibility(View.GONE);
                }
                else {
                    emptyView.setVisibility(View.GONE);
                    RecyclerViewEmptySupport.this.setVisibility(View.VISIBLE);
                }
            }

        }
    };

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

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

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

    @Override
    public void setAdapter(Adapter adapter) {
        super.setAdapter(adapter);

        if(adapter != null) {
            adapter.registerAdapterDataObserver(emptyObserver);
        }

        emptyObserver.onChanged();
    }

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

Ve RecyclerViewsınıf yerine kullanmalısınız :

<com.maff.utils.RecyclerViewEmptySupport android:id="@+id/list1"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    />

<TextView android:id="@+id/list_empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Empty"
    />

ve

RecyclerViewEmptySupport list = 
    (RecyclerViewEmptySupport)rootView.findViewById(R.id.list1);
list.setLayoutManager(new LinearLayoutManager(context));
list.setEmptyView(rootView.findViewById(R.id.list_empty));

2
Bu kodu bu cevaptan mı yoksa buradan mı aldınız ?
Sufian

@Sufian Hayır, bu cevabı görmedim, sadece aynı yolu buldum. Ama bu kod kesinlikle benimkinden daha güzel görünüyor :)
maff91

2
Bunu FirebaseRecyclerAdapter ile birleştirmeye çalıştım, işe yaramadı. Bunun nedeni, FirebaseRecyclerAdapter öğesinin onChange öğesini (AdapterDataObserver öğesinin) çağırmaması, bunun yerine onItem * yöntemlerini çağırmasıdır. Çalışmasını sağlamak için şunu ekleyin: `` Genel boşluğu geçersiz kıl onItemRangeRemoved (int positionStart, int itemCount) {// check} Açık boşluğu geçersiz kıl onItemRangeMoved (int ,Position, int toPosition, int itemCount) {// the check} // etc .. `
FrankkieNL

1
Bağdaştırıcının gözlemcide boş olup olmadığını neden kontrol ediyorsunuz? bağdaştırıcı boşsa gözlemci asla çağrılmamalıdır.
Stimsoni

16
ugh, bunun sadece klasik Google BS olduğunu söylemeliyim. Boş bir görünüm eklemek için bunu uygulamak zorunda mıyım? Cr @ psh1t SDK'sına dahil edilmelidir! Tanrı aşkına!
Neon Warge

62

Boş durum için yalnızca farklı görünüm türüne sahip özel bir adaptör kullanan bir çözüm.

public class EventAdapter extends 
    RecyclerView.Adapter<EventAdapter.ViewHolder> {

    private static final int VIEW_TYPE_EVENT = 0;
    private static final int VIEW_TYPE_DATE = 1;
    private static final int VIEW_TYPE_EMPTY = 2;

    private ArrayList items;

    public EventAdapter(ArrayList items) {
        this.items = items;
    }

    @Override
    public int getItemCount() {
        if(items.size() == 0){
            return 1;
        }else {
            return items.size();
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (items.size() == 0) {
            return VIEW_TYPE_EMPTY;
        }else{
            Object item = items.get(position);
            if (item instanceof Event) {
                return VIEW_TYPE_EVENT;
            } else {
                return VIEW_TYPE_DATE;
            }
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v;
        ViewHolder vh;
        if (viewType == VIEW_TYPE_EVENT) {
            v = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_event, parent, false);
            vh = new ViewHolderEvent(v);
        } else if (viewType == VIEW_TYPE_DATE) {
            v = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_event_date, parent, false);
            vh = new ViewHolderDate(v);
        } else {
            v = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_event_empty, parent, false);
            vh = new ViewHolder(v);
        }

        return vh;
    }

    @Override
    public void onBindViewHolder(EventAdapter.ViewHolder viewHolder, 
                                 final int position) {
        int viewType = getItemViewType(position);
        if (viewType == VIEW_TYPE_EVENT) {
            //...
        } else if (viewType == VIEW_TYPE_DATE) {
            //...
        } else if (viewType == VIEW_TYPE_EMPTY) {
            //...
        }
    }

    public static class ViewHolder extends ParentViewHolder {
        public ViewHolder(View v) {
            super(v);
        }
    }

    public static class ViewHolderDate extends ViewHolder {

        public ViewHolderDate(View v) {
            super(v);
        }
    }

    public static class ViewHolderEvent extends ViewHolder {

        public ViewHolderEvent(View v) {
            super(v);
        }
    }

}

3
@ sfk92fksdf Neden hataya açık? Bu, geri dönüşüm görünümünde birden çok görüntüleme türünü ele almanız gereken yoldur
MSpeed

@billynomates, çünkü getItemCount()bir oneliner olmalı ama burada ifbazı gizli mantıkla önemsiz bir şeyimiz yok . Bu mantık da garip bir şekilde ortaya çıkıyor getItemViewTypeve tanrı başka nerede biliyor
Alexey Andronov

3
Tek satır olması gerekmez. Birden fazla görüntüleme türünüz varsa bunu yapmanın yolu budur.
MSpeed

@ sfk92fksdf Gizli mantıkla ne demek istiyorsun? Kod tam orada
ra

1
Bence bu cevap kabul edilen cevap olmalı. Gerçekten çok yönlü görünüm türlerini ele almanın yolu
Ivo Beckers

45

ViewSwitcher kullanıyorum

<ViewSwitcher
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/switcher"
    >

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

    <TextView android:id="@+id/text_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/list_empty"
        android:gravity="center"
        />

</ViewSwitcher>

kodda imleci / veri kümesini kontrol edecek ve görünümleri değiştireceksiniz.

void showItems(Cursor items) {
    if (items.size() > 0) {

        mAdapter.switchCursor(items);

        if (R.id.list == mListSwitcher.getNextView().getId()) {
            mListSwitcher.showNext();
        }
    } else if (R.id.text_empty == mListSwitcher.getNextView().getId()) {
        mListSwitcher.showNext();
    }
}

Ayrıca, birkaç kod satırı ile animasyonlar ayarlayabilirsiniz

mListSwitcher.setInAnimation(slide_in_left);
mListSwitcher.setOutAnimation(slide_out_right);

Gerçekten roman
Zhang Xiang

Temiz çözelti.
Ojonugwa Jude Ochalifu

30

Kevin'in cevabı tam olmadığından. 'S
kullanır ve veri kümesini güncelleştirmek için bu daha doğru yanıttır . Aşağıda başka bir kullanıcının eklediği Kotlin sürümüne bakın. RecyclerAdapternotifyItemInsertednotifyItemRemoved

Java:

mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {

    @Override
    public void onChanged() {
        super.onChanged();
        checkEmpty();
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        super.onItemRangeInserted(positionStart, itemCount);
        checkEmpty();
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
        super.onItemRangeRemoved(positionStart, itemCount);
        checkEmpty();
    }

    void checkEmpty() {
        mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
    }
});

Kotlin

adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
    override fun onChanged() {
        super.onChanged()
        checkEmpty()
    }

    override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
        super.onItemRangeInserted(positionStart, itemCount)
        checkEmpty()
    }

    override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
        super.onItemRangeRemoved(positionStart, itemCount)
        checkEmpty()
    }

    fun checkEmpty() {
        empty_view.visibility = (if (adapter.itemCount == 0) View.VISIBLE else View.GONE)
    }
})

2
Bu harika bir çözüm. Kotlin sürümünü içeren bir düzenleme öneriyorum.
jungledev

Bu iyi görünüyor, ancak swapAdapter () veya setAdapter () öğesini birden çok kez çağırırsanız çalışmayabilir.
Glaucus

Bence en zarif çözüm!
android meraklısı

Harika iş. etiketi gösterirken RecyclerView'i gizlemeyi unutmayın
MrG

18

RVEmptyObserver

Özel kullanmak yerine RecyclerView, genişletmek , listede hiçbir öğe olmadığında görüntülenen AdapterDataObserverbir özel ayarlamaya izin veren daha basit bir çözümdür View:

Örnek Kullanım:

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

Sınıf:

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

Ben aramıyorsun eğer hızlı çalışmasını inanıyoruz checkIfEmpty()içinde onChanged()veonItemRangeInserted()
Geekarist

Kabul ediyorum (ve şahsen yaptığım bu), ancak bu sadece bu sorunla karşı karşıya olan insanlar için bir başlangıç ​​noktasıydı.
Sheharyar

9

Bağdaştırıcınızın getItemViewTypebağdaştırıcısında 0 öğe olup olmadığını kontrol edin ve varsa farklı bir viewType döndürün.

Ardından onCreateViewHolder, viewType'ın daha önce döndürdüğünüz ve farklı bir görünümü şişirdiğini kontrol edin. Bu durumda, bu TextView ile bir düzen dosyası

DÜZENLE

Bu hala çalışmıyorsa, görünümün boyutunu programlı olarak şu şekilde ayarlamak isteyebilirsiniz:

Point size = new Point();
((WindowManager)itemView.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(size);

Ardından görüşme çağrınızı şişirdiğinizde:

inflatedView.getLayoutParams().height = size.y;
inflatedView.getLayoutParams().width = size.x;

Kulağa iyi geliyor. Ancak girmem onCreateViewHolderbenim veri kümesi olduğunda nullya da ben geri dönmek zorunda çünkü boşaltmak 0içinde getItemCount.
JJD

Sonra boşsa 1 dönün :)
Pedro Oliveira

Biraz çalışıyor. Teşekkür ederim. - Küçük ayrıntı, boş liste öğesinin geri dönüşüm görünümünde dikey olarak ortalanamamasıdır . Her ne kadar ayarladığım android:layout_gravity="center"ve android:layout_height="match_parent"ana geri dönüşümcü görünümü için metin görünümü ekranın üstünde kalır .
JJD

Kullandığınız satırın düzenine bağlıdır. Yüksekliğinde match_parent olmalıdır. Yine de çalıştıramazsanız, genel bir düzen dinleyicisi ekleyin ve düzen parametrelerini ekranla aynı yüksekliğe ve genişliğe sahip olacak şekilde ayarlayın.
Pedro Oliveira

Tüm kaplar (etkinlik, parça, doğrusal düzen, geri dönüşüm görünümü, metin görünümü) olarak ayarlanır android:layout_height="match_parent". Satır ekran yüksekliğine genişlemese de.
JJD

8

İşte boş görünüm göstermek, yeniden deneme görünümü (yük api başarısız olduğunda) ve yükleme ilerleme durumu için sınıfım RecyclerView

public class RecyclerViewEmptyRetryGroup extends RelativeLayout {
    private RecyclerView mRecyclerView;
    private LinearLayout mEmptyView;
    private LinearLayout mRetryView;
    private ProgressBar mProgressBar;
    private OnRetryClick mOnRetryClick;

    public RecyclerViewEmptyRetryGroup(Context context) {
        this(context, null);
    }

    public RecyclerViewEmptyRetryGroup(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecyclerViewEmptyRetryGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onViewAdded(View child) {
        super.onViewAdded(child);
        if (child.getId() == R.id.recyclerView) {
            mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            return;
        }
        if (child.getId() == R.id.layout_empty) {
            mEmptyView = (LinearLayout) findViewById(R.id.layout_empty);
            return;
        }
        if (child.getId() == R.id.layout_retry) {
            mRetryView = (LinearLayout) findViewById(R.id.layout_retry);
            mRetryView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mRetryView.setVisibility(View.GONE);
                    mOnRetryClick.onRetry();
                }
            });
            return;
        }
        if (child.getId() == R.id.progress_bar) {
            mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        }
    }

    public void loading() {
        mRetryView.setVisibility(View.GONE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.VISIBLE);
    }

    public void empty() {
        mEmptyView.setVisibility(View.VISIBLE);
        mRetryView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public void retry() {
        mRetryView.setVisibility(View.VISIBLE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public void success() {
        mRetryView.setVisibility(View.GONE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public RecyclerView getRecyclerView() {
        return mRecyclerView;
    }

    public void setOnRetryClick(OnRetryClick onRetryClick) {
        mOnRetryClick = onRetryClick;
    }

    public interface OnRetryClick {
        void onRetry();
    }
}

activity_xml

<...RecyclerViewEmptyRetryGroup
        android:id="@+id/recyclerViewEmptyRetryGroup">

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

        <LinearLayout
            android:id="@+id/layout_empty">
            ...
        </LinearLayout>

        <LinearLayout
            android:id="@+id/layout_retry">
            ...
        </LinearLayout>

        <ProgressBar
            android:id="@+id/progress_bar"/>

</...RecyclerViewEmptyRetryGroup>

resim açıklamasını buraya girin

Kaynak burada https://github.com/PhanVanLinh/AndroidRecyclerViewWithLoadingEmptyAndRetry


7

Özel RecyclerView'de AdapterDataObserver kullanma

Kotlin:

RecyclerViewEnum.kt

enum class RecyclerViewEnum {
    LOADING,
    NORMAL,
    EMPTY_STATE
}

RecyclerViewEmptyLoadingSupport.kt

class RecyclerViewEmptyLoadingSupport : RecyclerView {

    var stateView: RecyclerViewEnum? = RecyclerViewEnum.LOADING
        set(value) {
            field = value
            setState()
        }
    var emptyStateView: View? = null
    var loadingStateView: View? = null


    constructor(context: Context) : super(context) {}

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}


    private val dataObserver = object : AdapterDataObserver() {
        override fun onChanged() {
            onChangeState()
        }

        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
            super.onItemRangeRemoved(positionStart, itemCount)
            onChangeState()
        }

        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            super.onItemRangeInserted(positionStart, itemCount)
            onChangeState()
        }
    }


    override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
        super.setAdapter(adapter)
        adapter?.registerAdapterDataObserver(dataObserver)
        dataObserver.onChanged()
    }


    fun onChangeState() {
        if (adapter?.itemCount == 0) {
            emptyStateView?.visibility = View.VISIBLE
            loadingStateView?.visibility = View.GONE
            this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
        } else {
            emptyStateView?.visibility = View.GONE
            loadingStateView?.visibility = View.GONE
            this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
        }
    }

    private fun setState() {

        when (this.stateView) {
            RecyclerViewEnum.LOADING -> {
                loadingStateView?.visibility = View.VISIBLE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
                emptyStateView?.visibility = View.GONE
            }

            RecyclerViewEnum.NORMAL -> {
                loadingStateView?.visibility = View.GONE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
                emptyStateView?.visibility = View.GONE
            }
            RecyclerViewEnum.EMPTY_STATE -> {
                loadingStateView?.visibility = View.GONE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
                emptyStateView?.visibility = View.VISIBLE
            }
        }
    }
}

Layout.xml

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

    <LinearLayout
        android:id="@+id/emptyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/emptyLabelTv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="empty" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/loadingView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_gravity="center"
            android:indeterminate="true"
            android:theme="@style/progressBarBlue" />
    </LinearLayout>

    <com.peeyade.components.recyclerView.RecyclerViewEmptyLoadingSupport
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

faaliyette şu şekilde kullanın:

recyclerView?.apply {
        layoutManager = GridLayoutManager(context, 2)
        emptyStateView = emptyView
        loadingStateView = loadingView
        adapter = adapterGrid
    }

    // you can set LoadingView or emptyView manual
    recyclerView.stateView = RecyclerViewEnum.EMPTY_STATE
    recyclerView.stateView = RecyclerViewEnum.LOADING

1
Bu çözüm ile giderseniz artan bellek ayırma boyutu nedeniyle numaralandırma kullanmanın yetersiz olduğuna dikkat edin. Uygunluk StringDefveya IntDefek açıklamalarla içeriğinize bağlı olarak Tamsayı veya Dize kullanın
Andrii Artamonov

2

Ben eklendi RecyclerViewve alternatif ImageViewiçin RelativeLayout:

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

    <ImageView
        android:id="@+id/no_active_jobs"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ic_active_jobs" />

    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

ve sonra Adapter:

@Override
public int getItemCount() {
    if (mOrders.size() == 0) {
        mRecyclerView.setVisibility(View.INVISIBLE);
    } else {
        mRecyclerView.setVisibility(View.VISIBLE);
    }
    return mOrders.size();
}

7
nasıl ulaşılacağını mRecyclerViewiçerideAdapter
Basheer AL-MOMANI

2
Adaptörü belirli bir Etkinliğe bağlamak iyi bir tasarım deseni değildir. Bunu arayüzler üzerinden yapmak daha iyidir
ruX

1
Ayrıca bu, bir düzenin aşılmasına neden oluyor ve bu önerilmiyor ve bazı performans sorunlarına neden olabilir. Daha fazla bilgi için youtube.com/watch?v=T52v50r-JfE adresine bakın
Felipe Conde

1

Bir başka yol da, addOnChildAttachStateChangeListenerhangi çocuk görüşlerinin görünüp kaybolacağını ele almaktır RecyclerView.

recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onChildViewDetachedFromWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.VISIBLE);
            }
        });

0

Sadece bir FirebaseRecyclerAdapter ile çalışıyorsanız, bu yazı bir cazibe olarak çalışır https://stackoverflow.com/a/39058636/6507009


7
Bu bağlantı soruyu cevaplayabilse de, cevabın temel kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir.
Anh Pham
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.