Создать ссылку на TextView в Android
У меня есть следующий удобный метод:
public static void createLink(TextView textView, String linkText, String linkHRef) {
String htmlLink = "<a href='%s'>%s</a>";
Spanned spanned = Html.fromHtml(String.format(htmlLink, linkHRef, linkText));
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(ContextCompat.getColor(textView.getContext(), android.R.color.holo_green_light));
textView.setText(spanned, TextView.BufferType.SPANNABLE);
}
Я использую этот метод для создания интерактивной ссылки внутри текстового представления, учитывая само текстовое представление, текстовую ссылку и URL-адрес.
Теперь я хотел бы показать "эффект щелчка", когда пользователь нажимает на этот текст.
Как мне этого добиться?
Большое спасибо!
ОБНОВИТЬ
Мне удалось получить то, что я имею в виду, таким образом:
public static void createLink(TextView textView, String linkText, String linkHRef, @ColorRes int linkColorStateList) {
String htmlLink = "<a href='%s'>%s</a>";
Spanned spanned = Html.fromHtml(String.format(htmlLink, linkHRef, linkText));
textView.setTextColor(ContextCompat.getColorStateList(textView.getContext(), linkColorStateList));
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(spanned, TextView.BufferType.SPANNABLE);
}
И определение цветового списка XML-файла:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:color="@color/green" />
<item android:state_focused="true" android:state_pressed="true" android:color="@color/green_dark" />
<item android:state_focused="false" android:state_pressed="true" android:color="@color/green_dark" />
<item android:color="@color/green" />
</selector>
Теперь цвет текста, содержащегося в TextView, меняется, когда я нажимаю на него.
Единственное, чего я не понимаю, это почему цвет фона TextView тоже меняется, становясь ярко-синим. Мой код не делает этого, я думаю. Кто-нибудь может быть знает это?
4 ответа
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String description = "Your Description http://stackru.com/";
Spannable spannable = new SpannableString( description );
Linkify.addLinks(spannable, Linkify.WEB_URLS);
URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
for (URLSpan urlSpan : spans) {
LinkSpan linkSpan = new LinkSpan(urlSpan.getURL());
int spanStart = spannable.getSpanStart(urlSpan);
int spanEnd = spannable.getSpanEnd(urlSpan);
spannable.setSpan(linkSpan, spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.removeSpan(urlSpan);
}
txt_textview.setMovementMethod(EnhancedLinkMovementMethod.getInstance());
txt_textview.setText(spannable, BufferType.SPANNABLE);
}
//if you want to open in app web
private class LinkSpan extends URLSpan {
private LinkSpan(String url) {
super(url);
}
@Override
public void onClick(View view) {
String url = getURL();
//Toast.makeText(getApplicationContext(), ""+url, Toast.LENGTH_SHORT).show();
Intent webIntent = new Intent(this,Web.class);
webIntent.putExtra("url", url);
startActivity(webIntent);
}
}
public class EnhancedLinkMovementMethod extends ArrowKeyMovementMethod {
private static EnhancedLinkMovementMethod sInstance;
private static Rect sLineBounds = new Rect();
public static MovementMethod getInstance() {
if (sInstance == null) {
sInstance = new EnhancedLinkMovementMethod();
}
return sInstance;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int index = getCharIndexAt(widget, event);
if (index != -1) {
ClickableSpan[] link = buffer.getSpans(index, index, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
}
else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
}
return true;
}
}
/*else {
Selection.removeSelection(buffer);
}*/
}
return super.onTouchEvent(widget, buffer, event);
}
private int getCharIndexAt(TextView textView, MotionEvent event) {
// get coordinates
int x = (int) event.getX();
int y = (int) event.getY();
x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();
x += textView.getScrollX();
y += textView.getScrollY();
/*
* Fail-fast check of the line bound.
* If we're not within the line bound no character was touched
*/
Layout layout = textView.getLayout();
int line = layout.getLineForVertical(y);
synchronized (sLineBounds) {
layout.getLineBounds(line, sLineBounds);
if (! sLineBounds.contains(x, y)) {
return -1;
}
}
// retrieve line text
Spanned text = (Spanned) textView.getText();
int lineStart = layout.getLineStart(line);
int lineEnd = layout.getLineEnd(line);
int lineLength = lineEnd - lineStart;
if (lineLength == 0) {
return -1;
}
Spanned lineText = (Spanned) text.subSequence(lineStart, lineEnd);
// compute leading margin and subtract it from the x coordinate
int margin = 0;
LeadingMarginSpan[] marginSpans = lineText.getSpans(0, lineLength, LeadingMarginSpan.class);
if (marginSpans != null) {
for (LeadingMarginSpan span : marginSpans) {
margin += span.getLeadingMargin(true);
}
}
x -= margin;
// retrieve text widths
float[] widths = new float[lineLength];
TextPaint paint = textView.getPaint();
paint.getTextWidths(lineText, 0, lineLength, widths);
// scale text widths by relative font size (absolute size / default size)
final float defaultSize = textView.getTextSize();
float scaleFactor = 1f;
AbsoluteSizeSpan[] absSpans = lineText.getSpans(0, lineLength, AbsoluteSizeSpan.class);
if (absSpans != null) {
for (AbsoluteSizeSpan span : absSpans) {
int spanStart = lineText.getSpanStart(span);
int spanEnd = lineText.getSpanEnd(span);
scaleFactor = span.getSize() / defaultSize;
int start = Math.max(lineStart, spanStart);
int end = Math.min(lineEnd, spanEnd);
for (int i = start; i < end; i++) {
widths[i] *= scaleFactor;
}
}
}
// find index of touched character
float startChar = 0;
float endChar = 0;
for (int i = 0; i < lineLength; i++) {
startChar = endChar;
endChar += widths[i];
if (endChar >= x) {
// which "end" is closer to x, the start or the end of the character?
int index = lineStart + (x - startChar < endChar - x ? i : i + 1);
//Logger.e(Logger.LOG_TAG, "Found character: " + (text.length()>index ? text.charAt(index) : ""));
return index;
}
}
return -1;
}
}
Просто добавь android:autoLink="web"
в ваш XML-файл, внутри вашего TextView
TextView textView = (TextView) view.findViewById(R.id.textview); SpannableString linkText= new SpannableString("linkText"); linkText.setSpan(new UnderlineSpan(), 0, linkText.length(), 0); textView.setText(LinkText);
Этот код выше сделает ваше текстовое представление подчеркнутым как ссылка. Сейчас используется неявное намерение.
Intent i = новый Intent (это,Intent.ACTION_VIEW); i.setData(Uri.parse("ваш http-URL"));
startActivity (я);
Попробуй это:
textView.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v)
{
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(textView.getText().toString()));
startActivity(browserIntent);
}
});