Saya sudah lama ListView
bahwa pengguna dapat menggulir di sekitar sebelum kembali ke layar sebelumnya. Ketika pengguna membuka ini ListView
lagi, saya ingin daftar tersebut digulir ke titik yang sama seperti sebelumnya. Ada ide tentang cara mencapai ini?
android
android-listview
scroll
scroll-position
rantravee
sumber
sumber
Jawaban:
Coba ini:
Penjelasan:
ListView.getFirstVisiblePosition()
mengembalikan item daftar paling terlihat. Tetapi item ini mungkin sebagian digulir keluar dari pandangan, dan jika Anda ingin mengembalikan posisi gulir yang tepat dari daftar Anda perlu mendapatkan offset ini. JadiListView.getChildAt(0)
mengembalikanView
untuk item daftar teratas, dan kemudianView.getTop() - mList.getPaddingTop()
mengembalikan ofset relatifnya dari atasListView
. Kemudian, untuk mengembalikanListView
posisi gulir, kita memanggilListView.setSelectionFromTop()
dengan indeks item yang kita inginkan dan offset ke posisi tepi atas dari atasListView
.sumber
int index = mList.getFirstVisiblePosition();
dan hanya satu baris untuk mengembalikan:mList.setSelectionFromTop(index, 0);
. Jawabannya bagus (+1)! Saya telah mencari solusi elegan untuk masalah ini.sumber
Saya mengadopsi solusi yang disarankan oleh @ (Kirk Woll), dan itu berfungsi untuk saya. Saya juga melihat dalam kode sumber Android untuk aplikasi "Kontak", bahwa mereka menggunakan teknik yang sama. Saya ingin menambahkan beberapa perincian: Di atas pada kelas yang diturunkan dari ListActivity saya:
Kemudian, beberapa metode menimpa:
Tentu saja "loadData" adalah fungsi saya untuk mengambil data dari DB dan memasukkannya ke dalam daftar.
Pada perangkat Froyo saya, ini berfungsi baik ketika Anda mengubah orientasi telepon, dan ketika Anda mengedit item dan kembali ke daftar.
sumber
mListState = getListView().onSaveInstanceState().
Terutama pada rotasi perangkat.onRestoreInstanceState
tidak pernah dipanggil :(Cara yang sangat sederhana:
Metode setSelection akan mengatur ulang daftar ke item yang disediakan. Jika tidak dalam mode sentuh item sebenarnya akan dipilih jika dalam mode sentuh item hanya akan diposisikan di layar.
Pendekatan yang lebih rumit:
sumber
Saya menemukan sesuatu yang menarik tentang ini.
Saya mencoba setSelection dan scrolltoXY tetapi tidak berhasil sama sekali, daftar tetap di posisi yang sama, setelah beberapa coba-coba saya mendapat kode berikut yang berfungsi
Jika alih-alih memposting Runnable Anda mencoba menjalankanOnUiThread juga tidak berfungsi (setidaknya pada beberapa perangkat)
Ini adalah solusi yang sangat aneh untuk sesuatu yang harus lurus ke depan.
sumber
setSelectionFromTop()
tidak berhasil.PERINGATAN!! Ada bug di AbsListView yang tidak memungkinkan onSaveState () berfungsi dengan benar jika ListView.getFirstVisiblePosition () adalah 0.
Jadi Jika Anda memiliki gambar besar yang mengambil sebagian besar layar, dan Anda menggulir ke gambar kedua, tetapi sedikit yang pertama ditampilkan, posisi gulir Tidak akan disimpan ...
dari AbsListView.java:1650 (komentar milik saya)
Tetapi dalam situasi ini, 'top' dalam kode di bawah ini akan menjadi angka negatif yang menyebabkan masalah lain yang mencegah negara untuk dipulihkan dengan benar. Jadi ketika 'top' negatif, dapatkan anak berikutnya
sumber
Cukup
sumber
Untuk beberapa orang yang mencari solusi untuk masalah ini, akar masalah mungkin di mana Anda mengatur adaptor tampilan daftar Anda. Setelah Anda mengatur adaptor pada tampilan daftar, itu akan mengatur ulang posisi gulir. Hanya sesuatu yang perlu dipertimbangkan. Saya pindah pengaturan adaptor ke onCreateView saya setelah kami mengambil referensi ke listview, dan itu memecahkan masalah bagi saya. =)
sumber
Saya memposting ini karena saya terkejut tidak ada yang menyebutkan ini.
Setelah pengguna mengklik tombol kembali, ia akan kembali ke tampilan daftar dalam kondisi yang sama saat ia keluar dari sana.
Kode ini akan menimpa tombol "atas" untuk berperilaku dengan cara yang sama seperti tombol kembali sehingga dalam kasus Listview -> Detail -> Kembali ke Listview (dan tidak ada pilihan lain) ini adalah kode paling sederhana untuk mempertahankan posisi gulir dan konten dalam tampilan daftar.
Perhatian: Jika Anda dapat pergi ke aktivitas lain dari aktivitas detail, tombol naik akan mengembalikan Anda kembali ke aktivitas itu sehingga Anda harus memanipulasi sejarah tombol back agar ini berfungsi.
sumber
Tidak cukup hanya
android:saveEnabled="true"
dengan deklarasi ListView xml?sumber
SOLUSI TERBAIK ADALAH:
ANDA HARUS MEMANGGIL DALAM POS DAN DI BENANG!
sumber
Anda dapat mempertahankan status gulir setelah memuat ulang jika Anda menyimpan keadaan sebelum memuat ulang dan mengembalikannya. Dalam kasus saya, saya membuat permintaan jaringan yang tidak sinkron dan memuat ulang daftar itu dalam panggilan balik setelah selesai. Di sinilah saya mengembalikan keadaan. Contoh kode adalah Kotlin.
sumber
Jika Anda menggunakan fragmen yang dihosting pada suatu aktivitas, Anda dapat melakukan sesuatu seperti ini:
sumber
Jika Anda menyimpan / mengembalikan posisi gulir
ListView
diri Anda, Anda pada dasarnya menduplikasi fungsi yang sudah diterapkan dalam kerangka kerja android. TheListView
mengembalikan baik posisi gulir hanya baik pada sendiri kecuali satu peringatan: sebagai @aaronvargas disebutkan ada bug diAbsListView
yang tidak akan membiarkan untuk mengembalikan posisi gulir baik untuk daftar item pertama. Namun demikian cara terbaik untuk mengembalikan posisi gulir adalah tidak mengembalikannya. Kerangka kerja Android akan lebih baik untuk Anda. Pastikan Anda telah memenuhi ketentuan berikut:setSaveEnabled(false)
metode dan tidak mengaturandroid:saveEnabled="false"
atribut untuk daftar di file tata letak xmlExpandableListView
overridelong getCombinedChildId(long groupId, long childId)
sehingga mengembalikan angka panjang positif (implementasi default di kelasBaseExpandableListAdapter
mengembalikan angka negatif). Berikut ini contohnya:.
ListView
atauExpandableListView
digunakan dalam sebuah fragmen, jangan membuat ulang fragmen tersebut pada aktivitas rekreasi (setelah rotasi layar misalnya). Dapatkan fragmen denganfindFragmentByTag(String tag)
metode.ListView
memilikiandroid:id
dan unik.Untuk menghindari peringatan yang disebutkan di atas dengan item daftar pertama, Anda dapat membuat adaptor Anda dengan cara mengembalikan adaptor khusus ketinggian nol piksel untuk
ListView
posisi at 0. Berikut adalah contoh sederhana proyek yang menunjukkanListView
danExpandableListView
mengembalikan posisi gulir halusnya sedangkan posisi gulirnya tidak disimpan secara eksplisit. /pulih. Posisi gulir halus dipulihkan dengan sempurna bahkan untuk skenario kompleks dengan beralih sementara ke beberapa aplikasi lain, rotasi layar ganda dan beralih kembali ke aplikasi uji. Harap dicatat, jika Anda secara eksplisit keluar dari aplikasi (dengan menekan tombol Kembali) posisi gulir tidak akan disimpan (dan semua Tampilan lainnya tidak akan menyimpan statusnya). https://github.com/voromto/RestoreScrollPosition/releasessumber
Untuk aktivitas yang berasal dari ListActivity yang mengimplementasikan LoaderManager.LoaderCallbacks menggunakan SimpleCursorAdapter tidak berfungsi untuk mengembalikan posisi di onReset (), karena aktivitas itu hampir selalu dimulai kembali dan adaptor dimuat kembali ketika tampilan detail ditutup. Caranya adalah mengembalikan posisi di onLoadFinished ():
di onListItemClick ():
di onLoadFinished ():
di onBackPressed ():
sumber
Tak satu pun dari solusi yang ditawarkan di sini tampaknya bekerja untuk saya. Dalam kasus saya, saya memiliki
ListView
diFragment
mana saya menggantiFragmentTransaction
, jadiFragment
contoh baru dibuat setiap kali fragmen ditampilkan, yang berarti bahwaListView
negara tidak dapat disimpan sebagai anggotaFragment
.Alih-alih, saya akhirnya menyimpan status di
Application
kelas khusus saya . Kode di bawah ini akan memberi Anda gambaran bagaimana cara kerjanya:Ide dasarnya adalah Anda menyimpan keadaan di luar instance fragmen. Jika Anda tidak menyukai gagasan memiliki bidang statis di kelas aplikasi Anda, saya kira Anda bisa melakukannya dengan menerapkan antarmuka fragmen dan menyimpan keadaan dalam aktivitas Anda.
Solusi lain adalah menyimpannya
SharedPreferences
, tetapi itu menjadi sedikit lebih rumit, dan Anda harus memastikan Anda menghapusnya pada saat peluncuran aplikasi kecuali Anda ingin keadaan tetap ada di seluruh peluncuran aplikasi.Juga, untuk menghindari "posisi gulir tidak disimpan ketika item pertama terlihat", Anda dapat menampilkan item pertama dummy dengan
0px
tinggi. Ini dapat dicapai dengan menggantigetView()
adaptor Anda, seperti ini:sumber
Jawaban saya adalah untuk Firebase dan posisi 0 adalah solusi
dan convertView
posisi 0 a tambahkan item kosong yang tidak Anda gunakan
Saya telah melihat pekerjaan ini sementara waktu tanpa mengganggu pengguna, saya harap ini berfungsi untuk Anda
sumber
gunakan kode di bawah ini:
dan kapan pun Anda menyegarkan data Anda gunakan kode di bawah ini:
sumber
Saya menggunakan FirebaseListAdapter dan tidak bisa mendapatkan solusi apa pun untuk bekerja. Saya akhirnya melakukan ini. Saya menduga ada cara yang lebih elegan tetapi ini adalah solusi yang lengkap dan berfungsi.
Sebelum diCreate:
Di dalam FirebaseListAdapter:
onStart:
onStop:
Karena saya juga harus menyelesaikan ini untuk FirebaseRecyclerAdapter saya memposting solusi untuk itu juga:
Sebelum diCreate:
Di dalam FirebaseRecyclerAdapter:
onStart:
onStop:
sumber
Untuk mengklarifikasi jawaban yang sangat baik dari Ryan Newsom dan untuk menyesuaikannya untuk fragmen dan untuk kasus biasa yang ingin kita navigasi dari fragmen "master" ListView ke fragmen "detail" dan kemudian kembali ke "master"
"Ajaib" di sini adalah bahwa ketika kita menavigasi kembali dari fragmen detail ke fragmen ListView, tampilan tidak dibuat ulang, kita tidak mengatur adaptor ListView, jadi semuanya tetap seperti kita meninggalkannya!
sumber