2013-11-03 6 views
14

Ich arbeite an ClickableSpan in einem TextView, und ich versuche, die geklickte span's Text zu bekommen. Das ist mein Code.Android ClickableSpan bekomme Text onClick()

// this is the text we'll be operating on 
SpannableString text = new SpannableString("Lorem ipsum dolor sit amet"); 

// make "dolor" (characters 12 to 17) display a toast message when touched 
ClickableSpan clickableSpan = new ClickableSpan() { 
    @Override 
    public void onClick(View view) { 
     // This will get "Lorem ipsum dolor sit amet", but I just want "dolor" 
     String text = ((TextView) view).getText().toString(); 
     Toast.makeText(context, text, Toast.LENGTH_LONG).show(); 
    } 
}; 

text.setSpan(clickableSpan, 12, 17, 0); 

Wie Sie sehen können, habe ich die clickablespan die die TextView auf Zeichen 12 bis 17, und ich möchte diese Zeichen in der onClick Ereignis bekommen.

Kann ich das überhaupt machen? Oder kann ich zumindest den Parameter 12, 17 an onClick Ereignis übergeben?

Vielen Dank!

Antwort

28

try this:

public class LoremIpsumSpan extends ClickableSpan { 
    @Override 
    public void onClick(View widget) { 
     // TODO add check if widget instanceof TextView 
     TextView tv = (TextView) widget; 
     // TODO add check if tv.getText() instanceof Spanned 
     Spanned s = (Spanned) tv.getText(); 
     int start = s.getSpanStart(this); 
     int end = s.getSpanEnd(this); 
     Log.d(TAG, "onClick [" + s.subSequence(start, end) + "]"); 
    } 
} 
+0

Danke pskink, es funktioniert! – TrungDQ

+1

sicher, es tut ... fügen Sie die Schecks erwähnt in// TODOs – pskink

+2

funktioniert auch für mehrere anklickbare Wörter :) danke! Aber warum funktioniert es? Damit OnClick die Ansicht erhält, die die Textansicht darstellt, gibt tv.getText das angeklickte Objekt "Überspannt" zurück, auch wenn andere Wörter mit der Bezeichnung "Spannbare Wörter" vorhanden sind. Wie funktioniert das? @pskink – fersarr

2

Edited: vorheriger Code falsch war, funktioniert diese

// make "dolor" (characters 12 to 17) display a toast message when touched 
    ClickableSpan clickableSpan = new ClickableSpan() { 
     @Override 
     public void onClick(View view) { 
      TextView textView = (TextView) view; 
      CharSequence charSequence = textView.getText(); 
      if (charSequence instanceof Spannable) { 
       Spannable spannableText = (Spannable)charSequence; 
       ClickableSpan[] spans = spannableText.getSpans(0, textView.length(), ClickableSpan.class); 
       for (ClickableSpan span : spans) { 
        int start = spannableText.getSpanStart(span); 
        int end = spannableText.getSpanEnd(span); 
        Toast.makeText(MainActivity.this, charSequence.subSequence(start, end), Toast.LENGTH_LONG).show(); 
       } 
      } 
     } 
    }; 
+0

Sind Sie sich sicher? Ich habe deinen Code noch nicht ausgeführt, aber es scheint nicht zu funktionieren ... dein 'sannableText' wird nicht benutzt,' spanStr' wurde nicht definiert. Und übrigens, 'textView.getText()' gibt eine 'CharSequence' zurück, nicht einen' SpannableStringBuilder' ... Könnten Sie das bitte noch einmal überprüfen? – TrungDQ

+0

Ich meine spannableText anstelle von spanStr. Ich habe von Kopf, ich mache jetzt einen echten Code und aktualisiere eine Weile. –

+0

Ich dachte auch in SpannedText anstelle von SpannableStringBuilder. Wie auch immer, du hast recht, das geht nicht. getSpans ist für Editierbar (EditText, nicht TextView) –

4

ein wenig einfacher, auch ein Modell Referenz bei Bedarf passieren könnte.

public class SpecialClickableSpan extends ClickableSpan { 

    String text; 

    public SpecialClickableSpan(String text){ 
     super(); 
     this.text = text; 
    } 

    @Override 
    public void onClick(View widget) { 
     Log.d(TAG, "onClick [" + text + "]"); 
    } 
} 

Dann rufen Sie neue SpecialClickableSpan ("My Text")

+0

Hey, danke! es ist perfekt für mich! –

0

Sie können auch String spannable wie diese

String htmlLinkText = "Lorem ipsum <a href='http://www.google.com'>dolor</a> sit amet"; 
    testView.setText(Html.fromHtml(htmlLinkText)); 
    testView.setMovementMethod(LinkMovementMethod.getInstance()); 

    CharSequence text = testView.getText(); 
    if (text instanceof Spannable) { 
     int end = text.length(); 
     Spannable sp = (Spannable) testView.getText(); 
     URLSpan[] urls = sp.getSpans(0, end, URLSpan.class); 
     SpannableStringBuilder style = new SpannableStringBuilder(text); 
     style.clearSpans();//should clear old spans 
     for (URLSpan url : urls) { 
      CustomerTextClick click = new CustomerTextClick(url.getURL()); 
      style.setSpan(click, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 
     testView.setText(style); 
    } 

und CustomerTextClick verwenden wird

private static zu machen sein Klasse CustomerTextClick erweitert ClickableSpan {

private String mUrl; 

    CustomerTextClick(String url) { 
     mUrl = url; 
    } 

    @Override 
    public void onClick(View widget) { 
     // TODO Auto-generated method stub 
     //Toast.makeText(ctx, "hello google!",Toast.LENGTH_LONG).show(); 
     // Do your action here 
    } 
} 

Geprüfter und funktionierender Code.

+0

Sie können click listener auch direkt in for loop als verwenden 'für (URLSpan url: urls) { CustomerTextKlick klicken = neu CustomerTextClick (url.getURL()); style.setSpan (neu ClickableSpan() { @Override public void onClick (Blick widget) { } }, sp.getSpanStart (url), sp.getSpanEnd (url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } ' –