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

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());
Marc Attinasi
quelle
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());
zwölfter
quelle
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()})
elf
quelle
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
mughil
quelle