একটি পুনর্ব্যবহারযোগ্য ভিউয়ের সাথে খালি দৃশ্যটি কীভাবে প্রদর্শন করবেন?


271

আমি বিন্যাস ফাইল ভিতরে একটি বিশেষ দৃশ্য করা ব্যবহার করছি বর্ণিত ListActivityডকুমেন্টেশন করা কোন তথ্য নেই যখন প্রদর্শিত । এই ভিউটির আইডি রয়েছে "android:id/empty"

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

আমি ভাবছি কীভাবে নতুন দিয়ে এটি করা যায় RecyclerView?


2
আপনি github.com/rockerhieu/rv-adapter-states ব্যবহার করতে পারেন , এটি কেবল ফাঁকা দর্শন নয়, লোডিং ভিউ এবং ত্রুটি দর্শনকে সমর্থন করে। এবং আপনি এটি ব্যবহার করতে পারবেন বিদ্যমান অ্যাডাপ্টারের যুক্তি পরিবর্তন না করে।
হাইউ রকার

20
এটি আকর্ষণীয় ছাড়া কিছুই নয় যে setEmptyView()কোনও RecyclerView... এর বিরুদ্ধে সাধারণ পদ্ধতি বলে মনে হয় না ...
সাববি

এখানে আমার উত্তর, দয়া করে এই লিঙ্কটি চেক করুন stackoverflow.com/a/58411351/5449220
রকেশ ভার্মা

@ সাব্বি, একমত হন, তবে setEmptyView()এর অসুবিধাও ছিল। ডেটা লোড করার সময়, আমরা খালি ভিউ ভিতরে দেখাতে চাইনি ListView, তবে এটি হয়েছিল। সুতরাং, আমাদের কিছু যুক্তি প্রয়োগ করতে হয়েছিল। বর্তমানে আমি স্ট্যাকওভারফ্লো . com/a/48049142/2914140 ব্যবহার করি ।
কুলমাইন্ড

উত্তর:


305

একই লেআউটে যেখানে সংজ্ঞায়িত করা হয়েছে সেখানে RecyclerViewযুক্ত করুন 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" />

onCreateবা উপযুক্ত কলব্যাক আপনি না পরীক্ষা যদি ডেটা সেটটি যে ফিড আপনার RecyclerViewখালি। যদি ডেটাসেট RecyclerViewখালি থাকে তবে এটিও খালি। সেক্ষেত্রে স্ক্রিনে বার্তাটি উপস্থিত হয়। যদি তা না হয় তবে এর দৃশ্যমানতাটি পরিবর্তন করুন:

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
এটি আমার পক্ষে কাজ করে না কারণ পুনর্ব্যবহারযোগ্য ভিউ বিন্যাসটি খণ্ডটিতে স্ফীত হয় যখন কোনও সাধারণ আইটেম বিন্যাস বা কোনও আইটেম বিন্যাস প্রদর্শন করার সিদ্ধান্তটি অ্যাডাপ্টারে নেওয়া হয়।
জেজেডি

1
@ জেজেডি যখন কোনও খণ্ড ব্যবহার করে তখন একই জিনিস প্রযোজ্য। আপনি যখন আপনার খণ্ড দৃশ্যকে স্ফীত করবেন তখন আপনার পুনর্ব্যবহারযোগ্য দৃশ্য এবং তারপরে অন্য খালি আপনার খালি দৃষ্টির জন্য ব্যবহৃত হবে। সাধারণত আমার খণ্ডগুলিতে আমার সেখানে অনুসরণের দর্শন থাকবে: 1) পুনর্ব্যবহারযোগ্য দর্শন, 2) খালি দর্শন, এবং 3) অগ্রগতি দর্শন। আমি তালিকাটি যাই হোক না কেন সাধারণত অ্যাডাপ্টারটি পাস করি তবে তালিকার আকারের ভিত্তিতে আমি হয় পুনর্ব্যবহারযোগ্য দৃশ্যটি আড়াল করব এবং খালি বা বিপরীতে দেখাব। যদি একটি পুনর্ব্যবহারযোগ্য ভিউতে একটি খালি তালিকা থাকে, তবে এটি এটি দিয়ে কিছুই করে না। আপনি কেবল একটি খালি দৃশ্য দেখুন।
রে হান্টার

1
@ স্ট্যাকাকেক্স যাচাইকরণটি অবশ্যই খণ্ডটির অনক্রিটভিউ কলব্যাক বা ক্রিয়াকলাপের পুনরায় শুরু হওয়া আবশ্যক। এইভাবে, ব্যবহারকারীর কাছে স্ক্রিনটি প্রদর্শিত হওয়ার আগেই যাচাইকরণটি করা হবে এবং ডেটাসেটে সারিগুলির পরিমাণ বৃদ্ধি বা হ্রাস করে উভয়ের পক্ষে কাজ করবে।
slellis

2
@ জাপনোলজিকা আপনি এটি অন্য উপায়ে করতে পারেন: ডেটাसेटটি পরিবর্তিত হওয়ার পরে ইভেন্টবাস (যেমন গ্রিনরোবটস ইভেন্টবস বা অটো) ব্যবহার করুন, তারপরে ইভেন্টবাসে অ্যাডাপ্টার পোস্ট করুন post খণ্ডগুলিতে আপনি যা করেন তা এমন একটি পদ্ধতি তৈরি করুন যার প্যারামিটারগুলি ইভেন্টবাস.পোস্ট পদ্ধতিতে অ্যাডাপ্টারটি যা যা করছে তার সাথে সামঞ্জস্য হয় এবং তারপরে সেই অনুযায়ী বিন্যাসটি পরিবর্তন করে। অ্যাডাপ্টারে একটি কলব্যাক ইন্টারফেস তৈরি করা এবং আরও অ্যাডাপ্টারের তৈরির পরে টুকরাটি প্রয়োগ করে এটি আরও সহজ এবং আরও মিলিত পদ্ধতির হয়।
এজেন্টকনফফ

2
বিন্যাসে আমি একাধিক মূল ট্যাগ পাই। আপনার সম্পূর্ণ লেআউট ফাইলটি দেখতে কেমন?
পাউডার366

192

আমার প্রকল্পের জন্য আমি (এই সমাধান প্রণীত RecyclerViewসঙ্গে setEmptyViewপদ্ধতি):

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

এবং আপনার এটি RecyclerViewক্লাসের পরিবর্তে ব্যবহার করা উচিত :

<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"
    />

এবং

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

2
আপনি এই উত্তরটি বা এখান থেকে এই কোডটি নিয়েছেন ?
সুফিয়ান

@ সুফিয়ান না, আমি উত্তরটি দেখতে পাইনি, ঠিক একইভাবে খুঁজে পেয়েছি। তবে সেই কোডটি অবশ্যই আমার চেয়ে সুন্দর দেখাচ্ছে :)
maff91

2
আমি এটি ফায়ারবেসেকার্লঅ্যাডাপ্টারের সাথে একত্রিত করার চেষ্টা করেছি, এটি কার্যকর হয়নি। এটি কারণ ফায়ারব্যাসেরেক্লারএডাপ্টার অনচেনজকে (অ্যাডাপ্টারডেটা ওভারসিভারের) কল করে না, পরিবর্তে এটি "আইটেম" -মোথডসকে কল করে। এটির কাজটি যুক্ত করার জন্য: tem আইটেমরঞ্জারমোভড (int পজিশন স্টার্ট, ইন আইটেমকাউন্ট) ওভাররাইড করুন {// চেক} সার্বজনীন শূন্যপরিবর্তন আইটেমরেঞ্জমোভড (INT পজিশন, ইন টু পজিশন, ইন আইটেমকন্ট) {// চেক} // ইত্যাদি `
ফ্রাঙ্ককিএনএল

1
অ্যাডাপ্টারটি পর্যবেক্ষকের শূন্য কিনা তা আপনি কেন পরীক্ষা করেন? যদি অ্যাডাপ্টারটি নাল হয় তবে পর্যবেক্ষককে কখনই ডাকা উচিত নয়।
সিসটেমনি

16
ওহ, আমি অবশ্যই এটি অবশ্যই ক্লাসিক গুগল বিএস। খালি ভিউ যুক্ত করতে কি আমাকে এটি প্রয়োগ করতে হবে? এটি তাদের সিআর @ psh1t এসডিকে অন্তর্ভুক্ত করা উচিত! ঈশ্বরের দোহাই!
নিয়ন ওয়ারেজ

62

খালি পরিস্থিতির জন্য ভিন্ন ধরণের ধরণের সাথে কেবলমাত্র একটি কাস্টম অ্যাডাপ্টার ব্যবহার করে এখানে একটি সমাধান দেওয়া হচ্ছে।

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 কেন এটি ত্রুটিযুক্ত? আপনি রিসাইক্লারভিউতে একাধিক দেখার ধরণের হ্যান্ডেল করার কথা
এটিই

@ বিলিনোমেটস, কারণ এটি অনিয়েনার getItemCount()হওয়া উচিত তবে এখানে আমাদের কাছে ifকিছু লুকানো যুক্তি রয়েছে v এই যুক্তিটিও বিশ্রীভাবে উপস্থিত হয়েছিল getItemViewTypeএবং where
শ্বর

3
এটি একটি লাইন হতে হবে না। যদি আপনার একাধিক দেখার ধরণ থাকে তবে এটি করার উপায় এটি।
এমএসপিড

@ sfk92fksdf গোপন যুক্তি বলতে কী বোঝ? কোডটি এখনই is
radu122

1
আমার মতে এই উত্তরটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি সত্যিই একচেটিয়া দর্শন প্রকারগুলি পরিচালনা করার উপায়
Ivo Beckers

45

আমি ভিউউইচর ব্যবহার করি

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

কোডে আপনি কার্সার / ডেটাসেট এবং স্যুইচ ভিউগুলি পরীক্ষা করবেন।

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

এছাড়াও আপনি কোডের কয়েকটি লাইনের সাথে ইচ্ছে করলে আপনি অ্যানিমেশন সেট করতে পারেন

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

এটি সত্যিই উপন্যাস
ঝাং জিয়াং

পরিষ্কার সমাধান।
ওজনগওয়া জুড ওচালিফু

30

যেহেতু কেভিনের উত্তর সম্পূর্ণ নয়।
এর ফলে বেশি সঠিক উত্তর যদি আপনি ব্যবহার করেন RecyclerAdapterএর notifyItemInsertedএবং notifyItemRemovedআপডেট ডেটা সেটটি করতে। কোটলিন সংস্করণ দেখুন অন্য ব্যবহারকারী নীচে যুক্ত।

জাভা:

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
এটি একটি দুর্দান্ত সমাধান। আমি এটিতে একটি সম্পাদনার প্রস্তাব দিচ্ছি যা কোটলিন সংস্করণ অন্তর্ভুক্ত করবে।
জংলেদেব

এটি ভাল বলে মনে হচ্ছে তবে আপনি যদি swapAdapter () বা এমনকি সেটএডাপ্টার () সেট করে একাধিকবার কল করেন তবে এটি কাজ করবে না।
গ্লোকাস

আমি মনে করি সবচেয়ে মার্জিত সমাধান!
অ্যান্ড্রয়েড উত্সাহী

মহান কাজ. লেবেলটি দেখানোর সময় রিসাইক্লারভিউটি লুকিয়ে রাখতে ভুলবেন না
মিঃজি

18

RVEmptyObserver

কাস্টম ব্যবহারের পরিবর্তে RecyclerView, প্রসারিত AdapterDataObserverকরা একটি সহজ সমাধান যা Viewতালিকায় কোনও আইটেম না থাকাকালীন প্রদর্শিত একটি কাস্টম সেট করার অনুমতি দেয় :

ব্যবহারের উদাহরণ:

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

ক্লাস:

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

আমি বিশ্বাস করি যে আপনি যদি কল checkIfEmpty()না করেন onChanged()এবংonItemRangeInserted()
গীকারিস্ট

আমি সম্মত (এবং এটি আমি ব্যক্তিগতভাবে কী করেছি) তবে এটি কেবল এই সমস্যার মুখোমুখি লোকদের জন্য একটি সূচনা পয়েন্ট হিসাবে বোঝানো হয়েছিল।
শেহিয়র

9

আপনার অ্যাডাপ্টারের getItemViewTypeপরীক্ষায় অ্যাডাপ্টারের 0 টি উপাদান রয়েছে কিনা এবং যদি অন্যরকম ভিউটাইপ ফিরে আসে।

তারপরে আপনার onCreateViewHolderচেকের উপর দেখুন যে ভিউটাইপটি হ'ল আপনি আগে ফিরে এসেছেন এবং একটি ভিন্ন দৃষ্টিভঙ্গি দেখান। এই ক্ষেত্রে সেই টেক্সটভিউয়ের সাথে একটি লেআউট ফাইল

সম্পাদনা

যদি এটি এখনও কাজ না করে থাকে তবে আপনি ভিউটির আকারটি অগ্রগতিগতভাবে এভাবে সেট করতে চাইতে পারেন:

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

এবং তারপরে আপনি যখন নিজের দর্শন কলকে স্ফীত করবেন:

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

ভাল লাগছে। তবে onCreateViewHolderআমার ডেটাসেটটি কখন nullখালি আছে তা খালি প্রবেশ করতে হবে 0না getItemCount
জেজেডি

তারপরে 1 টি ফিরে
পেড্রো অলিভিরা

কিছুটা কাজ করে। ধন্যবাদ. - গৌণ বিশদটি হ'ল আমি খালি তালিকার আইটেমটি পুনর্ব্যবহারকারী দৃশ্যে উল্লম্বভাবে কেন্দ্রীভূত হতে পারি না । আমি সেট করা যাই হোক না কেন android:layout_gravity="center"এবং android:layout_height="match_parent"পিতামাতার পুনর্ব্যবহারকারী দৃশ্যের জন্য পাঠ্য ভিউ স্ক্রিনের শীর্ষে থাকে ।
জেজেডি

এটি আপনি যে সারিটি ব্যবহার করছেন তার বিন্যাসের উপর নির্ভর করে। এটি উচ্চতার উপরে পিতামাতার সাথে মিলিত হওয়া উচিত। আপনি যদি এখনও এটিকে কাজ করতে না পারেন তবে একটি বৈশ্বিক বিন্যাস শ্রোতা যুক্ত করুন এবং স্ক্রিনের মতো একই উচ্চতা এবং প্রস্থের জন্য এটির বিন্যাসের পরামিতিগুলি সেট করুন।
পেড্রো অলিভিরা

সমস্ত পাত্রে (ক্রিয়াকলাপ, খণ্ড, রৈখিক বিন্যাস, পুনর্ব্যবহারযোগ্য দৃশ্য, পাঠ্য দর্শন) সেট করা আছে android:layout_height="match_parent"। যদিও সারিটি স্ক্রিনের উচ্চতায় প্রসারিত হয় না।
জেজেডি

8

খালি দর্শন প্রদর্শন, পুনরায় দেখুন (যখন লোড এপিআই ব্যর্থ হয়েছে) এবং এর জন্য লোডিং অগ্রগতির জন্য আমার ক্লাস এখানে 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>

এখানে চিত্র বর্ণনা লিখুন

উত্সটি এখানে https://github.com/PhanVanLinh/AndroidRecyclerViewWithLoadingEmptyAndRetry


7

কাস্টম রিসাইক্লারভিউতে অ্যাডাপ্টারডেটাঅবার্সার ব্যবহার করুন

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>

ক্রিয়াকলাপে এইভাবে ব্যবহার করুন:

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
যদি আপনি সেই সমাধানটি নিয়ে যান তবে মনোযোগ দিন যে এনমগুলি ব্যবহার করা তার মেমরির বরাদ্দের আকার বাড়ার কারণে অপর্যাপ্ত। উপযুক্ত StringDefবা IntDefটীকাগুলির সাথে আপনার প্রসঙ্গের উপর নির্ভর করে পূর্ণসংখ্যা বা স্ট্রিং ব্যবহার করুন
আন্দ্রেই আর্টামোনভ

2

আমি যোগ RecyclerViewএবং বিকল্প ImageViewথেকে 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>

এবং তারপরে Adapter:

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

7
কীভাবে mRecyclerViewভিতরে প্রবেশ করবেনAdapter
বাশির আল-মোমানী

2
নির্দিষ্ট ক্রিয়াকলাপে অ্যাডাপ্টারকে বেঁধে রাখার জন্য এটি নকশার নকশাটি ভাল নয়। ইন্টারফেসের মাধ্যমে এটি করা আরও ভাল
রুक्स

1
এছাড়াও এটি একটি লেআউটকে ওভারড্রোয়ের কারণ করছে, যা প্রস্তাবিত নয় এবং এটি কিছু কার্যক্ষমতার সমস্যার কারণ হতে পারে। আরও তথ্যের জন্য youtube.com/watch?v=T52v50r-JfE দেখুন
ফিলিপ কনডে

1

আরও একটি উপায় হ'ল ব্যবহৃত addOnChildAttachStateChangeListenerহ্যান্ডলগুলি কীভাবে শিশুদের দৃষ্টিভঙ্গি উপস্থিত / অদৃশ্য হয়ে যায় তা ব্যবহার করা 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

আপনি যদি ফায়ারব্যাসেরেক্লারএডাপ্টারের সাথে কাজ করছেন তবেই এই পোস্টটি কবজ হিসাবে কাজ করবে https://stackoverflow.com/a/39058636/6507009


7
যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত পৃষ্ঠাগুলি পরিবর্তিত হলে লিঙ্ক-শুধুমাত্র উত্তরগুলি অবৈধ হতে পারে।
আনহ ফাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.