Android ClickableSpan tidak memanggil onClick


150

Saya membuat ClickableSpan, dan itu ditampilkan dengan benar dengan teks yang tepat digarisbawahi. Namun, klik tidak mendaftar. Apakah Anda tahu apa yang saya lakukan salah ???

Terima kasih, Victor

Berikut ini cuplikan kode:

view.setText("This is a test");
ClickableSpan span = new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        log("Clicked");
    }
};
view.getText().setSpan(span, 0, view.getText().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

Jawaban:


430

Sudahkah Anda mencoba mengatur MovementMethod pada TextView yang berisi rentang? Anda perlu melakukan itu untuk membuat klik itu berfungsi ...

tv.setMovementMethod(LinkMovementMethod.getInstance());

Jangan bekerja dengan baik jika tvtipe EditText, benar Anda dapat mengklik rentang tetapi tidak mengedit ini seperti biasa.
FIG-GHD742

Terima kasih banyak! Ini juga bekerja untuk saya! dapatkah Anda menjelaskan kepada saya karenanya tentang pengaturan ini?
alfo888_ibg

63
TENTU SAJA Saya perlu mengatur apa yang disebut oleh dokumentasi sebagai "penangan kunci panah" untuk membuat penangan klik berfungsi. Sangat jelas! (╯ ° □ °) ╯︵ ┻━┻
adamdport

Ini bekerja, tetapi saya tidak akan pernah tahu mengapa itu bukan perilaku default.
EpicPandaForce

Dan Google lupa menyebutkan bahwa memanggil setMovementMethod membuat "ellipsize" tidak berfungsi ... Jadi, tampaknya pendekatan yang benar adalah dengan mengimplementasikan TouchListener secara manual dan mengambilnya dari sana ...
slott

4

Setelah beberapa percobaan dan kesalahan, urutan pengaturan yang tv.setMovementMethod(LinkMovementMethod.getInstance());penting.

Ini kode lengkap saya

String stringTerms = getString(R.string.sign_up_terms);
Spannable spannable = new SpannableString(stringTerms);
int indexTermsStart = stringTerms.indexOf("Terms");
int indexTermsEnd = indexTermsStart + 18;
spannable.setSpan(new UnderlineSpan(), indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(getColor(R.color.theme)), indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Log.d(TAG, "TODO onClick.. Terms and Condition");
    }
}, indexTermsStart, indexTermsEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

int indexPolicyStart = stringTerms.indexOf("Privacy");
int indexPolicyEnd = indexPolicyStart + 14;
spannable.setSpan(new UnderlineSpan(), indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(getColor(R.color.theme)), indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Log.d(TAG, "TODO onClick.. Privacy Policy");
    }
}, indexPolicyStart, indexPolicyEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

TextView textViewTerms = (TextView) findViewById(R.id.sign_up_terms_text);
textViewTerms.setText(spannable);
textViewTerms.setClickable(true);
textViewTerms.setMovementMethod(LinkMovementMethod.getInstance());

4

Fungsi pemanfaatan Kotlin:

fun setClickable(textView: TextView, subString: String, handler: () -> Unit, drawUnderline: Boolean = false) {
    val text = textView.text
    val start = text.indexOf(subString)
    val end = start + subString.length

    val span = SpannableString(text)
    span.setSpan(ClickHandler(handler, drawUnderline), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

    textView.linksClickable = true
    textView.isClickable = true
    textView.movementMethod = LinkMovementMethod.getInstance()

    textView.text = span
}

class ClickHandler(
        private val handler: () -> Unit,
        private val drawUnderline: Boolean
) : ClickableSpan() {
    override fun onClick(widget: View?) {
        handler()
    }

    override fun updateDrawState(ds: TextPaint?) {
        if (drawUnderline) {
            super.updateDrawState(ds)
        } else {
            ds?.isUnderlineText = false
        }
    }
}

Pemakaian:

Utils.setClickable(textView, subString, {handleClick()})

1

Pendekatan Langsung di Kotlin

  val  textHeadingSpannable = SpannableString(resources.getString(R.string.travel_agent))


           val clickSpan = object : ClickableSpan(){
               override fun onClick(widget: View) {

                // Handel your click
               }
           }
            textHeadingSpannable.setSpan(clickSpan,104,136,Spannable.SPAN_INCLUSIVE_EXCLUSIVE)

            tv_contact_us_inquire_travel_agent.movementMethod = LinkMovementMethod.getInstance()
            tv_contact_us_inquire_travel_agent.text = textHeadingSpannable
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.