recyclerview 实现viewpager grideview分页效果 GrideSnapHelper

为了逼自己学习,所以瞎折腾一下,让自己张点见识。

项目中原来使用的是ViewPager + GrideView 实现的卡片滑动,代码挺多的,我非得想改造成用recyclerView实现,

话说折腾成功。先看下效果。

recyclerview 实现viewpager grideview分页效果 GrideSnapHelper_第1张图片

每页三列,滑动停止后自动找到最近的一页停下。

大多数人都是直接实现SnapHelper,但是我武功没那么高强,况且只要能解决问题的同志就是好裁缝!对于那些没有问题制造困难也要解决问题的好同志,我只能说,带我飞.

我给这个类起名叫GrideSnapHelper,感觉实现了GrideSnapHelper很高达上...其实我只实现了滚动监听而已.

使用方法:

        GrideSnapHelper grideSnapHelper = new GrideSnapHelper(3,3,this);
        grideSnapHelper.attachToRecycleView(recyclerView);

GrideSnapHelper源码

    import android.app.Activity;
        import android.support.v7.widget.GridLayoutManager;
        import android.support.v7.widget.RecyclerView;
        import android.util.Log;
        import android.view.View;
        import android.view.WindowManager;

        import java.util.ArrayList;

        import static android.content.ContentValues.TAG;
        import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
        import static android.support.v7.widget.RecyclerView.SCROLL_STATE_SETTLING;
        import static android.widget.NumberPicker.OnScrollListener.SCROLL_STATE_IDLE;

/**
 * Created by 瑜哥 on 2018/3/29.
 * 1:寻找锚点:visiable fist last范围内%行*列=0的都是锚点
 * 2:锚点为正,如果超过屏幕的一半,取当前锚点-1,如果小于屏幕一半取当前锚点
 */

public class GrideSnapHelper {

    RecyclerView recyclerView;
    int horizon, column;
    private GridLayoutManager layoutManager;
    private ArrayList positionLisit;
    private final int screen_width;

    public GrideSnapHelper(int horizon, int column, Activity ctx) {
        this.horizon = horizon;
        this.column = column;
        WindowManager wm1 = ctx.getWindowManager();
        screen_width = wm1.getDefaultDisplay().getWidth();
    }

    public void attachToRecycleView(RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
        setListener();
    }

    private void setListener() {
        if (recyclerView == null) {
            return;
        }
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case SCROLL_STATE_IDLE:
                        System.out.println("recyclerview已经停止滚动");
                        snapView();
                        break;
                    case SCROLL_STATE_DRAGGING:
                        System.out.println("recyclerview正在被拖拽");
                        break;
                    case SCROLL_STATE_SETTLING:
                        System.out.println("recyclerview正在依靠惯性滚动");
                        break;
                }
            }
        });


    }

    private void snapView() {
        if (layoutManager ==null) {
            layoutManager = (GridLayoutManager)recyclerView.getLayoutManager();
            positionLisit = new ArrayList<>();
        }
        //寻找锚点
        positionLisit.clear();
        int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
        int lastVisibleItem = layoutManager.findLastVisibleItemPosition();
        for (int i = firstVisibleItem;i<=lastVisibleItem;i++) {
            if (i%(column*horizon)==0)
                positionLisit.add(i);
        }
        Log.d(TAG, "positionLisit: "+positionLisit.toString());
        //选择锚点
        int targetPosition = 0;
        //有1个锚点  锚点X坐标大于屏幕一半取上一个锚点,锚点X坐标小于屏幕一半取当前锚点
        if (positionLisit.size() == 1) {
            View item = layoutManager.findViewByPosition(positionLisit.get(0));
            if (item==null) return;
            final int []location=new int[2];
            item.getLocationOnScreen(location);
            int x=location[0];//获取当前位置的横坐标
            int y=location[1];//获取当前位置的纵坐标
            if (x > screen_width / 2) {
                targetPosition = positionLisit.get(0) - column * horizon;
            } else {
                targetPosition = positionLisit.get(0);
            }
        }
        //有2个锚点  取小锚点
        else if (positionLisit.size() == 2) {
            targetPosition = positionLisit.get(0);
        }
        Log.d(TAG, "targetPosition: "+targetPosition);
//        recyclerView.smoothScrollToPosition(targetPosition);
        layoutManager.scrollToPositionWithOffset(targetPosition, 0);
    }
}

其实代码码只有两句话:

 1:寻找锚点:可视范围内所有条目的Position%(每页条目数)=0的都是锚点  
 2:选择锚点:有1个锚点  锚点X坐标大于屏幕一半取上一个锚点(当前锚点-每页条目数),锚点X坐标小于屏幕一半取当前锚点
                       有2个锚点  取position小的锚点

你可能感兴趣的:(Android开发)