RecyclerView实现探探卡片滑动功能及优化

简介: title: RecyclerView实现探探卡片滑动功能date: 2018-10-07 10:35:56tags: RecyclerView代码实现博客地址:https://blog.csdn.net/qq_39085422/article/details/78612132我只掌握了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加载网络图片时,会闪烁,使用本地图片时不会

img_4c460be176229f9954b2a993463bbf08.jpe
图片闪烁.jpg

原因: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>
目录
相关文章
|
27天前
|
8月前
|
存储 缓存 Android开发
构建高效的Android应用:采用RecyclerView优化列表显示
【4月更文挑战第2天】 在移动开发领域,列表显示是最常见的用户界面组件之一。对于Android平台而言,RecyclerView因其高效、灵活的特点而备受开发者青睐。本文将深入探讨如何利用RecyclerView在Android应用中实现流畅的列表滚动,以及通过各种优化策略来提升性能和用户体验。我们将从基本概念出发,逐步展开如何自定义适配器、视图持有者,以及利用布局管理器来实现复杂的列表布局。此外,还将讨论如何通过异步加载、缓存机制和动态数据更新来进一步优化性能。
115 1
|
前端开发 Android开发
仿微信通讯录滑动定位ListView功能(一)
仿微信通讯录滑动定位ListView功能(一)
149 0
仿微信通讯录滑动定位ListView功能(一)
|
安全 Android开发
仿微信通讯录滑动定位ListView功能(二)
仿微信通讯录滑动定位ListView功能(二)
139 0
仿微信通讯录滑动定位ListView功能(二)
NewPagedFlowView电影票卡片式无限自动轮播图方法改进
新增网络图片数据源和本地图片数据源属性 直接传入url链接数组或uiimage对象数组
254 0
NewPagedFlowView电影票卡片式无限自动轮播图方法改进
实现RecycleView横向、竖向无限循坏(基于自定义RecyclerView.LayoutManager)
实现RecycleView横向、竖向无限循坏(基于自定义RecyclerView.LayoutManager)
389 0
|
XML 存储 数据格式
如何使用RecyclerView优雅地实现复杂列表效
/ 今日科技快讯 / 发现一件很有意思的事情,今天这篇文章中介绍的RecyclerView,以及昨天文章中介绍的Lifecycles,它们共同的作者都是前天文章中介绍的Yigit Boyar大神。确实不是我有意为之,我都是按照投稿的顺序来安排推送的。而Yigit Boyar大神明天将会做客上海GDG,与大家进行一场问答式的技术活动。这种跟Google大神零距离接触的机会可不多,希望大家到时都能准时观看,我们明天见。/ 作者简介 /本篇文章来自秦川小将的投稿,给大家分享了如何使用RecyclerView实现复杂的列表,相信会对大家有所帮助!同时也感谢作者贡献的精彩文章! 秦川小将的博客地址:
如何使用RecyclerView优雅地实现复杂列表效
|
缓存 Android开发
RecyclerView高级进阶之优雅地解决瀑布流的两个神坑
RecyclerView高级进阶之优雅地解决瀑布流的两个神坑
RecyclerView高级进阶之优雅地解决瀑布流的两个神坑
|
Android开发
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(二)
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(二)
444 0
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(二)
|
编解码 Android开发
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(一)
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(一)
546 0
【Flutter】Android、Flutter 折叠屏适配 ( 展开大屏 | 折叠主屏 | 折叠副屏 | 静态展示 | 动态热切换适配 | 拉伸布局 | X 轴自适应适配 | 布局重构 )(一)