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

作者: 月塘路 | 来源:发表于2018-10-07 17:40 被阅读10次

    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阴影显示不完全

    Card_View_border.jpg
    原因:将CardView作为最外层布局,可能是两个CardView重叠时,边界会融合到一起。
    解决方法:在外层再套一层布局,比如LinearLayout之类的。
    解决后效果图:
    Card_View.jpg
    在文末会贴出我的布局代码。

    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加载网络图片时,会闪烁,使用本地图片时不会

    图片闪烁.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>
    

    相关文章

      网友评论

      本文标题:RecyclerView实现探探卡片滑动功能及优化

      本文链接:https://www.haomeiwen.com/subject/ueolaftx.html