Bagaimana saya bisa membuat daftar di mana ketika Anda mencapai akhir daftar saya diberitahu sehingga saya dapat memuat lebih banyak item?
Bagaimana saya bisa membuat daftar di mana ketika Anda mencapai akhir daftar saya diberitahu sehingga saya dapat memuat lebih banyak item?
Jawaban:
Salah satu solusinya adalah mengimplementasikan OnScrollListener
dan membuat perubahan (seperti menambahkan item, dll.) ListAdapter
Ke kondisi yang nyaman dalam onScroll
metodenya.
Yang berikut ini ListActivity
memperlihatkan daftar bilangan bulat, mulai dengan 40, menambahkan item ketika pengguna menggulir ke akhir daftar.
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;
}
}
}
Anda jelas harus menggunakan utas terpisah untuk tindakan jangka panjang (seperti memuat data web) dan mungkin ingin menunjukkan kemajuan dalam item daftar terakhir (seperti yang dilakukan pasar atau aplikasi gmail).
firstVisible + visibleCount >= totalCount
dipenuhi beberapa kali dengan beberapa panggilan ke pendengar. Jika fungsi load-more adalah permintaan web, (kemungkinan besar itu adalah), tambahkan cek lain untuk melihat apakah permintaan sedang berjalan atau tidak. Di sisi lain, periksa apakah totalCount tidak sama dengan jumlah total Sebelumnya, karena kami tidak perlu beberapa permintaan untuk jumlah item yang sama dalam daftar.
Hanya ingin menyumbangkan solusi yang saya gunakan untuk aplikasi saya.
Ini juga didasarkan pada OnScrollListener
antarmuka, tetapi saya menemukan itu memiliki kinerja scrolling yang jauh lebih baik pada perangkat low-end, karena tidak ada perhitungan jumlah terlihat / total dilakukan selama operasi gulir.
ListFragment
atau ListActivity
implementasikanOnScrollListener
Tambahkan metode berikut ke kelas itu:
@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);
}
}
}
di mana currentPage
halaman sumber data Anda yang harus ditambahkan ke daftar Anda, dan threshold
jumlah item daftar (dihitung dari akhir) yang seharusnya, jika terlihat, memicu proses pemuatan. Jika Anda mengatur threshold
ke 0
, misalnya, pengguna harus menggulir ke bagian paling akhir daftar untuk memuat lebih banyak item.
(opsional) Seperti yang Anda lihat, "pemeriksaan beban-lebih" hanya dipanggil ketika pengguna berhenti menggulir. Untuk meningkatkan kegunaan, Anda dapat mengembang dan menambahkan indikator pemuatan ke akhir daftar melalui listView.addFooterView(yourFooterView)
. Salah satu contoh untuk tampilan footer seperti itu:
<?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>
(opsional) Akhirnya, hapus indikator memuat itu dengan menelepon listView.removeFooterView(yourFooterView)
jika tidak ada lagi item atau halaman.
ListFragment
baik tanpa masalah - cukup ikuti setiap langkah di atas dan Anda akan baik-baik saja;) Atau Anda bisa memberikan pesan kesalahan?
getListView().setOnScrollListener(this)
Anda dapat mendeteksi akhir daftar dengan bantuan onScrollListener , kode kerjanya disajikan di bawah ini:
@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();
}
}
Cara lain untuk melakukan itu (di dalam adaptor) adalah sebagai berikut:
public View getView(int pos, View v, ViewGroup p) {
if(pos==getCount()-1){
addMoreData(); //should be asynctask or thread
}
return view;
}
Perlu diketahui bahwa metode ini akan dipanggil berkali-kali, jadi Anda perlu menambahkan kondisi lain untuk memblokir beberapa panggilan addMoreData()
.
Ketika Anda menambahkan semua elemen ke daftar, silakan hubungi notifyDataSetChanged () di dalam adaptor Anda untuk memperbarui tampilan (itu harus dijalankan pada utas UI - runOnUiThread )
getView
. Misalnya, Anda tidak dijamin pos
dilihat oleh pengguna. Mungkin hanya hal-hal pengukuran ListView.
Pada Ognyan Bankov GitHub
saya menemukan solusi yang sederhana dan berfungsi!
Itu menggunakan Volley HTTP library
yang membuat jaringan untuk aplikasi Android lebih mudah dan yang paling penting, lebih cepat. Volley tersedia melalui repositori AOSP terbuka.
Kode yang diberikan menunjukkan:
Untuk konsistensi di masa depan saya membayar repo Bankov .
Berikut ini adalah solusi yang juga memudahkan untuk menampilkan tampilan pemuatan di akhir ListView saat sedang memuat.
Anda dapat melihat kelas di sini:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Pembantu agar memungkinkan untuk menggunakan fitur tanpa memperluas dari SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Pendengar yang mulai memuat data saat pengguna akan mencapai bagian bawah ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Anda dapat menggunakan kelas ini secara langsung atau memperluas dari itu.
Mungkin sedikit terlambat tetapi solusi berikut ini terjadi sangat berguna dalam kasus saya. Yang perlu Anda lakukan hanyalah menambah ListView Anda Footer
dan membuatnya addOnLayoutChangeListener
.
http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)
Sebagai contoh:
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");
}
});
Acara ini terjadi sekali ketika footer menjadi terlihat dan bekerja seperti pesona.
Kunci dari masalah ini adalah untuk mendeteksi peristiwa yang memuat lebih banyak, memulai permintaan async untuk data dan kemudian memperbarui daftar. Juga diperlukan adaptor dengan indikator memuat dan dekorator lainnya. Bahkan, masalahnya sangat rumit dalam beberapa kasus sudut. Hanya OnScrollListener
implementasi saja tidak cukup, karena kadang-kadang item tidak memenuhi layar.
Saya telah menulis paket pribadi yang mendukung daftar tanpa akhir RecyclerView
, dan juga menyediakan implementasi loader async AutoPagerFragment
yang membuatnya sangat mudah untuk mendapatkan data dari sumber multi-halaman. Itu dapat memuat halaman yang Anda inginkan ke dalam RecyclerView
acara khusus, tidak hanya halaman berikutnya.
Berikut alamatnya: https://github.com/SphiaTower/AutoPagerRecyclerManager
Solusi terbaik sejauh ini yang saya lihat adalah di perpustakaan FastAdapter untuk pandangan pendaur ulang. Itu memiliki EndlessRecyclerOnScrollListener
.
Berikut ini adalah contoh penggunaan: EndlessScrollListActivity
Setelah saya menggunakannya untuk daftar gulir tanpa akhir, saya menyadari bahwa pengaturannya sangat kuat. Saya pasti akan merekomendasikannya.
Saya telah bekerja di solusi lain yang sangat mirip dengan itu, tetapi, saya menggunakan footerView
untuk memberi kemungkinan kepada pengguna mengunduh lebih banyak elemen dengan mengklik footerView
, saya menggunakan "menu" yang ditunjukkan di atas ListView
dan di bagian bawah tampilan induk, "menu" ini menyembunyikan bagian bawahnya ListView
, jadi, ketika menu listView
bergulir menghilang dan ketika status gulir idle, menu muncul lagi, tetapi ketika pengguna menggulir ke ujung menu listView
, saya "meminta" untuk tahu jika footerView
ditampilkan dalam kasus itu, menu tidak muncul dan pengguna dapat melihat footerView
untuk memuat lebih banyak konten. Berikut kodenya:
Salam.
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) {
}
});
Saya tahu ini adalah pertanyaan lama dan dunia Android sebagian besar telah beralih ke RecyclerViews, tetapi bagi siapa pun yang tertarik, Anda mungkin menemukan perpustakaan ini sangat menarik.
Ia menggunakan BaseAdapter yang digunakan dengan ListView untuk mendeteksi kapan daftar telah digulir ke item terakhir atau ketika sedang digulir menjauh dari item terakhir.
Itu datang dengan contoh proyek (hampir 100 baris kode aktivitas) yang dapat digunakan untuk dengan cepat memahami cara kerjanya.
Penggunaan sederhana:
class Boy{
private String name;
private double height;
private int age;
//Other code
}
Adaptor untuk menampung objek Boy akan terlihat seperti:
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);
}
Perhatikan bagaimana metode getView BoysAdapter mengembalikan panggilan ke metode superclass EndlessAdapter getView
. Ini 100% penting.
Sekarang untuk membuat adaptor, lakukan:
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);
}
}
};
The loadMore
item tombol atau elemen ui lain yang mungkin diklik untuk mengambil lebih banyak data dari url. Ketika ditempatkan sebagaimana dijelaskan dalam kode, adaptor tahu persis kapan harus menunjukkan tombol itu dan kapan harus menonaktifkannya. Cukup buat tombol di xml Anda dan letakkan seperti yang ditunjukkan pada kode adaptor di atas.
Nikmati.