RecyclerView实现探探卡片滑动功能及优化
title: RecyclerView实现探探卡片滑动功能
date: 2018-10-07 10:35:56
tags: RecyclerView
代码实现
博客地址:https://blog.csdn.net/qq_39085422/article/details/78612132
我只掌握了RecyclerView基础用法,所以参考别人博客的代码实现。
我使用CardView代替RoundImageView实现圆角效果。
遇到的问题
1.CardView阴影显示不完全
原因:将CardView作为最外层布局,可能是两个CardView重叠时,边界会融合到一起。
解决方法:在外层再套一层布局,比如LinearLayout之类的。
解决后效果图:
在文末会贴出我的布局代码。
2.左右滑,滑出时卡顿(未解决)
原因:adapter.notifyDataSetChanged();
卡片滑出后需要删除对应的数据,对数据源进行remove()操作,之后通知adapter,这个时候会发生卡顿
3.向上下滑动时,动画衔接的不好
原因:临界值计算公式不合理,只计算了在X轴的偏移量
解决:CardItemTouchHelperCallback类中的onChildDraw()里,
解决前代码:
float ratio = dX / getThreshold(recyclerView, viewHolder);
解决后代码:
float distance = (float)Math.sqrt(dX*dX+dY*dY); float ratio = distance / getThreshold(recyclerView, viewHolder);
变化:增加了distance变量,计算位移两点间的直线距离。
4.用Gilde加载网络图片时,会闪烁,使用本地图片时不会
原因:Gilde进行加载网络图片时,会保留缓存,使用时加载完整图片,所以分辨率不同,会闪烁。
解决:
思路是类似于做一层缓存,先把图片加载好放在一个List里面,使用时直接从数组里取出来,这样子就模拟了本地图片加载。
具体实现如下:
在adaputer中声明两个数组
//图片的URL private List<String> imgUrlList = new ArrayList<>(); //缓存数组 private List<GlideDrawable> glideDrawableList = new ArrayList<>(); //glideDrawableList的访问方法,imgUrlList通过构造函数传入,不需要get,set public List<GlideDrawable> getGlideDrawableList() { return glideDrawableList; } public void setGlideDrawableList(List<GlideDrawable> glideDrawableList) { this.glideDrawableList = glideDrawableList; }
之后创建一个updateGlideDrawableList()方法,用于请求网络图片,CardConfig.DEFAULT_SHOW_ITEM是显示的卡片数量,CardConfig.DEFAULT_CACHE_ITEM是而外的缓存数量,为了防止用户滑动太快,网络请求速度跟不上。
public void updateGlideDrawableList(){ //每次最多循环的次数i<卡片显示数量+额外缓存数量 for (int i = mCardShowInfoBeanList.size(); i < CardConfig.DEFAULT_SHOW_ITEM+CardConfig.DEFAULT_CACHE_ITEM; i++){ //防止list为空 if(imgUrlList.size() <= 0){ return; } //依次去除所有的url String url = imgUrlList.remove(0); //使用Gilde请求网络图片 Glide.with(mContext) .load(url) //Gilde将图片剪裁成336,326 .into(new SimpleTarget<GlideDrawable>(336, 326) { @Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { //将图片资源放入缓存数组 glideDrawableList.add(resource); //通知adapter数据已经更新,刷新显示。 AdapterCardSwipeLive.this.notifyDataSetChanged(); } }); } }
之后只要在imgUrlList传入之后,onBindViewHolder()之前使用该方法就好了,这里我选择在构造函数里调用:
public Adapter(Context context, List imgUrlList){ this.imgUrlList = imgUrlList; this.mContext = context; //我选择今早的调用此方法,减少用户的等待时间 updateGlideDrawableList(); }
到这里,核心代码就已经写完了,接下来只需要将之前使ItemTouchHelperCallback中操作imgUrlList的地方进行一些修改,替换成glideDrawableList就可以了:
//替换前 T remove = adaputer.getList().remove(layoutPosition); adapter.notifyDataSetChanged(); //替换后 T remove = ((List<T>) adapterCardSwipeLive.getmCardShowInfoBeanList()).remove(layoutPosition); //调用这个方法以补充被remove掉的GlideDrawable updateGlideDrawableList(); adapter.notifyDataSetChanged();
这样子就完成了,使用时,传进adaputer来的只有imgUrlList,然后adapter向外只提供一个glideDrawableList,外面也只能对glideDrawableList进行增删改查。同时每删除glideDrawableList中的一个元素,再通过updateGlideDrawableList()添加回来,就能实现尽可能少的缓存。这里只是提供一个思路,代码不一定能毫无错误的运行出来,需要自己进行适配。
拓展
如果你搜索卡片层叠效果,你会发现更多更详细的内容
总结:
折腾了好久也无法像探探那样流畅,只能朝四个方向滑出,而不能360°滑出,
流畅度效果也有不少差距。
应该是实现思路的不同,我是基于recyclerView实现的,比较简单,另一种基于ListView实现的比较复杂,但效果很好。可见自己水平还有待提高。
相关代码:
item_card_slide.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="336dp" android:layout_height="426dp"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" app:cardCornerRadius="7.5dp" app:cardElevation="1dp" app:cardUseCompatPadding="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <ImageView android:id="@+id/iv_avatar" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:background="@color/pink"/> <ImageView android:id="@+id/iv_dislike" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="15dp" android:layout_marginTop="15dp" android:alpha="0" android:background="@color/blue"/> <ImageView android:id="@+id/iv_like" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="15dp" android:layout_marginTop="15dp" android:alpha="0" android:background="@color/grey"/> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="100dp" android:paddingLeft="14dp" android:paddingTop="15dp"> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="小姐姐" android:textColor="@android:color/black" android:textSize="16sp" /> <TextView android:id="@+id/tv_age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_name" android:layout_marginTop="5dp" android:background="@color/pink" android:gravity="center" android:text=" 23" android:textColor="#FFFFFF" android:textSize="14sp" /> <TextView android:id="@+id/tv_constellation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_name" android:layout_marginLeft="4dp" android:layout_marginTop="5dp" android:layout_toRightOf="@id/tv_age" android:background="@color/olivedrab" android:gravity="center" android:text="狮子座" android:textColor="#FFFFFF" android:textSize="14sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_age" android:layout_marginTop="5dp" android:gravity="center" android:text="IT/互联网" android:textColor="#cbcbcb" /> </RelativeLayout> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout>
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Effective Objective-C 2.0 Tips 总结 Chapter 5,6,7
Effective Objective-C 2.0 Tips 总结 Chapter 5,6,7 Chapter 5 内存管理 Tips 29 理解引用计数 引用计数是 Objective-C 内存管理的基础,包括 ARC 也是建立在引用计数的基础之上,理解引用计数机制,能更好的帮你使用 ARC 引用计数的基本原理是每个对象都有一个当前有多少对象希望他存活的计数器,当这个计数器归零那么这个对象就会被释放 查看引用计数的方法叫做 retainCount 但是实际并不建议使用这个方法调试代码 如果对象 A 需要对象 B 存活,那么 A 需要调用 B 的 retain 方法,如果对象 A 不再需要对象 B 存活了,那么需要调用对象 B 的 release 方法或者 autorelease 方法 调用 release 并不会使对象被释放,对象释放被释放取决于引用计数是否为 0 所有的对象最终都间接或直接的被一个根对象所引用,macOS 应用是 NSApplication 对象,iOS 则是 UIApplication 对象,这两个对象都是应用启动时创建的单例 对象的 alloc 方法返回的对象由...
- 下一篇
Android 多线程之线程池
Android 多线程系列 Android 多线程之几个基本问题 Android 多线程之阻塞队列 Android多线程之常见的线程形态 Android线程池的真正实现是ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } corePoolSize:表示核心线程数。默认情况下核心线程会在线程池中一直存活,即使处于闲置状态。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那核心线程也会有超时策略,时间间隔由...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Mario游戏-低调大师作品
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G