ImageSpan添加點(diǎn)擊事件

方法

*方法一:重寫LinkMovementMethod
*方法二:設(shè)置ImageSpan的同時(shí),同一位置設(shè)置一個(gè)ClickableSpan

FAQ

去掉圖片的點(diǎn)擊選中狀態(tài)

注釋掉如下代碼

 Selection.setSelection(buffer,
 buffer.getSpanStart(imageSpans[0]),
 buffer.getSpanEnd(imageSpans[0]));

假設(shè)連續(xù)兩張圖片,點(diǎn)擊TextView中的第二個(gè)span,但是實(shí)際響應(yīng)的是第一個(gè)span

Android ClickableSpan 光標(biāo)選擇問(wèn)題,有需要的朋友可以參考下。

最近因項(xiàng)目需求,使用到CloudEditText 來(lái)實(shí)現(xiàn)文字輸入,并且需要點(diǎn)擊改變ImageSpan背景,使用軟鍵盤刪除鍵進(jìn)行操作

先說(shuō)明一下原理,CloudEditText 是使用 SpannableString 來(lái)進(jìn)行插入帶有樣式的文字,主要分3層:

1.SpannableString 必須有字符串傳入,不然后續(xù)的插入ImageSpan 與 ClickableSpan 都會(huì)出現(xiàn)數(shù)組越界問(wèn)題,因?yàn)闆](méi)有字符串的插入,EditText本身就是空的

SpannableString spannableString=new SpannableString(getText())

2.ImageSpan 插入drawable 到 對(duì)應(yīng)字符串長(zhǎng)度的區(qū)間

spannableString.setSpan(imageSpan,start,end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

3.ClickableSpan 插入同ImageSpan 相同的區(qū)間

spannableString.setSpan(clickSpan,start,end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

想要ClickableSpan 觸發(fā)點(diǎn)擊事件,edittext.setMovementMethod(LinkMovementMethod.getInstance()) 這句話是必須要加的

說(shuō)說(shuō)這里邊會(huì)遇到的一些坑,

1.點(diǎn)擊事件位置偏移問(wèn)題

問(wèn)題主要出在LinkMovementMethod 這個(gè)類中的OnTouchEvent 方法中,源碼里邊是這樣寫的 int off =layout.getOffsetForHorizontal(line,x) ,經(jīng)查閱此方法返回值是最接近手指觸摸位置的偏移量,這里就會(huì)出現(xiàn)一個(gè)問(wèn)題,當(dāng)手指觸摸到某個(gè)字符最前邊位置時(shí),光標(biāo)會(huì)選中在字符前邊,此時(shí)去刪除的話,必然會(huì)刪掉前一個(gè)字符。

當(dāng)然在字符上觸摸,因?yàn)槲恢脜^(qū)間小,用戶不太會(huì)關(guān)注,即使選錯(cuò)了,再選一次也無(wú)所謂;但是在點(diǎn)擊span的時(shí)候,出現(xiàn)這種情況就無(wú)法原諒了,因?yàn)閟pan相當(dāng)于把字符放大化了,這個(gè)時(shí)候點(diǎn)擊span的前邊位置,竟然會(huì)選中前一個(gè)span ,簡(jiǎn)直無(wú)法直視了

在遍查Google 和 Stack Overflow之后,竟然沒(méi)有找到解決方案,此時(shí)滿腦子都是修改源碼的思想,可是layout.getOffsetForHorizontal(line,x) 方法中設(shè)計(jì)到layout 中其他部分的源碼,全部修改工作量太大了。沒(méi)辦法,先硬著頭皮去看看layout的源碼,結(jié)果讓我找到一個(gè)可以解決問(wèn)題的方法,layout.getPrimaryHorizontal(off) ,根據(jù)位置獲取x軸的位移,這就好辦了,因?yàn)槭种赣|摸的位置是一定的,對(duì)比一下,就可以解決問(wèn)題了,方案如下:

float xLeft=layout.getPrimaryHorizontal(off);
if(xLeft<x){
    off+=1;
}else{
    off-=1;
}

ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

參考

  1. ImageSpan 可點(diǎn)擊、圖片與設(shè)置不一樣大
  2. 自定義可點(diǎn)擊的ImageSpan并在TextView中內(nèi)置“View“
  3. Android ClickableSpan 光標(biāo)選擇問(wèn)題
最后編輯于
?著作權(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)容

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