2017-09-05 3 views
9

i have a 3 cordes comme ceci:comment obtenir un caractère spécial avec le mot et son événement click

"@Username: Deliverd your order", 
"YOU got trophy: KING OF COINS", 
"There is a package waiting for you to pick up from #surat to #mumbai", 

ce que je voulais faire est d'obtenir le nom d'utilisateur et le nom de la ville dans une couleur différente avec son événement click. Ce que je peux obtenir est d'obtenir le nom d'utilisateur en le divisant en caractère ":". mais je ne sais pas comment obtenir le nom de la ville et cliquez sur l'événement des deux.

Dans le nom de la ville, seule la dernière couleur de la ville change, comment changer la couleur du nom de la ville et obtenir son événement click.

ce que j'ai essayé:

if (notifications.getTitle().contains(":")) 
{ 
    String[] username = notifications.getTitle().split(":"); 
    String uname = getColoredSpanned(username[0] + ":", "#ff7505"); 
    String txt = getColoredSpanned(username[1], "#000000"); 
    holder.txtTitle.append(Html.fromHtml(uname +" " + txt)); 
    holder.txtTitle.setMovementMethod(LinkMovementMethod.getInstance()); 
} 
else if (notifications.getTitle().contains("#")) 
{ 
    Matcher matcher = 
      Pattern.compile("#\\s(\\w+)").matcher(notifications.getTitle()); 
    i=0; 
    while (matcher.find()) 
    { 
      place.add(i, matcher.group(1)); 
      i++; 
    } 
    String place1 = getColoredSpanned("#" + place.get(0), "#237BCD"); 
    String place2 = getColoredSpanned("#" + place.get(1), "#237BCD"); 
    places1 = notifications.getTitle().replace("#" + place.get(0), place1); 
    places1 = notifications.getTitle().replace("#" + place.get(1), place2); 
    holder.txtTitle.setText(Html.fromHtml(places1)); 
} 
else 
{ 
    holder.txtTitle.setText(notifications.getTitle()); 
} 

private String getColoredSpanned(String text, String color) { 
    String input = "<font color=" + color + ">" + text + "</font>"; 
    return input; 
} 

et ce que je reçois en sortie:

enter image description here

et ce que j'attendais vraiment:

enter image description here

+0

https://stackoverflow.com/questions/10696986/how-to-set-the-part-of-the-text-view-is-clickable – vlatkozelka

+0

pour savoir comment obtenir des données à partir d'un texte, essayez de formater votre chaîne d'une manière qui est plus facile à analyser plutôt que d'utiliser split(), peut-être un json. – vlatkozelka

+0

j'ai essayé avec votre lien mais avec cela je peux obtenir l'événement de clic mais pas capable de placer la couleur –

Répondre

3

Je pense que vous avez fait avec nom d'utilisateur et problème auquel sont confrontés avec un clic sur la ville, donc j'ai donné réponse à cliquez sur le nom de la ville.

Merci à @Vinay pour une indication.

Veuillez vérifier le code ci-dessous.

public void setSpan() { 
     String test = "There is a package waiting for you to pick up from #surat to #mumbai"; 
     SpannableString spannable = new SpannableString(test); 
     final Matcher matcher = Pattern.compile("#\\s*(\\w+)").matcher(test); 
     while (matcher.find()) { 
      final String city = matcher.group(1); 
      ClickableSpan clickableSpan = new ClickableSpan() { 
       @Override 
       public void onClick(View textView) { 
        Toast.makeText(mActivity, city, Toast.LENGTH_SHORT).show(); 
       } 

       @Override 
       public void updateDrawState(TextPaint ds) { 
        super.updateDrawState(ds); 
        ds.setUnderlineText(false); 
        ds.setColor(Color.RED); 
       } 
      }; 
      int cityIndex = test.indexOf(city) - 1; 
      spannable.setSpan(clickableSpan, cityIndex, cityIndex + city.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
     } 
     mTextViewNotification.setText(spannable); 
     mTextViewNotification.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 

Capture d'écran de sortie:

enter image description here

+0

est-ce que cela fonctionne seulement pour "#"? parce que j'ai un autre texte qui a un signe "$", et avec un motif de signe de doller qui ne correspond pas. –

+0

et avec "@" signe son erreur toujours obtenir comme java.lang.IndexOutOfBoundsException: setSpan (-2 ... 7) commence avant 0 –

+0

Vous devez garder cette logique dans ce ** else if (notifications.getTitle(). contient ("#")) ** section –

4

utilisez Regex pour cela.

String str= "There is a package waiting for you to pick up from #surat to #mumbai"; 

Matcher matcher = Pattern.compile("#\\s*(\\w+)").matcher(str); 
while (matcher.find()) { 
    System.out.println(matcher.group(1)); 
} 

sortie sera:

surat 
mumbai 
+0

mais comment faire cette chaîne finale .., j'ai appliqué votre solution, je reçois surat et mumbai comme sortie, j'ai également coloré les deux endroits, maintenant comment ajouter au texte comme une sortie finale –

4

Pour extraire la description finale avec hashtags cliquables, ajoutez un LinearLayout caché dans votre élément de la liste mise en page:

<LinearLayout 
     android:id="@+id/layoutDescription" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="24dp" 
     android:orientation="horizontal" 
     android:visibility="gone" /> 

Modifier votre code pour séparer les hashtags avec dynamique TextViews et les ajouter de nouveau dans le LinearLayout:

if (notifications.getTitle().contains(":")) { 
     String[] username = notifications.getTitle().split(":"); 
     String pre_username = getColoredSpanned(username[0] + ":", "#ff7505"); 
     String post_username = getColoredSpanned(username[1], "#000000"); 
     holder.txtTitle.append(Html.fromHtml(pre_username + " " + post_username)); 
     holder.txtTitle.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 
    else if (notifications.getTitle().contains("#")) { 
     layoutDescription.setVisibility(View.VISIBLE); 

     Matcher matcher = Pattern.compile("#\\s(\\w+)").matcher(notifications.getTitle()); 

     List<String> place = new ArrayList<>(); 
     int i = 0; 
     while (matcher.find()) { 
      place.add(i, matcher.group(1)); 
      i++; 
     } 

     LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
       LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(5, 0, 5, 0); // (left, top, right, bottom) 

     TextView mHashTagA = new TextView(this); 
     mHashTagA.setLayoutParams(layoutParams); 
     mHashTagA.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Toast.makeText(getApplicationContext(), "Clicked on HashTag A", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     TextView mSeparator = new TextView(this); 
     mSeparator.setLayoutParams(layoutParams); 
     mSeparator.setText("to"); 

     TextView mHashTagB = new TextView(this); 
     mHashTagB.setLayoutParams(layoutParams); 
     mHashTagB.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Toast.makeText(getApplicationContext(), "Clicked on HashTag B", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     TextView mDescription = new TextView(getApplicationContext()); 
     mDescription.setTextColor(Color.parseColor("#343434")); 
     mDescription.setLayoutParams(layoutParams); 

     String place1 = getColoredSpanned("#" + place.get(0), "#237BCD"); 
     mHashTagA.setText(Html.fromHtml(place1)); 

     String place2 = getColoredSpanned("#" + place.get(1), "#237BCD"); 
     mHashTagB.setText(Html.fromHtml(place2)); 

     String without_hash = notifications.getTitle().split("#")[0]; 
     mDescription.setText(without_hash); 

     layoutDescription.addView(mDescription); 
     layoutDescription.addView(mHashTagA); 
     layoutDescription.addView(mSeparator); 
     layoutDescription.addView(mHashTagB); 
    } else { 
     layoutDescription.setVisibility(View.GONE); 
     holder.txtTitle.setText(notifications.getTitle()); 
    } 

La sortie finale,

enter image description here

+0

On dirait que la réponse parfaite. –

+0

semble prometteur .. je vais essayer bientôt .. et qu'en est-il utilisateur événement –

+0

il ne fonctionnera pas avec le texte multi-ligne. –

1

Utilisez SpannableString, youd ne nécessitent aucun caractère spécial, il suffit de savoir index cliquable de mots. Comme ci-dessous:

SpannableString styledString 
      = new SpannableString("There is a package waiting for you to pick up from " + 
      "surat" + // index 51 - 56 
      " to " + 
      "mumbai"); //index 60 - 66 

    // clickable text for "surat" 
    ClickableSpan clickableSpan1 = new ClickableSpan() { 

     @Override 
     public void onClick(View widget) { 
      // We display a Toast. You could do anything you want here. 
      Toast.makeText(MainActivity.this, "surat clicked", Toast.LENGTH_SHORT).show(); 

     } 
    }; 

    // clickable text for "mumbai" 
    ClickableSpan clickableSpan2 = new ClickableSpan() { 

     @Override 
     public void onClick(View widget) { 
      // We display a Toast. You could do anything you want here. 
      Toast.makeText(MainActivity.this, "mumbai clicked", Toast.LENGTH_SHORT).show(); 

     } 
    }; 

    styledString.setSpan(clickableSpan1, 51, 56, 0); 
    styledString.setSpan(clickableSpan2, 60, 66, 0); 

    textView.setText(styledString); 
+0

je sais, sa chose commune à faire .. mais mon texte est dynamique .. –

3

Essayez this library. C'est une implémentation hash-tag qui fonctionne pour # seulement. Cela peut vous aider après l'amélioration de cette bibliothèque pour vos besoins.

+1

belle bibliothèque ... oui, il pourrait être utile ... merci. –