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);
Victor Grazi
sumber

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());
Marc Attinasi
sumber
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());
twelvester
sumber
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()})
sebelas
sumber
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
mughil
sumber