溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

解決ListView里TextView設(shè)置LinkMovementMethod后導(dǎo)致其ItemClick失效的問題

發(fā)布時間:2020-08-07 23:18:20 來源:網(wǎng)絡(luò) 閱讀:11751 作者:kinbos 欄目:開發(fā)技術(shù)

最近在做項目研發(fā)過程中有這樣一個需求:ListView的Item里的子控件TextView要設(shè)置超鏈接、指定文字高亮顯示,然后點擊超鏈接后跳轉(zhuǎn)到指定URL的網(wǎng)頁。實現(xiàn)超鏈接的跳轉(zhuǎn)這很容易,只要通過對TextView設(shè)置SpannableString對象即可,即如下代碼:

TextView tv = (TextView)findViewById(R.id.tv);
SpannableString sp = new SpannableString("此處為tv里顯示的內(nèi)容");
sp.setSpan( new  URLSpan( "http://www.baidu.com" ), 3 ,  8 , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(sp);
tv.setMovementMethod(LinkMovementMethod.getInstance());

通過這樣的設(shè)置后已經(jīng)能夠?qū)崿F(xiàn)對超鏈接點擊跳轉(zhuǎn)到指定URL的網(wǎng)頁了,可麻煩又來了,你會發(fā)現(xiàn)點擊ListView里的Item時沒有任何反應(yīng),這是什么原因呢?還記得上面在設(shè)置超鏈接的時候有這樣一條語句:tv.setMovementMethod(LinkMovementMethod.getInstance());我們現(xiàn)在把這條語句注釋掉看看……run App,結(jié)果點擊Item的時候能夠響應(yīng)了,可惜超鏈接又失效了,任你點擊也沒有響應(yīng)了,哎,真可謂是“魚和熊掌不可兼得”?,F(xiàn)在已經(jīng)斷定Item失效的原因何在了,那為什么這條語句就會導(dǎo)致Item點擊失效呢?源碼往往是揭開程序中各種奇芭問題的尖銳利器,讓我們跟蹤下源碼吧……打開TextView的源碼文件,截取的關(guān)鍵代碼片段如下:

解決ListView里TextView設(shè)置LinkMovementMethod后導(dǎo)致其ItemClick失效的問題

該代碼片段是TextView源碼的第1421行(Android4.2.2版本),我們發(fā)現(xiàn)不能通過重寫此方法來解決我們所面臨的問題,再繼續(xù)跟蹤LinkMovementMethod這個類吧,關(guān)鍵源碼如下:

  @Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
                            MotionEvent event) {
    int action = event.getAction();
    if (action == MotionEvent.ACTION_UP ||
        action == MotionEvent.ACTION_DOWN) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        x -= widget.getTotalPaddingLeft();
        y -= widget.getTotalPaddingTop();
        x += widget.getScrollX();
        y += widget.getScrollY();
        Layout layout = widget.getLayout();
        int line = layout.getLineForVertical(y);
        int off = layout.getOffsetForHorizontal(line, x);
        //獲取textview里的超鏈接對象,并用ClickableSpan數(shù)組盛裝
        ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
        if (link.length != 0) { //此處是對超鏈接點擊事件進(jìn)行處理……
            if (action == MotionEvent.ACTION_UP) {
                link[0].onClick(widget);
            } else if (action == MotionEvent.ACTION_DOWN) {
                Selection.setSelection(buffer,
                                       buffer.getSpanStart(link[0]),
                                       buffer.getSpanEnd(link[0]));
            }
            return true; //處理結(jié)束后返回true,這里一定要注意:當(dāng)返回值為true時則表示點擊事件已經(jīng)被,就再也不會繼續(xù)傳遞了
        } else {
            Selection.removeSelection(buffer);
        }
    }
    return super.onTouchEvent(widget, buffer, event);
}

上述源碼為LinkMovementMethod類的第188行。發(fā)現(xiàn)了Item點擊失效的原因是因為onTouch方法總是返回true而并沒有根據(jù)不同的情況來作處理,此時大家可能會想直接對這個方法重寫就能解決問題了。我和大家想的也一樣,對該方法重寫,并根據(jù)情況返回true或false,遺憾的是還是沒有效果,并且在重寫的方法里看不到輸出的日志信息,暫時不明其中原因,請高手賜教!眼看就要看到光明了,可還是被打擊了……不要灰心,面包總是會有的,如果你不放棄的話,哈哈。換個keywords google一下,終于找到國外的一個網(wǎng)站,上面的文章標(biāo)題是:

解決ListView里TextView設(shè)置LinkMovementMethod后導(dǎo)致其ItemClick失效的問題

此時此刻的心情真是如獲至寶呀……接著看下去……發(fā)現(xiàn)有高人是這樣解決的:

解決ListView里TextView設(shè)置LinkMovementMethod后導(dǎo)致其ItemClick失效的問題

發(fā)現(xiàn)這位高人本質(zhì)思路是我們開始分析的本質(zhì)思路一樣,只不過他把要處理的代碼放在了TextView的onTouch方法里,然后根據(jù)不同的情況返回true或false.在getView()方法里對相應(yīng)的TextView進(jìn)行設(shè)置吧,Run app……見證奇跡的時刻到了……哈哈,結(jié)果真的能行了,耶哦!

原文鏈接:http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable

經(jīng)過此劫,我發(fā)現(xiàn)了為什么國外的技術(shù)總是比國內(nèi)要先進(jìn)得多了,我在此并不是貶低同僚,不支持國產(chǎn),而是在國內(nèi)的技術(shù)普遍都是你抄我,我抄你的,有的甚至連原文鏈接都不放……大家可以看看國外這個技術(shù)網(wǎng)站人家是怎么解決問題的,真是按部就班,循序漸進(jìn)的,不僅讓你知其然還知其所以然。

歡迎加入QQ討論群:285077071

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI