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.05f,translation相差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 * 这个方法不用操心 它是一个抽象方法 * 因为我们要自定义布局所以直接返回RecyclerView的LayoutParams就可以了 */ @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 的核心源码:Recyler类 RecyclerViewPool * ViewHolder的重用、缓冲--Scrap(废弃)、detach(解除绑定)、attach(绑定) */ //1.在布局之前,讲所有的子View先detach掉,放入到Scrap缓存中 detachAndScrapAttachedViews(recycler); //得到条目的数量 int itemcount = getItemCount(); if (itemcount < 1) { return; } //找到最后一个不需要完全重叠的item的位置:这个地方我需要好好的解释一下 // 现在RecyclerView的条目是10个,但是第十个的下标为9。RecyclerView的条目顺序是这样的,最底层的下标为0,最顶层的下标为9 所以我们如果我们要找最后一个不重叠的也就是说从上面往下数 //的第三个, 这个第三个从下往上数的下标是7 但是呢我们现在的小标为6 为什么呢 因为下标为9的不需要操作啊 所以我们就把6完全重叠 7和8进行缩放,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个图层 层叠效果 /** * 这里是从最下面往上数的但是呢 我们有需要只让两个进行缩放 itemcount是8 比如当前是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:1为UP 2为down 4为left 8为right 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 未经允许严禁转载,请尊重作者劳动成果。我的博客】
- Android图片上下左右滑动特效--Recycker实现
- Scroll实现上下左右滑动
- Android滑动菜单特效实现
- Android滑动菜单特效实现
- Android滑动菜单特效实现
- Android滑动菜单特效实现
- android上下左右滑动
- 使用viewpager嵌套实现上下左右滑动切换图片
- android 图片 上下左右滑动,能放大放小
- Android中实现上下左右都可滑动的ScrollView
- Android中实现上下左右都可滑动的ScrollView
- Android中实现上下左右都可滑动的ScrollView
- Android中实现上下左右都可滑动的ScrollView
- Android中实现上下左右都可滑动的ScrollView
- android屏幕监控上下左右滑动
- android屏幕监控上下左右滑动
- android CustomScrollView上下左右同时滑动
- android view 上下左右滑动 事件
- C#中的委托与Java中的接口回调
- 快到连妈妈都不认识你的文件搜索工具 搜索everything
- wikioi1553 互斥的数
- W3c泥垢!如此耿直。。。你是来讲冷笑话的吗?
- 基于maven实现zxing二维码
- Android图片上下左右滑动特效--Recycker实现
- jquery表格的维护和删除
- 关于BQ40Z50-R1使用过程中的点点滴滴
- HDU 1016 素数环
- freecodecamp 算法部分刷题笔记
- Leetcode 107. Binary Tree Level Order Traversal II
- struts2 demo
- windows8的BCD文件损坏无法进入的解决方法
- Spring中的一些术语