2012-04-02 6 views
24

Ich habe TextView mit Text, der dynamisch geändert. Dieser Text enthält Zeichenfolgen wie <a href='myWord'>myWord</a>. Ich möchte, dass nach dem Klicken auf diesen "Link" myWord in der EditText in der gleichen Aktivität erscheint.anklickbare Wort in TextView in Android

Dies ist mein Code:

txt.setText(Html.fromHtml("...<a href='link'>link</a>...")); 
txt.setMovementMethod(LinkMovementMethod.getInstance()); 

Es ist für URLs in href Attribute gut funktionieren, aber es ist ein Fehler, ein anderes Format.

Ich fand viele ähnliche Fragen auf dem StackOverflow, aber alle von ihnen waren über URL-Links. In meiner App möchte ich "Link" innerhalb Aktivität erstellen. Im Allgemeinen kann ich Tag zu etwas anderem ändern, wenn es abhängt ...

Bitte helfen Sie mir! Vielen Dank!

----- Gelöst ----- Danke Jacob Phillips für die Idee!

Mai wird es in Zukunft jemand interessant sein. Dies ist ein Code:

//This is my string; 
String str = "<b>Text</b> which contains one <a href='#'>link</a> and another <a href='#'>link</a>"; 
//TextView; 
TextView txt = new TextView(this); 
//Split string to parts:           
String[] devFull = data[v.getId()][1].split("<a href='#'>"); 
//Adding first part: 
txt.append(Html.fromHtml(devFull[0])); 
//Creating array for parts with links (they amount always will devFull.length-1): 
SpannableString[] link = new SpannableString[devFull.length-1]; 
//local vars: 
ClickableSpan[] cs = new ClickableSpan[devFull.length-1]; 
String linkWord; 
String[] devDevFull = new String[2]; 

for(int i=1; i<devFull.length; i++){ 
    //obtaining 'clear' link 
    devDevFull = devFull[i].split("</a>"); 
    link[i-1] = new SpannableString(devDevFull[0]); 
    linkWord = devDevFull[0]; 
    cs[i-1] = new ClickableSpan(){ 
     private String w = linkWord; 
     @Override 
     public void onClick(View widget) { 
      // here you can use w (linkWord) 
     } 
    }; 
    link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0); 
    txt.append(link[i-1]); 
    try{ 
     txt.append(Html.fromHtml(devDevFull[1])); 
    } 
    catch(Exception e){} 
} 

Antwort

0

Die beste Abhilfe, die ich weiß, ist, Ihre eigene Button-Klasse zu erstellen. Sie können den Button mit einem transparenten Hintergrund versehen, sodass nur der Text vom Benutzer gesehen wird. Wenn die Schaltfläche gedrückt wird, ändern Sie die TextColor und den TextStyle der Schaltfläche, so dass sie eine dunklere Farbe haben und unterstrichen sind. Dies funktioniert genauso wie ein Link. Sie können dann startActivity verwenden, um zur entsprechenden Aktivität zu wechseln. Sie sollten keine Hyperlinks verwenden, um eine Verbindung zu anderen Aktivitäten in Ihrer Anwendung herzustellen.

+0

Vielen Dank für Ihre Antwort, aber ich kann Button nicht verwenden. Text in meinem TextView ist nicht statisch und ich kann nicht wissen, wo mein "Link" beim nächsten Mal erscheint. Text kommt von DB und ich muss mein linkWord irgendwie markieren. Ich benutze Tag ... – lubart

+0

Haben Sie versucht, eine benutzerdefinierte Inhalt URI erstellen? – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

0

Meine persönliche Meinung wäre, eine zweite Textansicht zu machen, die den Text enthält, der Ihr Link sein soll. Dann könnten Sie Ihre Aktion im onClick dieser zweiten textView tun. Auch als oben angegebenes zzzzzzzzzzz können Sie die Schriftarteigenschaften dieses Textes nach dem Klicken auf die gewünschten Eigenschaften ändern.

+1

Vielen Dank für Ihre Antwort, aber ich kann meine TextView nicht für wenige Stücke teilen, ich brauche ein Loch TextView ... – lubart

+0

Um wirklich eine innere Anwendung Link (was Sie wollen, wenn ich richtig verstehe), ich Ich denke, der einzige Weg, dies zu tun, ist die OnClick-Methode aufzurufen, und ich glaube nicht, dass dies in einem bestimmten Teil einer Textansicht möglich ist. Viel Glück damit aber – testingtester

38

Dies sollte den Trick tun. Ändern Sie einfach den Text Ihres Edittets in OnClickListener. Es kann reduziert werden, aber das sollte funktionieren.

private void foo() { 
    SpannableString link = makeLinkSpan("click here", new View.OnClickListener() {   
     @Override 
     public void onClick(View v) { 
      // respond to click 
     } 
    }); 

    // We need a TextView instance.   
    TextView tv = new TextView(context); 

    // Set the TextView's text  
    tv.setText("To perform action, "); 

    // Append the link we created above using a function defined below. 
    tv.append(link); 

    // Append a period (this will not be a link). 
    tv.append("."); 

    // This line makes the link clickable! 
    makeLinksFocusable(tv); 
} 

/* 
* Methods used above. 
*/ 

private SpannableString makeLinkSpan(CharSequence text, View.OnClickListener listener) { 
    SpannableString link = new SpannableString(text); 
    link.setSpan(new ClickableString(listener), 0, text.length(), 
     SpannableString.SPAN_INCLUSIVE_EXCLUSIVE); 
    return link; 
} 

private void makeLinksFocusable(TextView tv) { 
    MovementMethod m = tv.getMovementMethod(); 
    if ((m == null) || !(m instanceof LinkMovementMethod)) { 
     if (tv.getLinksClickable()) { 
      tv.setMovementMethod(LinkMovementMethod.getInstance()); 
     } 
    } 
} 

/* 
* ClickableString class 
*/ 

private static class ClickableString extends ClickableSpan { 
    private View.OnClickListener mListener;   
    public ClickableString(View.OnClickListener listener) {    
     mListener = listener; 
    }   
    @Override 
    public void onClick(View v) { 
     mListener.onClick(v); 
    }   
} 
+0

Vielen Dank für Ihre Antwort. Es tut mir leid für eine dumme Frage, aber was ist die ClickableString() Klasse? – lubart

+0

Ich habe es gerade hinzugefügt. Ich habe eine modifizierte Version von [diese Antwort] (http://stackoverflow.com/a/5681946/884522) auf eine ähnliche Frage –

+0

Vielen Dank! Aber es funktioniert nicht :( Ich habe einen Fehler in der Zeile 'mlistener.onClick (v); 'in der ClickableString-Klasse: ' Die Methode onClick (DialogInterface, int) im Typ DialogInterface.OnClickListener ist nicht anwendbar für die Argumente (View) ' und ich weiß nicht, wie ich sie korrigieren soll. Hast du irgendwelche Ideen? Danke trotzdem! – lubart

9

besserer Ansatz ist

SpannableString ss = new SpannableString("Android is a Software stack"); 
    ClickableSpan clickableSpan = new ClickableSpan() { 
     @Override 
     public void onClick(View textView) { 
      startActivity(new Intent(MyActivity.this, NextActivity.class)); 
     } 
    }; 
    ss.setSpan(clickableSpan, 22, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
//where 22 and 27 are the starting and ending index of the String. Now word stack is clickable 
// onClicking stack it will open NextActiivty 

    TextView textView = (TextView) findViewById(R.id.hello); 
    textView.setText(ss); 
    textView.setMovementMethod(LinkMovementMethod.getInstance()); 
+0

wenn sie mehrere Klicks sind – Prasad

+0

werfen Sie einen Blick auf http://Stackoverflow.com/a/9982588/3496570 und http://Stackoverflow.com/a/22006998/3496570 – Nepster

+0

scheint Kopie-Paste von diesem - http: // stackoverflow.com/a/10697453/1479511 – NarendraJi

0

Um es vollständige Antwort zu machen Antworten mit mischen;

private void textAreaInit() 
{ 
    String str = "<a href='#'>Link 1</a> and <a href='#'>Link2</a> is here."; 

    TextView tv = mConfirmText; 
    String[] devFull = str.split("<a href='#'>"); 


    tv.append(Html.fromHtml(devFull[0])); 

    SpannableString[] link = new SpannableString[devFull.length-1]; 

    ClickableSpan[] cs = new ClickableSpan[devFull.length-1]; 
    String linkWord; 
    String[] devDevFull = new String[2]; 

    for(int i=1; i<devFull.length; i++) 
    { 
     //obtaining 'clear' link 
     devDevFull = devFull[i].split("</a>"); 
     link[i-1] = new SpannableString(devDevFull[0]); 
     linkWord = devDevFull[0]; 
     final String a = linkWord; 
     cs[i-1] = new ClickableSpan() 
     { 
      private String w = a; 
      @Override 
      public void onClick(View widget) { 

       if(w.equals("Link 1")) 
       { 
        Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class); 
        intent.putExtra("title", "Link1"); 
        intent.putExtra("uri", "link1"); 
        intent.putExtra("type", "1"); 
        startActivity(intent); 
       } 
       else 
       { 
        Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class); 
        intent.putExtra("title", "Link2"); 
        intent.putExtra("uri", "link2"); 
        intent.putExtra("type", "2"); 
        startActivity(intent); 
       } 
      } 
     }; 
     link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0); 
     tv.append(link[i-1]); 
     try{ 
      tv.append(Html.fromHtml(devDevFull[1])); 
     } 
     catch(Exception e){} 
    } 


    makeLinksFocusable(tv); 
} 

private void makeLinksFocusable(TextView tv) { 
    MovementMethod m = tv.getMovementMethod(); 
    if ((m == null) || !(m instanceof LinkMovementMethod)) { 
     if (tv.getLinksClickable()) { 
      tv.setMovementMethod(LinkMovementMethod.getInstance()); 
     } 
    } 
} 
Verwandte Themen