RecyclerView實(shí)現(xiàn)探探卡片滑動(dòng)功能及優(yōu)化


title: RecyclerView實(shí)現(xiàn)探探卡片滑動(dòng)功能
date: 2018-10-07 10:35:56
tags: RecyclerView


代碼實(shí)現(xiàn)

博客地址:https://blog.csdn.net/qq_39085422/article/details/78612132
我只掌握了RecyclerView基礎(chǔ)用法,所以參考別人博客的代碼實(shí)現(xiàn)。
我使用CardView代替RoundImageView實(shí)現(xiàn)圓角效果。

遇到的問題

1.CardView陰影顯示不完全


原因:將CardView作為最外層布局,可能是兩個(gè)CardView重疊時(shí),邊界會(huì)融合到一起。
解決方法:在外層再套一層布局,比如LinearLayout之類的。
解決后效果圖:
Card_View.jpg

在文末會(huì)貼出我的布局代碼。

2.左右滑,滑出時(shí)卡頓(未解決)

原因:adapter.notifyDataSetChanged();
卡片滑出后需要?jiǎng)h除對(duì)應(yīng)的數(shù)據(jù),對(duì)數(shù)據(jù)源進(jìn)行remove()操作,之后通知adapter,這個(gè)時(shí)候會(huì)發(fā)生卡頓

3.向上下滑動(dòng)時(shí),動(dòng)畫銜接的不好

原因:臨界值計(jì)算公式不合理,只計(jì)算了在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變量,計(jì)算位移兩點(diǎn)間的直線距離。

4.用Gilde加載網(wǎng)絡(luò)圖片時(shí),會(huì)閃爍,使用本地圖片時(shí)不會(huì)

圖片閃爍.jpg

原因:Gilde進(jìn)行加載網(wǎng)絡(luò)圖片時(shí),會(huì)保留緩存,使用時(shí)加載完整圖片,所以分辨率不同,會(huì)閃爍。
解決:
思路是類似于做一層緩存,先把圖片加載好放在一個(gè)List里面,使用時(shí)直接從數(shù)組里取出來,這樣子就模擬了本地圖片加載。
具體實(shí)現(xiàn)如下:
在adaputer中聲明兩個(gè)數(shù)組

//圖片的URL
private List<String> imgUrlList = new ArrayList<>();
//緩存數(shù)組
private List<GlideDrawable> glideDrawableList = new ArrayList<>();

//glideDrawableList的訪問方法,imgUrlList通過構(gòu)造函數(shù)傳入,不需要get,set
    public List<GlideDrawable> getGlideDrawableList() {
        return glideDrawableList;
    }

    public void setGlideDrawableList(List<GlideDrawable> glideDrawableList) {
        this.glideDrawableList = glideDrawableList;
    }

之后創(chuàng)建一個(gè)updateGlideDrawableList()方法,用于請(qǐng)求網(wǎng)絡(luò)圖片,CardConfig.DEFAULT_SHOW_ITEM是顯示的卡片數(shù)量,CardConfig.DEFAULT_CACHE_ITEM是而外的緩存數(shù)量,為了防止用戶滑動(dòng)太快,網(wǎng)絡(luò)請(qǐng)求速度跟不上。

public void updateGlideDrawableList(){
    //每次最多循環(huán)的次數(shù)i<卡片顯示數(shù)量+額外緩存數(shù)量
    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請(qǐng)求網(wǎng)絡(luò)圖片
        Glide.with(mContext)
                    .load(url)
                    //Gilde將圖片剪裁成336,326
                    .into(new SimpleTarget<GlideDrawable>(336, 326) {
                        @Override
                        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                            //將圖片資源放入緩存數(shù)組
                            glideDrawableList.add(resource);
                            //通知adapter數(shù)據(jù)已經(jīng)更新,刷新顯示。
                            AdapterCardSwipeLive.this.notifyDataSetChanged();
                        }
                    });
    }
}

之后只要在imgUrlList傳入之后,onBindViewHolder()之前使用該方法就好了,這里我選擇在構(gòu)造函數(shù)里調(diào)用:

public Adapter(Context context, List imgUrlList){
        this.imgUrlList = imgUrlList;
        this.mContext = context;
        //我選擇今早的調(diào)用此方法,減少用戶的等待時(shí)間
        updateGlideDrawableList();
    }

到這里,核心代碼就已經(jīng)寫完了,接下來只需要將之前使ItemTouchHelperCallback中操作imgUrlList的地方進(jìn)行一些修改,替換成glideDrawableList就可以了:

//替換前
T remove = adaputer.getList().remove(layoutPosition);
adapter.notifyDataSetChanged();

//替換后
T remove = ((List<T>) adapterCardSwipeLive.getmCardShowInfoBeanList()).remove(layoutPosition);
//調(diào)用這個(gè)方法以補(bǔ)充被remove掉的GlideDrawable
updateGlideDrawableList();
adapter.notifyDataSetChanged();

這樣子就完成了,使用時(shí),傳進(jìn)adaputer來的只有imgUrlList,然后adapter向外只提供一個(gè)glideDrawableList,外面也只能對(duì)glideDrawableList進(jìn)行增刪改查。同時(shí)每刪除glideDrawableList中的一個(gè)元素,再通過updateGlideDrawableList()添加回來,就能實(shí)現(xiàn)盡可能少的緩存。這里只是提供一個(gè)思路,代碼不一定能毫無錯(cuò)誤的運(yùn)行出來,需要自己進(jìn)行適配。

拓展

如果你搜索卡片層疊效果,你會(huì)發(fā)現(xiàn)更多更詳細(xì)的內(nèi)容

總結(jié):

折騰了好久也無法像探探那樣流暢,只能朝四個(gè)方向滑出,而不能360°滑出,
流暢度效果也有不少差距。
應(yīng)該是實(shí)現(xiàn)思路的不同,我是基于recyclerView實(shí)現(xiàn)的,比較簡(jiǎn)單,另一種基于ListView實(shí)現(xiàn)的比較復(fù)雜,但效果很好??梢娮约核竭€有待提高。

相關(guān)代碼:

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/互聯(lián)網(wǎng)"
                    android:textColor="#cbcbcb" />

            </RelativeLayout>
        </LinearLayout>
    </android.support.v7.widget.CardView>

</RelativeLayout>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,828評(píng)論 25 709
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,919評(píng)論 2 59
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,136評(píng)論 22 665
  • 內(nèi)容 抽屜菜單 ListView WebView SwitchButton 按鈕 點(diǎn)贊按鈕 進(jìn)度條 TabLayo...
    小狼W閱讀 1,666評(píng)論 0 10
  • 【2017.9.18】閱讀習(xí)慣 day 6 【打卡】娟~ 【書名】《戀愛戒律》 【作者】鄭潔心 【分類】?jī)尚躁P(guān)系 ...
    好聽的暖陽閱讀 171評(píng)論 0 0

友情鏈接更多精彩內(nèi)容