2012-04-02 16 views
3

元の文字列:AndroidのTextViewの形式の複数の単語

Loremのイプサム## ## ## ## dolar ATEM座ります。 Lorem ipsum dolar sit ## atem ##。整形後

Loremの#ipsum dolar #sit ATEM。 Lorem ipsum dolar sit #atem。

しかし最後のものだけがFormating i wantを持っています。下の画像を参照してください。

CODE

private void format() { 
    CharSequence text = editContent.getText(); 

    MovementMethod movementMethod = editContent.getMovementMethod(); 
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod)) 
    { 
     editContent.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 

    text = setSpanBetweenTokens(text, "##", new ForegroundColorSpan(0xFF0099FF), new UnderlineSpan(), new ClickableSpan() { 
     @Override 
     public void onClick(View widget) { 
      Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    editContent.setText(text); 
} 

private static CharSequence setSpanBetweenTokens(CharSequence text, String token, CharacterStyle... characterStyle) { 
    int tokenLen = token.length(); 
    int start = text.toString().indexOf(token) + 1; 
    int end = text.toString().indexOf(token, start); 

    while (start > -1 && end > -1) 
    { 
     SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); 
     for (CharacterStyle c : characterStyle) { 
      spannableStringBuilder.setSpan(c, start, end, 0); 
     } 

     spannableStringBuilder.delete(end, end + tokenLen); 
     spannableStringBuilder.delete(start - 1, start); 

     text = spannableStringBuilder; 

     start = text.toString().indexOf(token) + 1; 
     end = text.toString().indexOf(token, start); 
    } 

    return text; 
} 

EDIT

private void format() { 
    CharSequence text = editContent.getText(); 

    MovementMethod movementMethod = editContent.getMovementMethod(); 
    if ((movementMethod == null) || !(movementMethod instanceof LinkMovementMethod)) 
    { 
     editContent.setMovementMethod(LinkMovementMethod.getInstance()); 
    } 

    text = setSpanBetweenTokens(text, "##"); 

    editContent.setText(text); 
} 

private static CharSequence setSpanBetweenTokens(CharSequence text, String token) { 
    int tokenLen = token.length(); 
    int start = text.toString().indexOf(token) + 1; 
    int end = text.toString().indexOf(token, start); 

    while (start > -1 && end > -1) 
    { 
     SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); 

     spannableStringBuilder.setSpan(new ForegroundColorSpan(0xFF0099FF), start, end, 0); 
     spannableStringBuilder.setSpan(new UnderlineSpan(), start, end, 0); 
     spannableStringBuilder.setSpan(new ClickableSpan() { 
      @Override 
      public void onClick(View widget) { 
       Log.d("DEBUG", "Click"); 
      } 
     }, start, end, 0); 

     spannableStringBuilder.delete(end, end + tokenLen); 
     spannableStringBuilder.delete(start - 1, start); 

     text = spannableStringBuilder; 

     start = text.toString().indexOf(token) + 1; 
     end = text.toString().indexOf(token, start); 
    } 

    return text; 
} 

答えて

4

峠異なるオブジェクトの各スパンのための私の最終的な解決策:

spannableStringBuilder.setSpan(c, start, end, 0); 

あなたは各スパンで同じオブジェクト渡している:スパンオブジェクトがspannableStringBuilderに存在する場合、それが唯一の境界を変更する

new ForegroundColorSpan(0xFF0099FF) 

を、ない新しいスパンが追加されます。

3

私はより簡単な方法を提案します。あなたの書式設定のニーズが基本であれば、簡単な正規表現+ Html.fromHtml()は、トリックを行う必要があります。最終的な解決策が正しくしかし、ループ

private void format() { 
    String mText = editContent.getText(); 

    Spanned mSpannedText = Html.fromHtml(mText.replaceAll("##(.*?)##)","<font color=\"0xFF0099\">#$1</font>"), 

    editContent.setText(mSpannedText); 
} 
+0

私のフォーマット機能を更新しました –

+0

REGEXとWEBVIEWSの両方が最後のリソースだと思います。リソースを集中的に使用しているため、何か簡単ではありません。 –

+0

@Jorge Aguilar、私はこのスニペットがwebviewを作成するとは思わない。パフォーマンスヒットはごくわずかです。 –

1

あなたは

int start = text.toString().indexOf(token) + 1; 
を使用しているとして、あなたの最初のトークンが正しく削除されません

トークンの長さが1文字の場合にのみ機能します。あなたの選ばれたトークンがあるので、##これはあなたのテキストが正しく編集されていると、あなたのトークンのすべてのトレースが削除されていることを確認しますすでに作成された変数tokenLen

int start = text.toString().indexOf(token) + tokenLen; 

を利用する上記のコードを変更します。

関連する問題