RecyclerView smoothScroll zur Position in der Mitte. Android

Lesezeit: 4 Minuten

Benutzeravatar von Stan Malcolm
Stan Malcom

Ich verwende einen horizontalen Layout-Manager für meine RecyclerView. Ich muss machen RecyclerView auf die nächste Weise: Wenn Sie auf ein Element klicken, machen Sie smoothScroll zu dieser Position und platzieren Sie dieses Element in der Mitte RecyclerView (möglichst z. B. 10 Stück von 20).

Also ich habe kein Problem damit smoothScrollToPosition()aber wie man Artikel als in der Mitte von setzt RecyclerView???

Vielen Dank!

Benutzeravatar von user3680200
Benutzer3680200

Ja es ist möglich.

Durch die Umsetzung RecyclerView.SmoothScroller‘s Methode onTargetFound(View, State, Action).

/**
 * Called when the target position is laid out. This is the last callback SmoothScroller
 * will receive and it should update the provided {@link Action} to define the scroll
 * details towards the target view.
 * @param targetView    The view element which render the target position.
 * @param state         Transient state of RecyclerView
 * @param action        Action instance that you should update to define final scroll action
 *                      towards the targetView
 */
abstract protected void onTargetFound(View targetView, State state, Action action);

Konkret im LinearLayoutManager mit LinearSmoothScroller:

public class CenterLayoutManager extends LinearLayoutManager {

    public CenterLayoutManager(Context context) {
        super(context);
    }

    public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller {

        CenterSmoothScroller(Context context) {
            super(context);
        }

        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }
    }
}

  • extends LinearSmoothScroller überschreiben muss computeScrollVectorForPosition()

    – Ninja

    27. Dezember 2016 um 7:02 Uhr

  • Hat einwandfrei funktioniert

    – Eliseo Ocampos

    21. April 2017 um 17:11 Uhr

  • Perfekt, für andere rufen Sie einfach an recyclerView.smoothScrollToPosition(position); und vergessen Sie nicht, den Layout-Manager einzustellen recyclerView.setLayoutManager(layoutManager);

    – Peter

    9. Juni 2017 um 15:58 Uhr

  • Wo ist das onTargetFound() Funktion implementiert?

    – Fehler passieren

    24. August 2018 um 11:05 Uhr

  • Aber ich habe nicht genau verstanden, warum Sie diese Methode erwähnt haben onTargetFound() ?

    – Sirop4ik

    31. Oktober 2018 um 8:55 Uhr

Benutzeravatar von 王 能
王能

Verbesserungen an der Antwort – Es besteht keine Notwendigkeit, die zu überschreiben LinearLayoutManager

Aus der vorherigen Antwort:

public class CenterSmoothScroller extends LinearSmoothScroller {

    public CenterSmoothScroller(Context context) {
        super(context);
    }

    @Override
    public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
        return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
    }
}

Hier, wie man es benutzt:

RecyclerView.LayoutManager lm = new GridLayoutManager(...): // or whatever layout manager you need

...

RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());

smoothScroller.setTargetPosition(position);

lm.startSmoothScroll(smoothScroller);

  • Für andere, die so verwirrt sind wie ich, CenterSmoothScroller ist eine Klasse, die in der akzeptierten Antwort gefunden wird.

    – RJR-Apps

    14. Februar 2019 um 23:20 Uhr


  • Halleluja! Sie haben einen halben Tag damit verbracht, eine Reihe komplizierter Methoden auszuprobieren, und Ihre Lösung funktioniert perfekt. Vielen Dank!

    – mjp66

    18. März 2020 um 23:25 Uhr

  • Wie bekomme ich die Position, während ich die Recycleransicht deklariere? Ich muss das Element in die Mitte bringen, während der Benutzer das Element mit dem D-Pad scrollt. @ user8944115

    – Aravind

    28. April 2020 um 7:31 Uhr


  • das funktionierte wie ein Zauber!! Danke, wenn Sie die Klasse nicht finden, müssen Sie vielleicht Ihre Abhängigkeiten aktualisieren, ist unter androidx.recyclerview.widget.LinearSmoothScroller

    – Javier

    2. Juli 2021 um 9:46 Uhr


  • Es ist die richtige und einfache Lösung. Vielen Dank

    – Trung Đoan

    25. Oktober 2021 um 5:30 Uhr

Nur für den Fall, dass jemand die braucht Kotlin-Äquivalent der Klasse in der akzeptierten Antwort.

class CenterLayoutManager : LinearLayoutManager {
    constructor(context: Context) : super(context)
    constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State, position: Int) {
        val centerSmoothScroller = CenterSmoothScroller(recyclerView.context)
        centerSmoothScroller.targetPosition = position
        startSmoothScroll(centerSmoothScroller)
    }

    private class CenterSmoothScroller(context: Context) : LinearSmoothScroller(context) {
        override fun calculateDtToFit(viewStart: Int, viewEnd: Int, boxStart: Int, boxEnd: Int, snapPreference: Int): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2)
    }
}

Benutzeravatar von furkanbzkurt
furkanbzkurt

Basierend auf der Antwort von @Boda können Sie Folgendes verwenden, wenn Sie die reibungslose Bildlaufgeschwindigkeit (für eine bessere Animation) steuern möchten:

class CenterLayoutManager : LinearLayoutManager {
    constructor(context: Context) : super(context)
    constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(
        context,
        orientation,
        reverseLayout
    )

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
        context,
        attrs,
        defStyleAttr,
        defStyleRes
    )

    override fun smoothScrollToPosition(
        recyclerView: RecyclerView,
        state: RecyclerView.State,
        position: Int
    ) {
        val centerSmoothScroller = CenterSmoothScroller(recyclerView.context)
        centerSmoothScroller.targetPosition = position
        startSmoothScroll(centerSmoothScroller)
    }

    private class CenterSmoothScroller(context: Context) : LinearSmoothScroller(context) {
        override fun calculateDtToFit(
            viewStart: Int,
            viewEnd: Int,
            boxStart: Int,
            boxEnd: Int,
            snapPreference: Int
        ): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2)

        override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
            return MILLISECONDS_PER_INCH / displayMetrics.densityDpi
        }
    }

    companion object {
        // This number controls the speed of smooth scroll
        private const val MILLISECONDS_PER_INCH = 150f
    }
}

Verwendung:

recyclerView.layoutManager = CenterLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
recyclerView.smoothScrollToPosition(selectedPosition)

seit jetzt (Februar 2019) konnte ich diesen Code problemlos in ListView verwenden

(ListView)word_list_view.smoothScrollToPositionFromTop(your_item_index, center_position.y);

RecyclerView nicht verifiziert, ich denke, das wäre dasselbe.

  • Nicht verfügbar für RecyclerView

    – tagy22

    18. Dezember 2019 um 13:42 Uhr

  • Nicht verfügbar für RecyclerView

    – tagy22

    18. Dezember 2019 um 13:42 Uhr

1438760cookie-checkRecyclerView smoothScroll zur Position in der Mitte. Android

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy