मैं एक सूची कैसे बना सकता हूं, जहां जब आप सूची के अंत में पहुंच जाते हैं तो मुझे सूचित किया जाता है ताकि मैं और आइटम लोड कर सकूं?
मैं एक सूची कैसे बना सकता हूं, जहां जब आप सूची के अंत में पहुंच जाते हैं तो मुझे सूचित किया जाता है ताकि मैं और आइटम लोड कर सकूं?
जवाबों:
एक उपाय यह है कि किसी विधि को लागू किया जाए OnScrollListener
और ListAdapter
अपनी onScroll
विधि में सुविधाजनक स्थिति में परिवर्तन (जैसे वस्तुओं को जोड़ना आदि) किया जाए ।
निम्नलिखित ListActivity
पूर्णांक की एक सूची दिखाता है, 40 से शुरू होकर, आइटम को जोड़ना जब उपयोगकर्ता सूची के अंत तक स्क्रॉल करता है।
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;
}
}
}
आपको स्पष्ट रूप से लंबे समय तक चलने वाली क्रियाओं (जैसे वेब-डेटा लोड करना) के लिए अलग थ्रेड्स का उपयोग करना चाहिए और अंतिम सूची आइटम (जैसे बाजार या जीमेल एप्स करना) में प्रगति का संकेत देना चाह सकते हैं।
firstVisible + visibleCount >= totalCount
सुनने वाले को कई कॉल के साथ कई बार शर्त पूरी होती है। यदि लोड-अधिक फ़ंक्शन एक वेब अनुरोध है, (सबसे शायद यह होगा), तो एक और चेक जोड़ें कि क्या अनुरोध चल रहा है या नहीं। दूसरी ओर, जांचें कि क्या टोटकाउंट पिछले कुल गिनती के बराबर नहीं है, क्योंकि हमें सूची में समान संख्याओं के लिए कई अनुरोधों की आवश्यकता नहीं है।
बस एक समाधान का योगदान करना चाहता था जिसका उपयोग मैंने अपने ऐप के लिए किया।
यह OnScrollListener
इंटरफ़ेस पर भी आधारित है, लेकिन मैंने पाया कि कम-एंड डिवाइस पर स्क्रॉलिंग का बेहतर प्रदर्शन है, क्योंकि स्क्रॉल ऑपरेशन के दौरान कोई भी दृश्य / कुल गणना गणना नहीं की जाती है।
ListFragment
या ListActivity
अमल करने दोOnScrollListener
उस वर्ग में निम्नलिखित विधियाँ जोड़ें:
@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
, तो उपयोगकर्ता को अधिक आइटम लोड करने के लिए सूची के बहुत अंत तक स्क्रॉल करना होगा।
(वैकल्पिक) जैसा कि आप देख सकते हैं, "लोड-अधिक चेक" केवल तभी कहा जाता है जब उपयोगकर्ता स्क्रॉल करना बंद कर देता है। प्रयोज्य में सुधार करने के लिए, आप एक लोडिंग इंडिकेटर को सूची के अंत तक बढ़ा सकते हैं और जोड़ सकते हैं 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>
(वैकल्पिक) अंत में, listView.removeFooterView(yourFooterView)
यदि कोई और आइटम या पृष्ठ नहीं हैं, तो कॉल करके उस लोडिंग इंडिकेटर को हटा दें ।
ListFragment
बिना किसी समस्या के साथ उपयोग करता हूं - बस ऊपर दिए गए प्रत्येक चरण का पालन करें और आप ठीक हो जाएंगे?) या आप कोई त्रुटि संदेश प्रदान कर सकते हैं?
getListView().setOnScrollListener(this)
आप सूची के अंत का पता लगा सकते हैं onScrollListener की मदद से , वर्किंग कोड नीचे प्रस्तुत किया गया है:
@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()
।
जब आप सूची में सभी तत्वों को जोड़ते हैं, तो कृपया व्यू को अपडेट करने के लिए अपने एडेप्टर के अंदर InformDataSetChanged () कॉल करें (यह UI थ्रेड पर चलाया जाना चाहिए - runOnUiThread )
getView
। उदाहरण के लिए, आप pos
उपयोगकर्ता द्वारा देखे जाने की गारंटी नहीं देते हैं । यह बस ListView मापने के सामान हो सकता है।
पर Ognyan Bankov GitHub
मैं एक सरल और काम कर समाधान मिल गया!
यह इसका उपयोग करता है Volley HTTP library
जो Android ऐप्स के लिए नेटवर्किंग को आसान और सबसे महत्वपूर्ण, तेज़ बनाता है। वॉली खुले एओएसपी रिपॉजिटरी के माध्यम से उपलब्ध है।
दिया गया कोड प्रदर्शित करता है:
भविष्य की निरंतरता के लिए मैंने बैंकोव के रेपो को त्याग दिया ।
यहां एक समाधान है जो लोड करते समय ListView के अंत में एक लोडिंग दृश्य दिखाना आसान बनाता है।
आप यहां कक्षाएं देख सकते हैं:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - हेल्पर इसे संभव बनाने के लिए उपयोग करें। SimpleListViewWithLoadingIndicator से विस्तार किए बिना सुविधाएँ।
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - श्रोता जो उपयोगकर्ता को डेटा लोड करते समय शुरू करता है। ListView के निचले भाग तक पहुंचने वाला है।
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - EndlessListView। आप इस क्लास को सीधे इस्तेमाल कर सकते हैं या इससे बढ़ा सकते हैं।
थोड़ी देर हो सकती है लेकिन निम्नलिखित समाधान मेरे मामले में बहुत उपयोगी है। एक तरह से आपको बस इतना करना है कि अपनी सूची में जोड़ें 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");
}
});
यह घटना एक बार फायर करती है जब एक पाद दिखाई देता है और एक आकर्षण की तरह काम करता है।
इस समस्या की कुंजी लोड-अधिक ईवेंट का पता लगाना, डेटा के लिए एक async अनुरोध शुरू करना और फिर सूची को अपडेट करना है। इसके अलावा लोडिंग इंडिकेटर और अन्य डेकोरेटर्स के साथ एडॉप्टर की जरूरत होती है। वास्तव में, समस्या कुछ कोने के मामलों में बहुत जटिल है। बस एक OnScrollListener
कार्यान्वयन पर्याप्त नहीं है, क्योंकि कभी-कभी आइटम स्क्रीन को नहीं भरते हैं।
मैंने एक व्यक्तिगत पैकेज लिखा है, जो अंतहीन सूची का समर्थन करता है RecyclerView
, और एक async लोडर कार्यान्वयन भी प्रदान करता है AutoPagerFragment
जो बहु-पृष्ठ स्रोत से डेटा प्राप्त करना बहुत आसान बनाता है। यह किसी भी पृष्ठ RecyclerView
को किसी कस्टम ईवेंट में लोड कर सकता है , न कि अगले पृष्ठ पर।
यहाँ पता है: https://github.com/SphiaTower/AutoPagerRecyclerManager
अब तक का सबसे अच्छा समाधान जो मैंने देखा है, वह पुनर्नवीनीकरण विचारों के लिए फास्टएडस्केप पुस्तकालय में है। यह एक है EndlessRecyclerOnScrollListener
।
यहाँ एक उदाहरण का उपयोग किया गया है: EndlessScrollListActivity
एक बार जब मैंने इसे अंतहीन स्क्रॉलिंग सूची के लिए उपयोग किया तो मुझे महसूस हुआ कि सेटअप बहुत मजबूत है। मैं निश्चित रूप से इसकी सिफारिश करूंगा।
मैं उसी के समान एक अन्य समाधान में काम कर रहा हूं, लेकिन, मैं 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) {
}
});
मुझे पता है कि इसका एक पुराना सवाल है और एंड्रॉइड की दुनिया ज्यादातर रिसाइकलर व्यू में चली गई है, लेकिन किसी भी इच्छुक व्यक्ति के लिए, आपको यह लाइब्रेरी बहुत दिलचस्प लग सकती है ।
यह सूची देखने के लिए उपयोग किए गए बेस एडेप्टर का उपयोग यह पता लगाने के लिए करता है कि सूची को अंतिम आइटम पर स्क्रॉल किया गया है या जब इसे अंतिम आइटम से दूर स्क्रॉल किया जा रहा है।
यह एक उदाहरण परियोजना (गतिविधि कोड की बमुश्किल 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 तत्व यह है कि यूआरएल से अधिक डेटा लाने के लिए क्लिक किया जा सकता है। जब कोड में वर्णित के रूप में रखा जाता है, तो एडेप्टर को पता है कि उस बटन को कब दिखाना है और कब अक्षम करना है। बस अपने xml में बटन बनाएं और इसे ऊपर दिए गए एडॉप्टर कोड में दिखाए।
का आनंद लें।