Ich habe eine lange ListView
dass der Benutzer einen Bildlauf durchführen kann, bevor er zum vorherigen Bildschirm zurückkehrt. Wenn der Benutzer diese Seite öffnet ListView
Ich möchte, dass die Liste wieder an die gleiche Stelle wie zuvor gescrollt wird. Irgendwelche Ideen, wie man das erreichen kann?
Antworten
Zu viele Anzeigen?Versuchen Sie dies:
// save index and top position
int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - mList.getPaddingTop());
// ...
// restore index and position
mList.setSelectionFromTop(index, top);
Erläuterung:
ListView.getFirstVisiblePosition()
gibt das oberste sichtbare Listenelement zurück. Dieses Element kann jedoch teilweise aus dem Sichtfeld gerollt sein, und wenn Sie die genaue Rollposition der Liste wiederherstellen wollen, müssen Sie diesen Versatz ermitteln. Also ListView.getChildAt(0)
gibt die View
für das oberste Listenelement und dann View.getTop() - mList.getPaddingTop()
gibt seinen relativen Versatz vom oberen Rand der Datei ListView
. Dann, zur Wiederherstellung der ListView
die Scroll-Position, rufen wir ListView.setSelectionFromTop()
mit dem Index des gewünschten Elements und einem Versatz, um dessen Oberkante vom oberen Rand des ListView
.
Parcelable state;
@Override
public void onPause() {
// Save ListView state @ onPause
Log.d(TAG, "saving listview state");
state = listView.onSaveInstanceState();
super.onPause();
}
...
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Set new items
listView.setAdapter(adapter);
...
// Restore previous state (including selected item index and scroll position)
if(state != null) {
Log.d(TAG, "trying to restore listview state");
listView.onRestoreInstanceState(state);
}
}
Ich habe die von @(Kirk Woll) vorgeschlagene Lösung übernommen, und sie funktioniert bei mir. Ich habe auch im Android-Quellcode für die App "Kontakte" gesehen, dass dort eine ähnliche Technik verwendet wird. Ich möchte noch einige Details hinzufügen: Oben auf meiner ListActivity-abgeleiteten Klasse:
private static final String LIST_STATE = "listState";
private Parcelable mListState = null;
Dann werden einige Methoden außer Kraft gesetzt:
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
mListState = state.getParcelable(LIST_STATE);
}
@Override
protected void onResume() {
super.onResume();
loadData();
if (mListState != null)
getListView().onRestoreInstanceState(mListState);
mListState = null;
}
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
mListState = getListView().onSaveInstanceState();
state.putParcelable(LIST_STATE, mListState);
}
Natürlich ist "loadData" meine Funktion, um Daten aus der DB abzurufen und sie in die Liste zu stellen.
Auf meinem Froyo-Gerät funktioniert dies sowohl, wenn Sie die Ausrichtung des Telefons ändern, als auch, wenn Sie ein Element bearbeiten und zur Liste zurückkehren.
Ein sehr einfacher Weg:
/** Save the position **/
int currentPosition = listView.getFirstVisiblePosition();
//Here u should save the currentPosition anywhere
/** Restore the previus saved position **/
listView.setSelection(savedPosition);
Die Methode setSelection setzt die Liste auf das angegebene Element zurück. Wenn Sie sich nicht im Berührungsmodus befinden, wird das Element tatsächlich ausgewählt, wenn Sie sich im Berührungsmodus befinden, wird das Element nur auf dem Bildschirm positioniert.
Ein etwas komplizierterer Ansatz:
listView.setOnScrollListener(this);
//Implements the interface:
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
mCurrentX = view.getScrollX();
mCurrentY = view.getScrollY();
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
//Save anywere the x and the y
/** Restore: **/
listView.scrollTo(savedX, savedY);
Ich habe dazu etwas Interessantes gefunden.
Ich habe versucht, setSelection und scrolltoXY, aber es hat überhaupt nicht funktionieren, die Liste blieb in der gleichen Position, nach einigen Versuch und Irrtum habe ich den folgenden Code, der funktioniert
final ListView list = (ListView) findViewById(R.id.list);
list.post(new Runnable() {
@Override
public void run() {
list.setSelection(0);
}
});
Wenn Sie statt der Runnable zu posten runOnUiThread versuchen, funktioniert es auch nicht (zumindest auf einigen Geräten)
Dies ist eine sehr seltsame Lösung für etwas, das eigentlich ganz einfach sein sollte.
- See previous answers
- Weitere Antworten anzeigen