TextViewでテキストの一部をクリックした時の動作の実装方法をググると色々あってややこしかったので、下記要件の場合のみ便利なクラスを作ってみました。
- 全文・一部文字列だけ定義すれば動く。
- 任意の動作を書けるリスナーがある。
全文"testhogehogeeeeeeehogefugaaaaagugapiyo"の中から一部文字列"hoge"と"fuga"のクリックに個別に反応するサンプルと便利クラスを晒します。
便利クラス
TextLinker.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ClickableSpan;
import android.util.SparseArray;
import android.view.View;
public class TextLinker {
public interface OnLinkClickListener{
public void onLinkClick(int textId);
}
private static class TextClickSpan extends ClickableSpan{
private OnLinkClickListener mListener;
private int mTextId;
public TextClickSpan(int textId , OnLinkClickListener listener){
mTextId = textId;
mListener = listener;
}
@Override
public void onClick(View widget) {
if(mListener != null)mListener.onLinkClick(mTextId);
}
}
public static SpannableString getLinkableText(String text , SparseArray<String> links , OnLinkClickListener listener){
SpannableString spannable = new SpannableString(text);
int size = links.size();
for(int i = 0 ; i < size ; i++){
int key = links.keyAt(i);
String link = links.get(key);
Pattern p = Pattern.compile(link);
Matcher m = p.matcher(text);
while(m.find()){
TextClickSpan span = new TextClickSpan(key , listener);
spannable.setSpan(span, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return spannable;
}
}
使い方
String text ="testhogehogeeeeeeehogefugaaaaagugapiyo";
SparseArray<String> links = new SparseArray<String>();
links.append(0, "hoge");
links.append(1, "fuga");
OnLinkClickListener listener = new OnLinkClickListener() {
@Override
public void onLinkClick(int textId) {
// hogeをクリックするとtextIdは0、
// fugaをクリックするとtextIdは1。
}
};
TextView textView = (TextView)findViewById(R.id.text);
textView.setText(TextLinker.getLinkableText(text, links, listener));
textView.setMovementMethod(LinkMovementMethod.getInstance());
リンク色変更する場合
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textColorLink="@android:color/holo_purple"
/>