2016-06-22 22 views
1

すべての単語を個別にクリックできるTextViewがあります。私は、すべての単語がunstyledから始めたいと思います。単語をクリックすると、単語には下線が引かれて残ります。私はデフォルトの下線をクリアすることができますが、クリックすると何も起こりません。 (私はクリックをキャプチャして処理していますが、スパンスタイルを変更することはできません)。Android ClickableSpanスタイルを変更しないonclick

関連コードは以下のとおりです。助けを前にありがとう。

カスタムClickableSpan:

class WordSpan extends ClickableSpan { 
    private TextPaint textpaint; 
    public boolean clicked = false; 

    @Override 
    public void updateDrawState(TextPaint ds) { 
    textpaint = ds; 
    ds.setUnderlineText(false); 

    if (clicked) 
     ds.setUnderlineText(true); 
    } 

    @Override 
    public void onClick(View v) {} 

    public void setClicked(boolean c) { 
    clicked = c; 
    updateDrawState(textpaint); 
    } 
} 

のonCreate()から私はtxtファイルを解析し、TextViewのに各単語を追加しています。あなたはspannable文字列に複数のクリック可能なスパンを追加する必要があります個々の単語クリッカブルを作るために

SpannableString ss = new SpannableString(word.toString()); 

    WordSpan clickableSpan = new WordSpan() { 
    @Override 
    public void onClick(View view) { 
    setClicked(true); 
    view.invalidate(); 
    }}; 

    ss.setSpan(clickableSpan, 0, word.toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

    tvText.append(ss); 
    tvText.append(" "); 
} 

tvText.setMovementMethod(LinkMovementMethod.getInstance()); 
+0

1. Individualyワードはクリックできません。 2.シングルをクリックすると、すべてのテキストにアンダーラインが表示されます。これはスタイルを変更することを意味します。 あなたの正確な要件を理解できません。 – Chitrang

+0

clickablespanは個々の単語をクリック可能にします。私は個々の単語のクリックを処理し、このコードでクリックされた単語を検出することができます。今すぐクリックした単語のスタイルを変更して、実際にクリックされたことをユーザーに示す必要があります。 –

答えて

1

:この解析ループの中で私は、次のコードを持っています。たとえば、単一のTextviewで「foo」と「bar」を個別にクリック可能にするには、「foo」と「bar」の2つのクリック可能なスパンを追加し、spannable文字列に追加する必要があります。

例では、スペースを使用して文字列を分割していますが、スパンをクリックするロジックを記述する必要があります。

アンダーラインを削除するクリック可能なスパンです。さらに、クリック時に背景とテキストの色を設定できます。あなたはそれを使用しない場合は、それを削除することができます。

import android.text.TextPaint; 
import android.text.style.ClickableSpan; 

public abstract class TouchableSpan extends ClickableSpan { 
    private boolean mIsPressed; 
    private int mPressedBackgroundColor; 
    private int mNormalTextColor; 
    private int mPressedTextColor; 
    private int mBackgroundColor; 

    public TouchableSpan(int normalTextColor,int backgroundColor, int pressedTextColor, int pressedBackgroundColor) { 
     mBackgroundColor = backgroundColor; 
     mNormalTextColor = normalTextColor; 
     mPressedTextColor = pressedTextColor; 
     mPressedBackgroundColor = pressedBackgroundColor; 
    } 

    public void setPressed(boolean isSelected) { 
     mIsPressed = isSelected; 
    } 

    @Override 
    public void updateDrawState(TextPaint ds) { 
     super.updateDrawState(ds); 
     ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor); 
     ds.bgColor = mIsPressed ? mPressedBackgroundColor : mBackgroundColor; 
     ds.setUnderlineText(!mIsPressed); 
    } 
} 

スパンを処理するLinkMovementMethodを作成します。あなたは色の条項を削除する場合は、同様にこれを変更することができます

import android.text.Layout; 
import android.text.Selection; 
import android.text.Spannable; 
import android.text.method.LinkMovementMethod; 
import android.text.method.MovementMethod; 
import android.view.MotionEvent; 
import android.widget.TextView; 

public class LinkTouchMovementMethod extends LinkMovementMethod { 

    private TouchableSpan mPressedSpan; 

    @Override 
    public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      mPressedSpan = getPressedSpan(textView, spannable, event); 
      if (mPressedSpan != null) { 
       mPressedSpan.setPressed(true); 
       Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan), 
         spannable.getSpanEnd(mPressedSpan)); 
      } 
     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event); 
      if (mPressedSpan != null && touchedSpan != mPressedSpan) { 
       mPressedSpan.setPressed(false); 
       mPressedSpan = null; 
       Selection.removeSelection(spannable); 
      } 
     } else { 
      if (mPressedSpan != null) { 
       mPressedSpan.setPressed(false); 
       super.onTouchEvent(textView, spannable, event); 
      } 
      mPressedSpan = null; 
      Selection.removeSelection(spannable); 
     } 
     return true; 
    } 

    private TouchableSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent event) { 

     int x = (int) event.getX(); 
     int y = (int) event.getY(); 

     x -= textView.getTotalPaddingLeft(); 
     y -= textView.getTotalPaddingTop(); 

     x += textView.getScrollX(); 
     y += textView.getScrollY(); 

     Layout layout = textView.getLayout(); 
     int line = layout.getLineForVertical(y); 
     int off = layout.getOffsetForHorizontal(line, x); 

     TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class); 
     TouchableSpan touchedSpan = null; 
     if (link.length > 0) { 
      touchedSpan = link[0]; 
     } 
     return touchedSpan; 
    } 

} 

は、その後、あなたは、次の方法でそれを使用することができます。

TextView textView = (TextView)findViewById(R.id.hello_world); 
String fooBar = "asdfasdfasdfasf asdfasfasfasd"; 
String[] clickSpans = fooBar.split(" "); 
int clickSpanLength = clickSpans.length; 
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); 
int totalLength = 0; 
int normalColor = getResources().getColor(android.R.color.black); 
int clickColor = getResources().getColor(android.R.color.holo_blue_bright); 
String separator = " , "; 
int separatorLength = separator.length(); 
for (int i = 0; i < clickSpanLength; i++) { 
    int currentWordLength = clickSpans[i].length(); 
    spannableStringBuilder.append(clickSpans[i]); 
    if (i < clickSpanLength - 1) { 
     spannableStringBuilder.append(" , "); 
    } 

    spannableStringBuilder.setSpan(new TouchableSpan(normalColor, Color.TRANSPARENT, clickColor, Color.TRANSPARENT) { 
     @Override 
     public void onClick(View widget) { 

     } 
    }, totalLength, totalLength + currentWordLength, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); 
    totalLength = totalLength + currentWordLength + separatorLength; 
} 

textView.setText(spannableStringBuilder); 
textView.setMovementMethod(new LinkTouchMovementMethod()); 
+0

ありがとうございます。このソリューションは機能します。しかし、maxLinesとscrollbarsがxmlに設定されていても、TextViewはスクロールしません。 –

+0

textViewをスクロール可能にするには、スクロールビューで囲みます。 LinkMovementMethodの代わりにScrollingMovementMethodを拡張しても、スクロールビューへの移動方法を設定するもう1つの方法は機能しません –

関連する問題