অ্যান্ড্রয়েড অন্তহীন তালিকা


232

আমি কীভাবে একটি তালিকা তৈরি করতে পারি যেখানে আপনি তালিকার শেষে পৌঁছে গেলে আমাকে অবহিত করা হয় যাতে আমি আরও আইটেম লোড করতে পারি?


9
আমি কমনওয়ারের অন্তহীন অ্যাডাপ্টারটির প্রস্তাব দিচ্ছি: github.com/commonsguy/cwac-endless । আমি অন্য প্রশ্নের এই উত্তর থেকে এটি পেয়েছি: স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 66666670০64//২
টাইলার কলিয়ার

আমি কোনো এক সাহায্যের thing..can একই প্রয়োজন ..? Stackoverflow.com/questions/28122304/...

উত্তর:


269

একটি সমাধান হ'ল একটি প্রয়োগ করা এবং এর পদ্ধতিতে সুবিধাজনক স্থানে OnScrollListenerপরিবর্তন (যেমন আইটেম যুক্ত করা ইত্যাদি) করা ।ListAdapteronScroll

নিম্নলিখিতটি ListActivity40 টি দিয়ে শুরু করে, যখন তালিকার শেষে ব্যবহারকারী স্ক্রোল করে তখন আইটেম যুক্ত করে একটি সংখ্যার তালিকা দেখায়।

public class Test extends ListActivity implements OnScrollListener {

    Aleph0 adapter = new Aleph0();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(adapter); 
        getListView().setOnScrollListener(this);
    }

    public void onScroll(AbsListView view,
        int firstVisible, int visibleCount, int totalCount) {

        boolean loadMore = /* maybe add a padding */
            firstVisible + visibleCount >= totalCount;

        if(loadMore) {
            adapter.count += visibleCount; // or any other amount
            adapter.notifyDataSetChanged();
        }
    }

    public void onScrollStateChanged(AbsListView v, int s) { }    

    class Aleph0 extends BaseAdapter {
        int count = 40; /* starting amount */

        public int getCount() { return count; }
        public Object getItem(int pos) { return pos; }
        public long getItemId(int pos) { return pos; }

        public View getView(int pos, View v, ViewGroup p) {
                TextView view = new TextView(Test.this);
                view.setText("entry " + pos);
                return view;
        }
    }
}

দীর্ঘ চলমান ক্রিয়াগুলির জন্য আপনার স্পষ্টতই পৃথক থ্রেড ব্যবহার করা উচিত (যেমন ওয়েব ডেটা লোড করা) এবং সর্বশেষ তালিকা আইটেমের (যেমন বাজার বা জিমেইল অ্যাপ্লিকেশনগুলি) অগ্রগতি নির্দেশ করতে চাইবেন।


3
হুঁ, আপনি যদি পর্দার মাঝখানে স্ক্রোলিং বন্ধ করে দিতেন তবে এই অ্যাডাপ্টারের আকার বাড়বে না? এটি কেবলমাত্র পরবর্তী 10 টি লোড করা উচিত যখন তালিকার নীচে পৌঁছানোর সময়।
ম্যাথিয়াস

9
আমি বেসএডাপ্টার ব্যবহার করে এর মতো প্রচুর উদাহরণ লক্ষ্য করি। এটি উল্লেখ করতে চেয়েছিলেন যে আপনি যদি একটি ডেটাবেস ব্যবহার করছেন তবে একটি সিম্পল কার্সর অ্যাডাপ্টার ব্যবহার করে দেখুন। যখন আপনাকে তালিকায় যুক্ত করতে হবে, আপনার ডাটাবেসটি আপডেট করুন, একটি নতুন কার্সার পান এবং নোটিফাইডাটাসেট চেঞ্জডের সাথে সিম্পলসার্সার অ্যাডাপ্টার # চেঞ্জকার্সার ব্যবহার করুন। কোনও সাবক্লাসিংয়ের প্রয়োজন নেই এবং এটি বেসএডাপ্টারের চেয়ে ভাল পারফর্ম করে (আবার, কেবলমাত্র আপনি যদি একটি ডাটাবেস ব্যবহার করছেন)।
ব্রেক করুন

1
NotifyDataSetChanged () কল করার পরে, এটি তালিকার শীর্ষে যাবে, আমি কীভাবে এটি আটকাতে পারি?
আঁকুন

2
একটি নোট - আমি এই পদ্ধতিটি ব্যবহার করেছি, তবে যখন দৃশ্যমানসংখ্যার মান 0 হয় তখন একটি চেক যুক্ত করতে হবে প্রতিটি তালিকার জন্য, আমি অনস্ক্রোলটিতে একটি কলব্যাক পাই যেখানে প্রথম দেখা যায়, দৃশ্যমানকাউন্ট এবং টোটালকাউন্ট সমস্ত 0 হয়, যা প্রযুক্তিগতভাবে শর্তসাপেক্ষে পূরণ করে তবে তা হয় না is যখন আমি আরও লোড করতে চাই।
এরিক মিল

5
এই কোডটির সাথে আর একটি সমস্যা হ'ল শর্তটি firstVisible + visibleCount >= totalCountশ্রোতাদের একাধিক কল দিয়ে একাধিকবার পূরণ করা হয়। যদি লোড-মোর ফাংশন কোনও ওয়েব অনুরোধ হয়, (সম্ভবত এটি হবে), যদি অনুরোধ চলছে বা না হয় তার জন্য অন্য একটি চেক যুক্ত করুন। অন্যদিকে, টোটাল কাউন্টটি পূর্বের মোট গণনার সমান নয় কিনা তা পরীক্ষা করুন, কারণ তালিকার একই সংখ্যক আইটেমের জন্য আমাদের একাধিক অনুরোধের প্রয়োজন নেই।
সাবিন সেবাস্তিয়ান

94

আমি আমার অ্যাপ্লিকেশনটির জন্য একটি সমাধানটি অবদান রাখতে চেয়েছিলাম।

এটি OnScrollListenerইন্টারফেসের উপরও ভিত্তি করে তৈরি , তবে আমি কম-এন্ড ডিভাইসগুলিতে আরও ভাল স্ক্রোলিং পারফরম্যান্স পেয়েছি বলে দেখা যায়, যেহেতু দৃশ্যমান / মোট গণনা গণনার কোনওই স্ক্রোল ক্রিয়াকলাপের সময় সম্পন্ন হয় না।

  1. আপনার ListFragmentবা ListActivityবাস্তবায়ন করতে দিনOnScrollListener
  2. এই শ্রেণিতে নিম্নলিখিত পদ্ধতিগুলি যুক্ত করুন:

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        //leave this empty
    }
    
    @Override
    public void onScrollStateChanged(AbsListView listView, int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE) {
            if (listView.getLastVisiblePosition() >= listView.getCount() - 1 - threshold) {
                currentPage++;
                //load more list items:
                loadElements(currentPage);
            }
        }
    }
    

    currentPageআপনার ডাটাসোর্সের পৃষ্ঠাটি কোথায় যা আপনার তালিকায় যুক্ত করা উচিত এবং thresholdতালিকার আইটেমগুলির সংখ্যা (শেষ থেকে গণনা করা) যা দৃশ্যমান হলে লোডিংয়ের প্রক্রিয়াটি ট্রিগার করা উচিত। আপনি যদি সেট thresholdকরে থাকেন 0, উদাহরণস্বরূপ, আরও আইটেম লোড করতে ব্যবহারকারীকে তালিকার একেবারে প্রান্তে স্ক্রোল করতে হবে।

  3. (alচ্ছিক) আপনি দেখতে পাচ্ছেন, "লোড-মোর চেক" কেবল তখনই বলা হয় যখন ব্যবহারকারী স্ক্রোলিং বন্ধ করে দেয়। ব্যবহারযোগ্যতা উন্নত করতে, আপনি ফোলা এবং এর মাধ্যমে তালিকার শেষে একটি লোডিং সূচক যোগ করতে পারেন listView.addFooterView(yourFooterView)। এই জাতীয় পাদটীকা দেখার জন্য একটি উদাহরণ:

    <?xml version="1.0" encoding="utf-8"?>
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/footer_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dp" >
    
        <ProgressBar
            android:id="@+id/progressBar1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_gravity="center_vertical" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/progressBar1"
            android:padding="5dp"
            android:text="@string/loading_text" />
    
    </RelativeLayout>
    
  4. (alচ্ছিক) অবশেষে, listView.removeFooterView(yourFooterView)কোনও আইটেম বা পৃষ্ঠা না থাকলে কল করে সেই লোডিং সূচকটি সরিয়ে ফেলুন ।


আমি এটি চেষ্টা করেছিলাম তবে এটি তালিকাফ্র্যাগমেন্টের জন্য কাজ করে না। তালিকাভুক্তিতে এটি কীভাবে ব্যবহার করা যায়।
জিশান

ঠিক আছে, আমি এটির ListFragmentপাশাপাশি কোনও সমস্যা ছাড়াই এটি ব্যবহার করি - উপরের প্রতিটি পদক্ষেপটি অনুসরণ করুন এবং আপনি ভাল থাকবেন;) অথবা আপনি কোনও ত্রুটি বার্তা সরবরাহ করতে পারেন?
সাসচোয়ার

কি আপনি মিস করেছেন এই তাই উত্তরে ব্যাখ্যা করা হয় stackoverflow.com/a/6357957/1478093 -getListView().setOnScrollListener(this)
TBieniek

7
দ্রষ্টব্য: তালিকাভিউতে পাদচরণ যুক্ত করা এবং মুছে ফেলা সমস্যাযুক্ত (পাদলেখ যুক্ত করার আগে সেটএডাপ্টার বলা হয় তবে ফুটারটি প্রদর্শিত হবে না), আমি এটি অপসারণ না করে সরাসরি পাদলেখের দৃশ্যমানতার সংশোধন শেষ করেছি।
ডিভিডি

লোড এলিমেন্টে (কারেন্টেজ) কী যুক্ত করতে হবে ??? মানে আমি কি আমার এসিঙ্কটাস্ক বা থ্রেড কল করব?
অ্যান্ড্রয়েড_ডিভোপার

20

আপনি oncrolListener এর সাহায্যে তালিকার শেষটি সনাক্ত করতে পারেন , কার্য কোড নীচে উপস্থাপন করা হয়েছে:

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    if (view.getAdapter() != null && ((firstVisibleItem + visibleItemCount) >= totalItemCount) && totalItemCount != mPrevTotalItemCount) {
        Log.v(TAG, "onListEnd, extending list");
        mPrevTotalItemCount = totalItemCount;
        mAdapter.addMoreData();
    }
}

এটি করার আরেকটি উপায় (অ্যাডাপ্টারের অভ্যন্তরে) নিম্নরূপ:

    public View getView(int pos, View v, ViewGroup p) {
            if(pos==getCount()-1){
                addMoreData(); //should be asynctask or thread
            }
            return view;
    }

সচেতন হোন যে এই পদ্ধতিটি অনেকবার কল করা হবে, সুতরাং আপনাকে একাধিক কল ব্লক করতে অন্য শর্ত যুক্ত করতে হবে addMoreData()

আপনি যখন তালিকায় সমস্ত উপাদান যুক্ত করবেন, দয়া করে ভিউটি আপডেট করতে আপনার অ্যাডাপ্টারের অভ্যন্তরে notifyDataSetChanged () কল করুন (এটি ইউআই থ্রেডে চালানো উচিত - রানঅনুআইথ্রেড )


7
ভিউতে ফিরে আসার চেয়ে অন্য জিনিসগুলি করা খারাপ অভ্যাস getView। উদাহরণস্বরূপ, আপনি গ্যারান্টিযুক্ত নয় posযা ব্যবহারকারীর দ্বারা দেখা হয়েছে। এটি কেবল তালিকাভিউ মাপার স্টাফ হতে পারে।
টমাস আহলে

10 টি আইটেম স্ক্রোল হওয়ার পরে আমি আরও আইটেম লোড করতে চাই। তবে আমি লক্ষ্য করেছি যে 9 তম আইটেমটি 10 ​​ম আইটেমটি দৃশ্যমান হওয়ার আগেই লোডিং শুরু হয় o সুতরাং কীভাবে এটি বন্ধ করবেন?
অতুল ভরদ্বাজ

4

Ognyan Bankov GitHubআমার একটি সহজ এবং কাজ সমাধান পাওয়া!

এটি Volley HTTP libraryঅ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলির জন্য নেটওয়ার্কিংকে সহজ এবং সবচেয়ে গুরুত্বপূর্ণভাবে, দ্রুততর করে তোলে। ভোলি উন্মুক্ত এওএসপি সংগ্রহস্থলের মাধ্যমে উপলব্ধ।

প্রদত্ত কোডটি দেখায়:

  1. HTV পৃষ্ঠাভুক্ত অনুরোধ দ্বারা পপুলিযুক্ত তালিকাভিউ।
  2. নেটওয়ার্কআইমেজভিউয়ের ব্যবহার।
  3. "শেষবিহীন" তালিকার ভিউ পৃষ্ঠাগুলি পড়ুন-এগিয়ে ahead

ভবিষ্যতের দৃistence়তার জন্য আমি ব্যাংকভের রেপো কাঁটাচামচ করেছিলাম


2

এখানে একটি সমাধান রয়েছে যা লোড হওয়ার সময় তালিকার ভিউয়ের শেষে লোডিং ভিউ প্রদর্শন করা সহজ করে তোলে।

আপনি এখানে ক্লাস দেখতে পারেন:

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - সহায়তার সাহায্যে এটি ব্যবহার করা সম্ভব হয় সিম্পললিস্টভিউউথলিওডিং ইন্ডিকেটর থেকে প্রসারিত ছাড়াই বৈশিষ্ট্যগুলি।

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrolListener.java - শ্রোতা যখন ব্যবহারকারী লোড করা শুরু করে তালিকাভিউয়ের নীচে পৌঁছতে চলেছে।

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - এন্ডলেস লিস্টভিউ। আপনি এই ক্লাসটি সরাসরি ব্যবহার করতে বা এটি থেকে প্রসারিত করতে পারেন।


1

কিছুটা দেরি হতে পারে তবে নিম্নলিখিত সমাধানটি আমার ক্ষেত্রে খুব দরকারী। একটি উপায়ে আপনাকে যা করতে হবে তা হ'ল আপনার তালিকাভিউতে যুক্ত করুন Footerএবং এর জন্য তৈরি করুন addOnLayoutChangeListener

http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)

উদাহরণ স্বরূপ:

ListView listView1 = (ListView) v.findViewById(R.id.dialogsList); // Your listView
View loadMoreView = getActivity().getLayoutInflater().inflate(R.layout.list_load_more, null); // Getting your layout of FooterView, which will always be at the bottom of your listview. E.g. you may place on it the ProgressBar or leave it empty-layout.
listView1.addFooterView(loadMoreView); // Adding your View to your listview 

...

loadMoreView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
         Log.d("Hey!", "Your list has reached bottom");
    }
});

যখন কোনও পাদলেখ দৃশ্যমান হয়ে যায় এবং মনোমুগ্ধকর মতো কাজ করে তখন এই ইভেন্টটি ছড়িয়ে যায়।


0

এই সমস্যাটির মূলটি হ'ল লোড-মোর ইভেন্টটি সনাক্ত করা, ডেটাগুলির জন্য একটি অ্যাসিঙ্ক অনুরোধ শুরু করা এবং তারপরে তালিকাটি আপডেট করা। এছাড়াও লোডিং ইন্ডিকেটর এবং অন্যান্য সজ্জকার সহ একটি অ্যাডাপ্টার প্রয়োজন। আসলে, কোন কোন ক্ষেত্রে সমস্যাটি খুব জটিল। কেবলমাত্র একটি OnScrollListenerবাস্তবায়নই যথেষ্ট নয়, কারণ কখনও কখনও আইটেমগুলি স্ক্রিনটি পূরণ করে না।

আমি একটি ব্যক্তিগত প্যাকেজ লিখেছি যা এর জন্য অন্তহীন তালিকার সমর্থন করে RecyclerViewএবং একটি অ্যাসিঙ্ক লোডার প্রয়োগও সরবরাহ করে AutoPagerFragmentযা বহু-পৃষ্ঠার উত্স থেকে ডেটা পাওয়া খুব সহজ করে তোলে। এটি RecyclerViewকেবল পরের পৃষ্ঠায় নয়, একটি কাস্টম ইভেন্টে আপনি যে কোনও পৃষ্ঠা লোড করতে পারেন ।

এখানে ঠিকানাটি: https://github.com/SphiaTower/AutoPagerRecyclerManager


লিঙ্কটি নষ্ট হয়ে গেছে।
DSlomer64

0

এখন পর্যন্ত সেরা সমাধান যা আমি দেখেছি তা রিসাইক্লার দেখার জন্য ফাস্টএডাপ্টার লাইব্রেরিতে। এটি একটি EndlessRecyclerOnScrollListener

এখানে ব্যবহারের একটি উদাহরণ রয়েছে: এন্ডলেসস্ক্রোললিস্টঅ্যাক্টিভিটি

একবার আমি অন্তহীন স্ক্রোলিং তালিকার জন্য এটি ব্যবহার করেছি আমি বুঝতে পেরেছি যে সেটআপটি খুব শক্ত। আমি অবশ্যই এটি সুপারিশ করব।


0

আমি এর সাথে মিলে থাকা অন্য একটি সমাধানে কাজ করছি, তবে আমি footerViewব্যবহারকারীকে আরও বেশি উপাদান ক্লিক করে আরও ডাউনলোড করতে সম্ভাব্যতা দেওয়ার জন্য footerViewএকটি ব্যবহার করছি, আমি একটি "মেনু" ব্যবহার করছি যা ListViewনীচের অংশে এবং নীচে দেখানো হয়েছে প্যারেন্ট ভিউ, এই "মেনু" এর নীচের অংশটি গোপন করে ListView, সুতরাং, যখন listViewমেনুটি স্ক্রল করছে মেনুটি অদৃশ্য হয়ে যায় এবং যখন স্ক্রোলের অবস্থানটি নিষ্ক্রিয় থাকে, তখন মেনুটি আবার উপস্থিত হয়, তবে যখন ব্যবহারকারীটি শেষের দিকে স্ক্রোল করে listView, আমি "জিজ্ঞাসা" করতে চাই যদি সেই footerViewক্ষেত্রে প্রদর্শিত হয় তবে মেনুটি উপস্থিত হবে না এবং ব্যবহারকারীকে footerViewআরও সামগ্রী লোড করতে দেখতে পান। এখানে কোড:

শুভেচ্ছা।

listView.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub
        if(scrollState == SCROLL_STATE_IDLE) {
            if(footerView.isShown()) {
                bottomView.setVisibility(LinearLayout.INVISIBLE);
            } else {
                bottomView.setVisibility(LinearLayout.VISIBLE);
            } else {
                bottomView.setVisibility(LinearLayout.INVISIBLE);
            }
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {

    }
});

0

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

তালিকাটি শেষ আইটেমে কখন স্ক্রোল করা হয়েছে বা শেষ আইটেমটি থেকে সরে যাওয়ার সময় এটি সনাক্ত করতে এটি তালিকার সাথে ব্যবহৃত বেসএডাপ্টার ব্যবহার করে।

এটি একটি উদাহরণ প্রকল্পের সাথে আসে (কার্যকলাপের কোডের সবেমাত্র 100 লাইন) যা এটি কীভাবে কাজ করে তা দ্রুত বুঝতে ব্যবহার করা যেতে পারে।

সাধারণ ব্যবহার:

class Boy{

private String name;
private double height;
private int age;
//Other code

}

বয় অবজেক্টগুলি ধরে রাখার জন্য একটি অ্যাডাপ্টারের মতো দেখতে হবে:


public class BoysAdapter extends EndlessAdapter<Boy>{




        ViewHolder holder = null;


        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent
                    .getContext());

            holder = new ViewHolder();

            convertView = inflater.inflate(
                    R.layout.list_cell, parent, false);


            holder.nameView = convertView.findViewById(R.id.cell);

            // minimize the default image.
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Boy boy = getItem(position);

        try {
            holder.nameView.setText(boy.getName());

            ///Other data rendering codes.

        } catch (Exception e) {
            e.printStackTrace();
        }

        return super.getView(position,convertView,parent);

}

বয়েজএডাপ্টারের গেটভিউ পদ্ধতিটি কীভাবে এন্ডলেসএডাপ্টার সুপারক্লাসের getViewপদ্ধতিতে কল দেয় তা লক্ষ করুন । এটি 100% অপরিহার্য।

এখন অ্যাডাপ্টার তৈরি করতে, করুন:

   adapter = new ModelAdapter() {
            @Override
            public void onScrollToBottom(int bottomIndex, boolean moreItemsCouldBeAvailable) {

                if (moreItemsCouldBeAvailable) { 
                    makeYourServerCallForMoreItems();
                } else {
                    if (loadMore.getVisibility() != View.VISIBLE) {
                        loadMore.setVisibility(View.VISIBLE);
                    }
                }
            }

            @Override
            public void onScrollAwayFromBottom(int currentIndex) { 
                loadMore.setVisibility(View.GONE);
            }

            @Override
            public void onFinishedLoading(boolean moreItemsReceived) { 
                if (!moreItemsReceived) {
                    loadMore.setVisibility(View.VISIBLE);
                }
            }
        };

loadMoreআইটেম একটি বোতাম বা অন্যান্য UI উপাদান যে URL থেকে আরো ডেটা আনতে ক্লিক হতে পারে। কোডটিতে বর্ণিত হিসাবে স্থাপন করা হলে, অ্যাডাপ্টার ঠিক কখন জানায় যে কখন সেই বোতামটি প্রদর্শন করতে হবে এবং কখন এটি অক্ষম করতে হবে। আপনার এক্সএমএলটিতে কেবল বোতামটি তৈরি করুন এবং উপরের অ্যাডাপ্টারের কোড হিসাবে দেখানো হয়েছে।

উপভোগ করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.