it-swarm.com.de

RecyclerView smoothScroll zur Positionierung in der Mitte. Android

Ich verwende den horizontalen Layout-Manager für meine RecyclerView. Ich muss RecyclerView auf die nächste Art und Weise machen: Wenn Sie auf ein Element klicken, machen Sie smoothScrool an diese Position und setzen dieses Element in die Mitte von RecyclerView (wenn möglich, zum Beispiel 10 Element) von 20).

Also, ich habe kein Problem mit smoothScrollToPosition(), aber wie stelle ich einen Gegenstand als in der Mitte von RecyclerView ???

Vielen Dank!

18
Stan Malcolm

Ja es ist möglich.

Durch die Implementierung der Methode von RecyclerView.SmoothScrolleronTargetFound(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);

Speziell in 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);
        }
    }
}
59
user3680200

Verbesserungen der Antwort - LinearLayoutManager muss nicht überschrieben werden

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

  smoothScroller.setTargetPosition(position);

  LinearLayoutManager(LinearLayoutManager for your RecyclerView).startSmoothScroll(smoothScroller);
2
user8944115

Nur falls jemand das Kotlin-Äquivalent der Klasse in der akzeptierten Antwort benötigt.

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)
    }
}
1
Boda

seit jetzt (Feb 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 das gleiche.

0
Corxit Sun