Android ClickableSpan ruft onClick nicht auf


149

Ich erstelle ein ClickableSpan und es wird ordnungsgemäß angezeigt, wobei der richtige Text unterstrichen ist. Die Klicks werden jedoch nicht registriert. Weißt du was ich falsch mache ???

Danke, Victor

Hier ist das Code-Snippet:

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);

Antworten:


429

Haben Sie versucht, die Bewegungsmethode in der Textansicht festzulegen, die die Spanne enthält? Sie müssen dies tun, damit das Klicken funktioniert ...

tv.setMovementMethod(LinkMovementMethod.getInstance());

Funktioniert nicht gut, wenn tves sich um den Typ EditText handelt. Richtig, Sie können auf den Bereich klicken, diesen jedoch nicht wie gewohnt bearbeiten.
FIG-GHD742

Vielen Dank! Es ist auch Arbeit für mich! Können Sie mir deshalb diese Einstellung erläutern?
alfo888_ibg

63
Natürlich muss ich festlegen, was in der Dokumentation als "Pfeiltasten-Handler" bezeichnet wird, damit ein Klick-Handler funktioniert. So offensichtlich! (╯ ° □ °)) ad
Adamdport

Es funktioniert, aber ich werde nie wirklich wissen, warum dies nicht das Standardverhalten ist.
EpicPandaForce

Und Google hat vergessen zu erwähnen, dass das Aufrufen von setMovementMethod dazu führt, dass die "Ellipsengröße" nicht funktioniert ... Es scheint also der richtige Ansatz zu sein, einen TouchListener manuell zu implementieren und von dort zu übernehmen ...
Slott

4

Nach einigem Ausprobieren spielt die Reihenfolge der Einstellung eine tv.setMovementMethod(LinkMovementMethod.getInstance());Rolle.

Hier ist mein vollständiger Code

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

Kotlin util Funktion:

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
        }
    }
}

Verwendung:

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

1

Direkter Anflug in 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.