webentwicklung-frage-antwort-db.com.de

Wie speichere ich die Scroll-Position von RecyclerView in Android?

Ich habe eine Recycler-Ansicht, die sich innerhalb von SwipeRefreshLayout befindet. Außerdem haben Sie die Möglichkeit, jedes Element in einer anderen Aktivität zu öffnen. Nach dem Zurückkehren zum Recycler muss ich zum ausgewählten Element oder zum vorherigen Y blättern. Wie geht das?

Ja, ich habe gegoogelt und in StackOverFlow Artikel zum Speichern der Instanz des Layout Managers gefunden, wie zum Beispiel: RecyclerView-Speicher/Wiederherstellungsstatus zwischen Aktivitäten . Aber es hilft mir nicht.

UPDATE

Im Moment habe ich diese Art der Problemlösung, aber natürlich funktioniert es auch nicht.

private int scrollPosition;

...//onViewCreated - it is fragment
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(llm);
data = new ArrayList<>();
adapter.setData(getActivity(), data);
recyclerView.setAdapter(adapter);
...

@Override
public void onResume() {
    super.onResume();
    recyclerView.setScrollY(scrollPosition);
}

@Override
public void onPause() {
    super.onPause();
    scrollPosition = recyclerView.getScrollY();
}

Ja, ich habe scrollTo (int, int) ausprobiert - funktioniert nicht.

Jetzt habe ich versucht, beispielsweise nur zu Y = 100 zu scrollen, aber es wird überhaupt nicht gescrollt.

16
DefaultXYZ

Speichern Sie den aktuellen Status der Recycling-Ansichtsposition @onPause:

    positionIndex= llManager.findFirstVisibleItemPosition();
    View startView = rv.getChildAt(0);
    topView = (startView == null) ? 0 : (startView.getTop() - rv.getPaddingTop());

Stellen Sie die Bildlaufposition @onResume wieder her:

    if (positionIndex!= -1) {
        llManager.scrollToPositionWithOffset(positionIndex, topView);
    }

oder ein anderer Weg kann @onPause sein: 

long currentVisiblePosition = 0;
currentVisiblePosition = ((LinearLayoutManager)rv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();

@onResume wiederherstellen:

((LinearLayoutManager) rv.getLayoutManager()).scrollToPosition(currentVisiblePosition);
currentVisiblePosition = 0;
33
Madhukar Hebbar

Viele dieser Antworten scheinen zu kompliziert zu sein.

Der LayoutManager unterstützt onRestoreInstanceState sofort, so dass keine Bildlaufpositionen usw. gespeichert werden müssen. Die integrierte Methode speichert bereits perfekte Pixelpositionen.

beispiel-Fragmentcode (Nullprüfung usw. wurde zur besseren Übersichtlichkeit entfernt):

private Parcelable listState;
private RecyclerView list;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    listState=savedInstanceState.getParcelable("ListState");

}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putParcelable("ListState", list.getLayoutManager().onSaveInstanceState());

}

dann einfach anrufen

list.getLayoutManager().onRestoreInstanceState(listState);

sobald Ihre Daten wieder zu Ihrer RecyclerView hinzugefügt wurden

18
Kuffs

Verwenden Sie Ihren Recycler View Linearlayoutmanager, um die Bildlaufposition zu erhalten

int position = 0;
if (linearLayoutManager != null) {
   scrollPosition = inearLayoutManager.findFirstVisibleItemPosition();
}

und bei der Wiederherstellung folgenden Code verwenden

if (linearLayoutManager != null) {
  cardRecyclerView.scrollToPosition(mScrollPosition);
}

Hoffe das hilft dir

2
Nikhil

um die Position in den Einstellungen zu speichern, fügen Sie diese zu Ihrem onStop () hinzu.

 int currentVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
 getPreferences(MODE_PRIVATE).edit().putInt("listPosition", currentVisiblePosition).apply();

stellen Sie dann die Position so wieder her 

 if (getItemCount() == 0) {
     int savedListPosition = getPreferences(MODE_PRIVATE).getInt("listPosition", 0);
     recyclerView.getLayoutManager().scrollToPosition(savedListPosition); }

dieser letzte Code sollte in ein Ereignis des Adapters eingefügt werden (nicht sicher, welches Ereignis in meinem Fall onEvent () - com.google.firebase.firestore.EventListener war)

0
Dan Alboteanu

Aus irgendeinem Grund gibt es viele irreführende Tipps/Vorschläge zum Speichern und Wiederherstellen der Bildlaufposition in your_scrolling_container bei Orientierungsänderungen.

Aktuelle Scroll-Position übernehmen und in Activity onSaveInstanceState Speichern. Eine bestimmte scrollbare Ansicht erweitern, um das Gleiche dort zu tun Verhindern, dass Aktivität beim Rotieren zerstört wird Und ja, sie funktionieren gut, aber…

Tatsächlich ist alles viel einfacher, da Android es bereits für Sie erledigt!

Wenn Sie RecyclerView/ListView/ScrollView/NestedScrollView-Quellen genauer betrachten, werden Sie feststellen, dass jede von ihnen ihre Bildlaufposition in onSaveInstanceState speichert. Während des ersten Layout-Durchlaufs versuchen sie, in dieser Methode zu dieser Position zu scrollen.

Es gibt nur zwei Dinge, die Sie tun müssen, um sicherzustellen, dass alles einwandfrei funktioniert:

  1. Legen Sie eine ID für Ihre scrollbare Ansicht fest, die wahrscheinlich bereits erledigt ist. Andernfalls kann Android den Ansichtsstatus nicht automatisch speichern.

  2. Geben Sie vor dem ersten Layoutdurchlauf Daten an, um dieselben Bildlaufgrenzen wie vor der Drehung zu haben. In diesem Schritt haben Entwickler normalerweise einige Probleme.

0
Andrey T

Der einfachste und übergangskompatibelste Weg, den ich gefunden habe, ist:

   @Override
public void onPause() {
    super.onPause();
    recyclerView.setLayoutFrozen(true);
}

@Override
public void onResume() {
    super.onResume();
    recyclerView.setLayoutFrozen(false);
}
0
Mikias