Ich verwende grundlegende RecyclerView mit GridLayoutManager. Ich habe beobachtet, dass weder smoothScrollToPosition noch scrollToPosition ordnungsgemäß funktionieren.
a) Bei Verwendung von smoothScrollToPosition
erhalte ich häufig einen Fehler von RecyclerView
"RecyclerView ﹕ Die Zielposition wurde beim sanften Scrollen überfahren."
und RecyclerView
wird nicht ordnungsgemäß gescrollt (oft fehlt die angezielte Zeile). Dies wird meistens beobachtet, wenn ich versuche, zum ersten Element einer Zeile zu scrollen
b) Wenn Sie scrollToPosition
verwenden, scheint es ganz gut zu funktionieren, aber meistens sehe ich nur den ersten Eintrag der Zeile und der Rest wird nicht angezeigt.
Können Sie mir einige Hinweise geben, wie man wenigstens eine der Methoden richtig funktionieren lässt?
Danke vielmals!
Endlich konnte ich es schaffen! LinearLayoutManager.scrollToPositionWithOffset(int, int)
hat den Trick gemacht.
Ich habe auch dasselbe Problem, aber es ist mir gelungen, das Problem durch Anpassen von SmoothScroller zu beheben
lassen Sie Custom LayoutManager wie folgt
public class CustomLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 50f;
private Context mContext;
public CustomLayoutManager(Context context) {
super(context);
mContext = context;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView,
RecyclerView.State state, final int position) {
LinearSmoothScroller smoothScroller =
new LinearSmoothScroller(mContext) {
//This controls the direction in which smoothScroll looks
//for your view
@Override
public PointF computeScrollVectorForPosition
(int targetPosition) {
return CustomLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
//This returns the milliseconds it takes to
//scroll one pixel.
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH/displayMetrics.densityDpi;
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
}
(Dokumentation innerhalb des oben angegebenen Codes kommentiert) Bitte setzen Sie den obigen LayoutManager auf den Recyerview
CustomLayoutManagerlayoutManager = new CustomLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.smoothScrollToPosition(position);
mit dem benutzerdefinierten Layout-Manager
scrollToPosition Funktioniert auch gut in meinem Fall
recyclerView.scrollToPosition(position)
auch wenn Sie die Geschwindigkeit von smoothScrollToPosition anpassen möchten, überschreiben Sie bitte die
private static final float MILLISECONDS_PER_INCH = 50f;
in CustomLayoutManager . Wenn wir also den Wert als 1f setzen, wird smoothScrollToPosition schneller als scrollToPosition.increasing Wert.
In meinem Fall,
`mRecyclerView.scrollToPosition(10);`
funktionierte auch nicht ..
`mRecyclerView.smoothScrollToPosition(10);`
funktioniert gut für mich ...
Um von einer beliebigen Position in der RecyclerView nach unten zu scrollen, klicken Sie auf EditText.
edittext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
rv_commentList.postDelayed(new Runnable() {
@Override
public void run() {
rv_commentList.scrollToPosition(rv_commentList.getAdapter().getItemCount() - 1);
}
}, 1000);
}
});
recyclerView.getLayoutManager (). smoothScrollToPosition (recyclerView, new RecyclerView.State (), currentPosition);
So führen Sie einen reibungslosen Bildlauf durch und speichern die vertikale Position von RecyclerView
nach dem Drehen des Geräts: Dies ist die Methode, die in meinem Fall funktioniert.
public class MainFragment extends Fragment { //OR activity it's //fragment in my case
....
@Override
public void onLoadFinished(@NonNull Loader<List<Report>> loader, List<Report> objects) { // or other method of your choice, in my case it's a Loader
RecyclerView recyclerViewRv = findViewById(........;
.....
recyclerViewRv.setAdapter(.....Your adapter);
recyclerViewRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
recyclerScrollY = recyclerViewRv. computeVerticalScrollOffset();
}
});
//Apply smooth vertical scroll
recyclerViewRv.smoothScrollBy(0,recyclerScrollY);
}
//Save vertical scroll position before rotating devices
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("recyclerScrollY",recyclerScrollY);
}
//BackUp vertical scroll position after rotating devices
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
recyclerScrollY = savedInstanceState.getInt("recyclerScrollY");
}
}
//If you want to perform the same operation for horizontal scrolling just add a variable called recyclerScrollX = recyclerScrollY = recyclerViewRv. computeHorizontalScrollOffset(); then save in bundle
Messen Sie die Breite oder Höhe des Elements und rufen Sie smoothScrollBy (int dx, int dy) auf.
wenn Sie scrollToPosition verwenden, wird es über der Recycler-Ansicht angezeigt.
Wenn Sie jedoch smoothScrollToPosition verwenden, wird ein Bildlauf durchgeführt, bis das Fenster sichtbar ist. Deshalb wird smoothScrool unten angezeigt, aber es wird unten angezeigt
Wenn Sie einen schnellen Bildlauf zu einer Position oben in der RecyclerView durchführen möchten, verwenden Sie LinearLayoutManager.scrollToPositionWithOffset mit 0 als Offset.
Beispiel:
mLinearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLinearLayoutManager);
mLinearLayoutManager.scrollToPositionWithOffset(myPosition, 0);
smoothScrollToPosition ist sehr langsam. Wenn Sie etwas schnelles wollen, gehen Sie mit scrollToPositionWithOffset.
Der Aufruf der RecyclerView-Funktion smoothScroll ist nicht effektiv, da die RecyclerView das Layout nicht selbst verwaltet.
Sie sollten stattdessen die Scroll-Methode des Layout-Managers aufrufen.
Das sollte ungefähr so aussehen
mRecyclerView.getLayoutManager().scrollToPosition(desiredPosition);