2016-06-22 12 views
1

나는 모든 단어를 개별적으로 클릭 할 수있는 TextView 있습니다. 나는 모든 단어를 unstyled로 시작하고 싶다. 단어를 클릭하면 단어에 밑줄이 표시됩니다. 기본 밑줄을 지울 수 있지만 클릭 할 때 아무런 변화가 없습니다. (나는 클릭을 캡쳐하고 처리하고 있지만 스팬 스타일을 변경할 수는 없습니다.)안드로이드 ClickableSpan 스타일을 변경하지 onclick

관련 코드는 다음과 같습니다. 도움에 미리 감사드립니다.

사용자 정의 ClickableSpan :에서 onCreate에서

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

은() 내가 txt 파일을 구문 분석하고 텍스트 뷰에 각 단어를 추가하고있다.

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. 하나를 클릭하면 모든 텍스트에 밑줄이 표시됩니다. 이는 스타일 onclick을 변경한다는 의미입니다. 정확한 요구 사항을 이해할 수 없습니다. – Chitrang

+0

clickablespan은 개별 단어를 클릭 할 수있게합니다. 각 개별 단어에 대한 클릭을 처리하고이 단어로 클릭 한 단어를 찾아 낼 수 있습니다. 이제 클릭 한 단어의 스타일을 변경하여 실제로 클릭했음을 사용자에게 보여줘야합니다. –

답변

1

당신이 spannable 문자열에 여러 클릭 할 수있는 범위를 추가해야합니다 클릭 가능한 개별 단어를 만들려면이 구문 분석 루프 내에서 나는 다음과 같은 코드가 있습니다. 예를 들어, 하나의 Textview에서 "foo"와 "bar"를 개별적으로 클릭 할 수있게하려면 clickable span을 두 개 추가해야합니다. 하나는 "foo"이고 다른 하나는 "bar"입니다. 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); 
    } 
} 

Span을 처리 할 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

감사합니다.이 솔루션이 효과적입니다. 그러나 XML에 maxLines 및 scrollbars가 설정되어 있어도 TextView는 스크롤되지 않습니다. –

+0

textView를 스크롤 할 수있게하려면 scrollview로 둘러 쌉니다. LinkMovementMethod 대신 ScrollingMovementMethod를 확장하더라도 scrollview로 이동 메서드를 설정하는 다른 방법은 작동하지 않습니다. –