Android图片上下左右滑动特效--Recycker实现

来源:互联网 发布:田丰 阿里云 领英 编辑:程序博客网 时间:2024/06/14 03:08

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客

今天是初七了,我在这里先给大家拜个晚年了,祝大家在新的一年里身体健康,月月加薪,不出bug!大笑

我这篇博客是来给大家送福利的哟,什么福利呢?先看看效果呗


今天可能都上班了,我明白大家的心情,所以献上美女争艳图让小伙伴们缓解缓解心里的不爽。

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客

好了,言归正传了,下面跟大家分享下这个效果的实现吧。

这个效果跟探探APP的效果是一样的,没错,我做出来的效果就是跟它的那个功能完全一样的。下面分享给大家↓

这个效果我是使用的RecyclerView实现的,上次我给大家分享过一篇有关RecyclerView的子布局换位置和横向滑动删除的效果(查看),

这次是使用RecyclerView实现了这样的效果,可以说Google的推出的这个组件真的是很nice。分析下这个效果的核心,这个效果主要的难点就在于

面的重叠位置,我现在是放了10张图片,但是能看到的只有三张,并且一张比一张小,第三张以后的都被盖在了第三张的下面。这个效果是怎么实现的呢?咱们一点一点来。

用过RecyclerView的都知道,RecyclerView最后以什么形式展示,是取决于它的布局管理器,比如现有的ListView形式的(横向/纵向), GrideView形式的,瀑布流形式的(横向/纵向)等等,但是就现有的来看,好像完不成我们想要的效果啊。所以我的这个效果是自定义的布局管理 器来实现的。那么我们应该怎么实现呢?看我的代码,上面都添加了注释。

先看看工具类的东西吧。

/** * 工具类 * 作者:宋鑫  2017/1/29 11:18 * 邮箱:songxinnianshao@yeah.com */public class CardConfig {    //屏幕上最多显示几个item    public static  int MAX_SHOW_COUNT;    //每一集Scale相差0.05ftranslation相差7dp左右    public static float SCALR_GAP;    public static int TRANS_Y_GAP;    public static void initConfig(Context cxt){        MAX_SHOW_COUNT = 4;        SCALR_GAP = 0.05F;        TRANS_Y_GAP = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,15,cxt.getResources().getDisplayMetrics());    }}
【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客

/** * 自定义布局管理器 * 作者:宋鑫  2017/1/29 11:04 * 邮箱:songxinnianshao@yeah.com * childView 的宽高、摆放 * measureChildren()/layoutchildren */public class MyLayoutManager extends RecyclerView.LayoutManager {    /**     * 生成LayoutParams     * 这个方法不用操心   它是一个抽象方法     * 因为我们要自定义布局所以直接返回RecyclerViewLayoutParams就可以了     */    @Override    public RecyclerView.LayoutParams generateDefaultLayoutParams() {        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);    }    /**     * 摆放子控件的方法     */    @Override    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {        //摆放里面的子控件        /**         * Recycler 的核心源码:RecylerRecyclerViewPool         * ViewHolder的重用、缓冲--Scrap(废弃)、detach(解除绑定)、attach(绑定)         */        //1.在布局之前,讲所有的子Viewdetach掉,放入到Scrap缓存中        detachAndScrapAttachedViews(recycler);        //得到条目的数量        int itemcount = getItemCount();        if (itemcount < 1) {            return;        }        //找到最后一个不需要完全重叠的item的位置:这个地方我需要好好的解释一下        // 现在RecyclerView的条目是10个,但是第十个的下标为9RecyclerView的条目顺序是这样的,最底层的下标为0,最顶层的下标为9 所以我们如果我们要找最后一个不重叠的也就是说从上面往下数        //的第三个,   这个第三个从下往上数的下标是7     但是呢我们现在的小标为6 为什么呢  因为下标为9的不需要操作啊   所以我们就把6完全重叠     78进行缩放,9不缩放   还不明白的话        // 请继续阅读代码        int bottomPosition;        if (itemcount < CardConfig.MAX_SHOW_COUNT) {            bottomPosition = 0;        } else {            bottomPosition = itemcount - CardConfig.MAX_SHOW_COUNT;        }        for (int position = bottomPosition; position < itemcount; position++) {            //从缓存池里面取出一个item            View view = recycler.getViewForPosition(position);            //View加入到RecyclerView            addView(view);            measureChildWithMargins(view, 0, 0);            //空白区域   因为每一个条目的外面会有一个装饰,所以我们需要把装饰的距离计算出来并减掉            int widthSpace = getWidth() - getDecoratedMeasuredWidth(view);//屏幕的宽度减去使用的宽度就是横向所有空白区的宽度            int heightSpace = getHeight() - getDecoratedMeasuredHeight(view);//屏幕的高度减去使用的高度就是纵向所有空白区的高度            layoutDecorated(view, widthSpace / 2,//                    heightSpace / 2,//                    widthSpace / 2 + getDecoratedMeasuredWidth(view),//                    heightSpace / 2 + getDecoratedMeasuredHeight(view));//            //找到最上面的3个图层     层叠效果            /**             * 这里是从最下面往上数的但是呢 我们有需要只让两个进行缩放  itemcount8  比如当前是0就进不去第二个if             *             */            int level = itemcount - position - 1;            if (level > 0) {                view.setScaleX(1-CardConfig.SCALR_GAP*level);                if (level <CardConfig.MAX_SHOW_COUNT-1) {                    //第二个和第三个图层 需要缩放                    view.setTranslationY(CardConfig.TRANS_Y_GAP*level);                    view.setScaleY(1-CardConfig.SCALR_GAP*level);                }else{                    //这里是从顶层往下面数第四个  就需要完全重叠了                    Log.d("bbbb", "level:"+level);                    view.setTranslationY(CardConfig.TRANS_Y_GAP*(level -1));                    view.setScaleY(1-CardConfig.SCALR_GAP*(level-1));                }            }        }    }}
看完之后是不是有点蒙啊?没有事,最后我会把资源分享给大家的!但是现在还是要继续阅读博客。有点耐心哈

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客

看完上面的布局管理器是不是感觉没有爱啊?没事 其实就这一点难点,剩下的就简单了,继续!适配器的代码我就不贴在这里了,下面我们看下如何让RecyclerView左右上下的滑动吧!这里我也 是使用的跟上次以上的ItemTouchHelper操作的。看看主界面的代码吧(不要偷偷去看美女的图片哟)

/** * 作者:宋鑫  2017/1/29 11:04 * 邮箱:songxinnianshao@yeah.com */public class MainActivity extends AppCompatActivity {    private RecyclerView rv;    private String[] imgs = {            "http://pic38.nipic.com/20140301/18089642_120611589000_2.jpg",            "http://pic9.nipic.com/20100729/4918637_184806756306_2.jpg",            "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1485665845533&di=8cadf32d7562f7f40fe429dd0451040e&imgtype=0&src=http%3A%2F%2Fimg2.ph.126.net%2FDPx3oh2_Te1Q4d8Pa7_7ng%3D%3D%2F6631360235797243142.jpg",            "http://a.hiphotos.baidu.com/image/pic/item/dcc451da81cb39dbce6b325ad2160924ab183016.jpg",            "http://h.hiphotos.baidu.com/image/pic/item/b3fb43166d224f4af732261f0bf790529822d117.jpg",            "http://c.hiphotos.baidu.com/image/pic/item/0b7b02087bf40ad128102ae7552c11dfa9ecce3a.jpg",            "http://a.hiphotos.baidu.com/image/pic/item/faf2b2119313b07e5ad5b10c0ed7912397dd8c4e.jpg",            "http://img2.imgtn.bdimg.com/it/u=708771340,1463709076&fm=23&gp=0.jpg",            "http://e.hiphotos.baidu.com/image/pic/item/5882b2b7d0a20cf4bd2028d674094b36acaf9903.jpg",            "http://g.hiphotos.baidu.com/image/pic/item/a1ec08fa513d26976764cfd857fbb2fb4216d884.jpg",    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        rv = (RecyclerView) findViewById(R.id.rv);        rv.setLayoutManager(new MyLayoutManager());        List<SwoprBean> list = new ArrayList<>();        for (int i = 0; i < imgs.length; i++) {            SwoprBean bean = new SwoprBean();            bean.setPath(imgs[i]);            bean.setName("美女"+(i+1));            bean.setIndex(i+1);            list.add(bean);        }        MyAdapter adapter = new MyAdapter(list);        rv.setAdapter(adapter);        ItemTouchHelper.Callback callback = new RecyclerCallback(rv,adapter,list);        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);        touchHelper.attachToRecyclerView(rv);        CardConfig.initConfig(this);    }}

这里需要一个Callback,这个Callback才是能左右上下滑动的重点呢,很简单我就直接贴代码了啊,有不懂的地方欢迎私聊我或者留言

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客

/** * 作者:宋鑫  2017/1/29 19:38 * 邮箱:songxinnianshao@yeah.com */public class RecyclerCallback extends ItemTouchHelper.SimpleCallback {    private List<SwoprBean> dates;    private RecyclerView.Adapter mAdapter;    private RecyclerView mRv;    public RecyclerCallback(RecyclerView rv, RecyclerView.Adapter adapter, List dates) {        //方向:四个方向分别代表什么意思:Move \ Swiped        this(0, ItemTouchHelper.DOWN | ItemTouchHelper.UP | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);        this.mRv = rv;        this.mAdapter = adapter;        this.dates = dates;    }    public RecyclerCallback(int dragDirs, int swipeDirs) {        super(dragDirs, swipeDirs);    }    @Override    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {        return false;    }    @Override    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {        //滑动完毕----direction:1UP 2down  4left  8right        SwoprBean remove = dates.remove(viewHolder.getLayoutPosition());//        Log.d("aaaaa", "onSwiped: "+);        switch (direction) {            case ItemTouchHelper.DOWN:                ToastUtils.showToast(mRv.getContext(),"方向:下,滑掉的第"+remove.getIndex()+"个美女");                break;            case ItemTouchHelper.UP:                ToastUtils.showToast(mRv.getContext(),"方向:上,滑掉的第"+remove.getIndex()+"个美女");                break;            case ItemTouchHelper.LEFT:                ToastUtils.showToast(mRv.getContext(),"方向:左,滑掉的第"+remove.getIndex()+"个美女");                break;            case ItemTouchHelper.RIGHT:                ToastUtils.showToast(mRv.getContext(),"方向:右,滑掉的第"+remove.getIndex()+"个美女");                break;        }        dates.add(0, remove);        mAdapter.notifyDataSetChanged();    }    public float getThreashold() {        return mRv.getWidth() * 0.5f;    }    @Override    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);        //零界点----跟滑动的比例系数有关系--百分比        double distance = Math.sqrt(dX * dX + dY * dY);//移动的距离        double fraction = distance / getThreashold();        if (fraction > 1) {            fraction = 1;        }        int childCount = recyclerView.getChildCount();        for (int i = 0; i < childCount; i++) {            View child = recyclerView.getChildAt(i);            int level = childCount - i - 1;            if (level > 0) {                child.setScaleX((float) (1 - CardConfig.SCALR_GAP * level + fraction * CardConfig.SCALR_GAP));                if (level < CardConfig.MAX_SHOW_COUNT - 1) {                    //顶层的3个图层                    child.setTranslationY((float) (CardConfig.TRANS_Y_GAP * level - fraction * CardConfig.TRANS_Y_GAP));                    child.setScaleY((float) (1 - CardConfig.SCALR_GAP * level + fraction * CardConfig.SCALR_GAP));                } else {                    //下面的图层-- 完全层叠//                    child.setTranslationY(CardConfig.TRANS_Y_GAP*(level -1));//                    child.setScaleY(1-CardConfig.SCALR_GAP*(level-1));                }            }        }    }}
以上就是这个效果的核心代码,有不明白的地方欢迎大家私信我或者留言,大家一起探讨交流,这里是这次代码的资源大笑

【独具匠心http://my.csdn.net/songxin393764941 未经允许严禁转载,请尊重作者劳动成果。我的博客】



3 0
原创粉丝点击