開發(fā)問題記錄隨筆之關(guān)于輕擊RecyclerView中Item原設(shè)置點(diǎn)擊水波紋效果無效的反思與修改

如何設(shè)置item點(diǎn)擊水波紋效果:

  1. 在drawable文件夾下創(chuàng)建 linearlayout_water_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners android:radius="5dip"/>
    <solid android:color="#ffffff"/>

</shape>
  1. 在drawable-v24文件夾下創(chuàng)建 linearlayout_water_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners android:radius="5dip"/>
    <solid android:color="#ffffff"/>

</shape>

  1. 使用的顏色代碼添加到res-values-colors下
<color name="text_Grey">#c1c1c2</color>

  <color name="colorWhite">#ffffff</color>
  1. 將布局引用到RecyclerView子項(xiàng)布局里
android:background="@drawable/linearlayout_water_selecto"
    android:clickable="true"
    android:focusable="true"

此時(shí)設(shè)置完水波紋的點(diǎn)擊效果


但是不要急鹏氧,我們再來看看RecyclerView中如何設(shè)置item可點(diǎn)擊渤涌,這里筆者采用的是addOnItemTouchListener方法,由api提供:

RecyclerView.addOnItemTouchListener(OnItemTouchListener listener)

接下來看看完整代碼

public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private GestureDetectorCompat mGestureDetector;
    private RecyclerView recyclerView;

    public OnRecyclerItemClickListener(RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
        mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener());
    }

    //處理事件攔截
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }

    //處理點(diǎn)擊事件
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
    }

    //處理事件沖突把还,不用管
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    }

    //OnGestureListener主要回調(diào)各種單擊事件实蓬,而OnDoubleTapListener回調(diào)各種雙擊事件
    //sdk 還提供了一個(gè)外部類SimpleOnGestureListener,這個(gè)類實(shí)現(xiàn)了上面兩個(gè)接口的所有方法吊履。
    // 但全都是空實(shí)現(xiàn)瞳秽,函數(shù)體里什么也沒寫,其中就是把上面兩個(gè)接口合并一下率翅,給出默認(rèn)的空實(shí)現(xiàn)练俐。
    // 這樣繼承SimpleOnGestureListener的時(shí)候就不用實(shí)現(xiàn)每一個(gè)方法了。
    private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
        //單擊
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                int position = recyclerView.getChildLayoutPosition(child);
                onItemClick(vh,position);
            }
            return true;
        }

        //雙擊
        public boolean onDoubleTap(MotionEvent e){
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                int position = recyclerView.getChildLayoutPosition(child);
                onItemDoubleClick(vh,position);
            }
            return true;
        }

        //長按
        public void onLongPress(MotionEvent e){
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                int position = recyclerView.getChildLayoutPosition(child);
                onItemLongClick(vh, position);
            }
        }
    }

    public abstract void onItemClick(RecyclerView.ViewHolder vh,int position);
    public abstract void onItemDoubleClick(RecyclerView.ViewHolder vh, int position);
    public abstract void onItemLongClick(RecyclerView.ViewHolder vh, int position);
}

這段代碼很長冕臭,我們分析一下大概流程:

  1. 首先是自定義一個(gè)抽象類偶OnRecyclerItemClickListener實(shí)現(xiàn)接口RecyclerView.onItemTouchListener腺晾,并實(shí)例化手勢檢測對象和RecyclerView對象。

  1. 接著是一個(gè)構(gòu)造器辜贵,下面的三個(gè)方法一個(gè)處理事件攔截悯蝉,一個(gè)處理事件點(diǎn)擊,一個(gè)處理事件沖突托慨,都寫了注釋鼻由,相信了解事件分發(fā)的同學(xué)一定不陌生。

  1. 往下走是一個(gè)私有內(nèi)部類ItemTouchHelperGestureListener繼承了GestureDetector.SimpleOnGestureListener厚棵,注釋上也寫明了這個(gè)類可以實(shí)現(xiàn)OnGestureListener和OnDoubleTapListener兩個(gè)接口的全部方法蕉世,那我們就來看看這兩個(gè)接口分別實(shí)現(xiàn)了什么方法吧

OnGestureListener的回調(diào)接口如下:

    //用戶按下屏幕就會(huì)觸發(fā)
    public boolean onDown(MotionEvent e);

    //如果是按下的時(shí)間超過瞬間,而且在按下的時(shí)候沒有松開或者是拖動(dòng)的婆硬,那么onShowPress就會(huì)執(zhí)行
    public void onShowPress(MotionEvent e);

    //一次單獨(dú)的輕擊抬起操作,也就是輕擊一下屏幕狠轻,就是普通點(diǎn)擊事件
    public boolean onSingleTapUp(MotionEvent e);

    //在屏幕上拖動(dòng)事件
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

    //長按觸摸屏,超過一定時(shí)長彬犯,就會(huì)觸發(fā)這個(gè)事件
    public void onLongPress(MotionEvent e);

    //滑屏向楼,用戶按下觸摸屏查吊、快速移動(dòng)后松開
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);

OnDoubleTapListener的回調(diào)接口如下:

    //單擊事件。用來判定該次點(diǎn)擊是SingleTap而不是DoubleTap湖蜕,
    //如果連續(xù)點(diǎn)擊兩次就是DoubleTap手勢逻卖,如果只點(diǎn)擊一次,
    //系統(tǒng)等待一段時(shí)間后沒有收到第二次點(diǎn)擊則判定該次點(diǎn)擊為SingleTap而不是DoubleTap昭抒,
    //然后觸發(fā)SingleTapConfirmed事件
    public boolean onSingleTapConfirmed(MotionEvent e);

    //雙擊事件
    public boolean onDoubleTap(MotionEvent e);

    //雙擊間隔中發(fā)生的動(dòng)作箭阶。指觸發(fā)onDoubleTap以后,在雙擊之間發(fā)生的其它動(dòng)作
    public boolean onDoubleTapEvent(MotionEvent e);

  1. 關(guān)于分析我們一會(huì)再說戈鲁,接上步驟仇参,最后在你想要設(shè)置點(diǎn)擊的頁面添加如下代碼
//我自己實(shí)例化的對象,讀者按需修改
private RecyclerView recyclerViewForNews;
        //添加點(diǎn)擊事件
        recyclerViewForNews.addOnItemTouchListener(new OnRecyclerItemClickListener(recyclerViewForNews){
            @Override
            public void onItemClick(RecyclerView.ViewHolder vh,int position) {
                //item點(diǎn)擊事件
                String url = mUrlList.get(position);
                // 跳轉(zhuǎn)傳值
                Intent intent = new Intent(getActivity(), NewsActivity.class);
                intent.putExtra("url", url);
                startActivity(intent);

            }

            public void onItemDoubleClick(RecyclerView.ViewHolder vh, int position){
                //item雙擊事件
                String url = mUrlList.get(position);
                // 跳轉(zhuǎn)傳值
                Intent intent = new Intent(getActivity(), NewsActivity.class);
                intent.putExtra("url", url);
                startActivity(intent);
            }

            public void onItemLongClick(RecyclerView.ViewHolder vh, int position){
                //item長按事件
                String url = mUrlList.get(position);
                // 跳轉(zhuǎn)傳值
                Intent intent = new Intent(getActivity(), NewsActivity.class);
                intent.putExtra("url", url);
                startActivity(intent);
            }
        });

簡單說明一下婆殿,RecyclerView的對象是我自己設(shè)置的诈乒,僅服務(wù)于自己的項(xiàng)目,包括三個(gè)方法里的所有邏輯都是為了我自己項(xiàng)目中所需要的跳轉(zhuǎn)婆芦,讀者按需修改即可怕磨。

  1. 分析:為什么這篇文章的標(biāo)題叫做“反思與修改”呢?一般在別的文章中僅僅讓你重寫幾個(gè)方法消约,設(shè)置一下xml文件肠鲫,就完事了。但是細(xì)心的你一定會(huì)發(fā)現(xiàn)public boolean onSingleTapUp(MotionEvent e)和public boolean onSingleTapConfirmed(MotionEvent e)方法非常相似或粮,只差了一個(gè)Confirmed导饲,但是應(yīng)用在項(xiàng)目中效果是完全不同的。

public boolean onSingleTapUp(MotionEvent e)應(yīng)用在我們的項(xiàng)目中的話氯材,假設(shè)你點(diǎn)擊item時(shí)非常輕渣锦,幾乎不怎么用力觸摸屏幕,你會(huì)發(fā)現(xiàn)有時(shí)我們上述設(shè)置的水波紋效果是無法顯示出來的氢哮,這明顯與我們的需求不符袋毙。況且經(jīng)過筆者本身的試驗(yàn),點(diǎn)擊一些有水波紋效果的app無論是輕是重都會(huì)顯示出水波紋效果冗尤。
public boolean onSingleTapConfirmed(MotionEvent e)應(yīng)用于我們的項(xiàng)目中的話听盖,由于需要一段時(shí)間確認(rèn)你觸摸了屏幕幾次,所以無論你點(diǎn)擊屏幕是輕是重都會(huì)顯示出我們的水波紋效果裂七,于是我們在上述代碼中選擇重寫這個(gè)方法皆看。

接下來重寫的兩個(gè)方法就非常符合邏輯了,假如用戶真的點(diǎn)了兩次呢碍讯?或者假如用戶長按不放呢悬蔽?于是我們選擇重寫public boolean onDoubleTap(MotionEvent e)和public void onLongPress(MotionEvent e)方法,也就完成了基本的點(diǎn)擊捉兴,雙擊蝎困,長按都可以顯示出水波紋效果的基本需求了。

歡迎指正倍啥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末禾乘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子虽缕,更是在濱河造成了極大的恐慌始藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氮趋,死亡現(xiàn)場離奇詭異伍派,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剩胁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門诉植,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昵观,你說我怎么就攤上這事晾腔。” “怎么了啊犬?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵灼擂,是天一觀的道長。 經(jīng)常有香客問我觉至,道長剔应,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任语御,我火速辦了婚禮领斥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沃暗。我一直安慰自己月洛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布孽锥。 她就那樣靜靜地躺著嚼黔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惜辑。 梳的紋絲不亂的頭發(fā)上唬涧,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音盛撑,去河邊找鬼碎节。 笑死,一個(gè)胖子當(dāng)著我的面吹牛抵卫,可吹牛的內(nèi)容都是我干的狮荔。 我是一名探鬼主播胎撇,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼殖氏!你這毒婦竟也來了晚树?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雅采,失蹤者是張志新(化名)和其女友劉穎爵憎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婚瓜,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宝鼓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了巴刻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愚铡。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冈涧,靈堂內(nèi)的尸體忽然破棺而出茂附,到底是詐尸還是另有隱情,我是刑警寧澤督弓,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布营曼,位于F島的核電站,受9級特大地震影響愚隧,放射性物質(zhì)發(fā)生泄漏蒂阱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一狂塘、第九天 我趴在偏房一處隱蔽的房頂上張望录煤。 院中可真熱鬧,春花似錦荞胡、人聲如沸妈踊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽廊营。三九已至,卻和暖如春萝勤,著一層夾襖步出監(jiān)牢的瞬間露筒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工敌卓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慎式,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像瘪吏,于是被迫代替她去往敵國和親癣防。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容