2017-09-05 20 views
9

特殊字符我有一個​​3串這樣的:如何獲得與單詞和其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", 

我想要做的就是用戶名和城市名不同的顏色到其點擊事件。

我能達到的是通過分割爲「:」字符獲取用戶名。 但我不知道如何獲得城市名稱,並點擊兩者的事件。

在城市名稱中只有最後一個城市的顏色正在變化,如何更改兩個城市的名稱顏色並獲取其點擊事件。

這是我的嘗試:

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

,這就是我得到的輸出:

enter image description here

,這是我真正期待:

enter image description here

+0

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

+0

至於如何從文本中獲取數據,請嘗試格式化你的字符串更容易解析,而不是使用split(),也許是一個json。 – vlatkozelka

+0

我試圖與您的鏈接,但我可以得到點擊事件,但無法設置顏色.. –

回答

3

我想你已經輸入用戶名和麪臨的問題與城市的點擊,所以我給的答案與點擊城市名來完成。

感謝@Vinay給出了一些提示。

請檢查以下代碼。

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

輸出截圖:

enter image description here

+0

它只適用於「#」嗎?因爲我有其他帶有「$」符號的文字,並且與玩偶符號模式不匹配。 –

+0

和「@」表示它總是出現錯誤,如java.lang.IndexOutOfBoundsException:setSpan(-2 ... 7)在0之前開始 –

+0

您必須將此邏輯保存在此** else if(notifications.getTitle()。包含(「#」))**部分 –

4

使用正則表達式。

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

輸出將是:

surat 
mumbai 
+0

,但如何使最終的字符串..,我應用你的解決方案,我得到蘇拉特和孟買輸出,我也上色了兩個地方,現在如何添加到textview作爲最終輸出 –

4

要提取與點擊主題標籤的最終描述,你的列表項的佈局添加一個隱藏LinearLayout

<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" /> 

修改代碼來分隔與動態的主題標籤並將其添加回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()); 
    } 

最後的輸出,

enter image description here

+0

看起來像完美的答案。 –

+0

似乎很有希望..我會盡快嘗試..和用戶點擊事件 –

+0

它不會與多行文本工作。 –

1

使用SpannableString,你幾乎不需要任何特殊字符,只知道點擊單詞索引。 Like波紋管:

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

我知道,它的共同點是..但我的文字是動態的.. –

3

嘗試this library。這是一個只適用於#的散列標籤實現。根據您的需求增強此庫後,它可能會對您有所幫助。

+1

不錯的圖書館...是的,它可能會有所幫助......謝謝。 –