Skip to content

Instantly share code, notes, and snippets.

@rabidaudio
Created September 25, 2015 21:53
Show Gist options
  • Save rabidaudio/618f9d852989df95f042 to your computer and use it in GitHub Desktop.
Save rabidaudio/618f9d852989df95f042 to your computer and use it in GitHub Desktop.
HyperlinkTextView.java
package audio.rabid.dev.utils;
import android.content.Context;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Charles Julian Knight, charles@rabidaudio.com on 9/25/15.
*
* A text view that you can attach callbacks to.
*
* Links are surrounded by double square brackets. For example:
*
* <code>[[This]] is a link</code>
*
* Use {@link #setOnLinkClickListener(OnLinkClickListener)} to get a callback with both the link text
* and its index in the string so that you can handle it as you like.
*
* A lot of this was gathered from <a href="This stackoverflow answer">http://stackoverflow.com/a/5681946</a>.
*/
public class HyperlinkTextView extends TextView {
private OnLinkClickListener linkClickListener;
private static final Pattern URL_PATTERN = Pattern.compile("\\[\\[(.*?)\\]\\]");
public HyperlinkTextView(Context context) {
super(context);
}
public HyperlinkTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HyperlinkTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setText(CharSequence text, BufferType type) {
if(type==BufferType.NORMAL) {
setText(text.toString());
}else{
super.setText(text, type);
}
}
private void setText(String text) {
String[] regularText = URL_PATTERN.split(text);
Matcher m = URL_PATTERN.matcher(text);
int index = 0;
while(m.find()){
append(regularText[index]);
final String hyperlink = m.group(1);
SpannableString ss = SpannableString.valueOf(hyperlink);
final int finalIndex = index;
ss.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
if(linkClickListener != null){
linkClickListener.onLinkClick(hyperlink, finalIndex);
}
}
}, 0, hyperlink.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
append(ss);
index++;
}
if(regularText.length > m.groupCount()){
//need to add that last regular text
append(regularText[regularText.length-1]);
}
MovementMethod mm = getMovementMethod();
if ((mm == null) || !(mm instanceof LinkMovementMethod)) {
setMovementMethod(LinkMovementMethod.getInstance());
}
}
public void setOnLinkClickListener(OnLinkClickListener linkClickListener){
this.linkClickListener = linkClickListener;
}
public interface OnLinkClickListener {
void onLinkClick(String linkText, int id);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment