web-dev-qa-db-de.com

(Glatt) ScrollToPosition funktioniert nicht ordnungsgemäß mit RecyclerView

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!

36
petrushka1986

Endlich konnte ich es schaffen! LinearLayoutManager.scrollToPositionWithOffset(int, int) hat den Trick gemacht.

53
petrushka1986

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.

13
Ramz

In meinem Fall,

`mRecyclerView.scrollToPosition(10);` 

funktionierte auch nicht .. 

`mRecyclerView.smoothScrollToPosition(10);` 

funktioniert gut für mich ...

9
zephyr

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);

1
J.Sattar

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
1
Ahmed KHABER

Messen Sie die Breite oder Höhe des Elements und rufen Sie smoothScrollBy (int dx, int dy) auf.

1
Dubrovin

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

0
Chiam Simon V

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.

0
live-love

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);
0
orelzion