RecyclerView指定された場所を画面の中央にスクロール


背景
製品の要求を受けて、RecyclerViewにitemをクリックしてからRecyclerViewの中間位置にスクロールさせる必要があります.
構想
LayoutManagerのカスタマイズ
  • カスタムSmoothScroller継承LinearSmoothScroller
  • LinearLayoutManagerを継承smoothScrollToPositionコールカスタムSmoothScroller
  • を書き換える
  • calculateDtToFitメソッドにおけるint viewStart,int viewEnd,int boxStart,int boxEndの意味計算スクロール位置の下に抜粋した部分LinearSmoothScrollerのソースコード
  • があることを明らかにする.
    //LinearSmoothScroller     calculateDtToFit     
    //top = item view   
    final int top = layoutManager.getDecoratedTop(view) - params.topMargin;
    //bottom = item view   
    final int bottom = layoutManager.getDecoratedBottom(view) + params.bottomMargin;
    //start = RecyclerView    
    final int start = layoutManager.getPaddingTop();
    //end = RecyclerView    
    final int end = layoutManager.getHeight() - layoutManager.getPaddingBottom();
    return calculateDtToFit(top, bottom, start, end, snapPreference);
    

    インプリメンテーション
    
    import android.content.Context;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.LinearSmoothScroller;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    
    public class CenterLinearLayoutManager extends LinearLayoutManager {
    
        public CenterLinearLayoutManager(Context context) {
            super(context);
        }
    
        public CenterLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }
    
        public CenterLinearLayoutManager(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 {
    
            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);
            }
    
    		//    
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return 100f / displayMetrics.densityDpi;
            }
    
        }
    
    }
    

    使用
    RecyclerViewのLayoutManagerを切り替えるだけ
    mListView.setLayoutManager(new CenterLinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));