Android: Linkify TextView

У меня есть textview, который мне нужно связать. Вот что я делаю.

TextView text = (TextView) view.findViewById(R.id.name);
text.setText("Android...Update from Android");
Pattern pattern = Pattern.compile("Android");
String scheme = "www.android.com";
Linkify.addLinks(text, pattern, scheme);

Текстовый вид отображается правильно с текстом "Android... Обновление с Android", но у меня две проблемы.

1) Моя текстовая строка содержит два экземпляра строки "Android". Таким образом, оба текста связаны. Я хочу, чтобы только первое возникновение было связано. Как мне это сделать?

2) Когда я нажимаю ссылку linkfy, он открывает браузер, но URL-адрес странный. URL-адрес, который он пытается открыть, - "www.comandroid". Я не знаю, что здесь происходит. Текст "андроид" в URL-адресе заменяется. Я делаю что-то неправильно, когда Linknifying текст.

Любая помощь будет высоко оценена.

Ответ 1

Легкий способ поместить autoLink в макет XML.

  android:autoLink="web" 

Ответ 2

Я создал статический метод, который делает это просто:

/**
 * Add a link to the TextView which is given.
 * 
 * @param textView the field containing the text
 * @param patternToMatch a regex pattern to put a link around
 * @param link the link to add
 */
public static void addLink(TextView textView, String patternToMatch,
        final String link) {
    Linkify.TransformFilter filter = new Linkify.TransformFilter() {
        @Override public String transformUrl(Matcher match, String url) {
            return link;
        }
    };
    Linkify.addLinks(textView, Pattern.compile(patternToMatch), null, null,
            filter);
}

И OP мог бы использовать его просто:

addLink(text, "^Android", "http://www.android.com");

Ответ 3

У меня нет большого опыта работы с Linkify. Пока все, что я хотел сделать, это сделать URL-адреса в тексте ссылками, которые обрабатываются автоматически другой версией addLinks.

Однако регулярное выражение, которое вы используете для сопоставления на "Android", можно изменить так, чтобы оно соответствовало тому, которое запускает строку, настраивая ваше регулярное выражение:

Pattern pattern = Pattern.compile("^Android");

Обратите внимание на добавление '^'. Это говорит правилу регулярного выражения, чтобы он соответствовал шаблону "Android", когда он запускает строку. Если это будет работать с вашими строками, тогда отлично. Если у вас есть другие случаи, слово, которое вы хотите связать, находится не в начале строки, вам нужно будет еще раз изучить регулярные выражения. Я рекомендую этот сайт узнать больше regular-expressions.info

Ответ 4

Если вы хотите открыть все URL-адреса, которые содержатся в тексте, вы можете сделать это.

            TextView textview=(TextView)findViewById(R.id.text);

    textview.setText("Android....Update from android...www.android.com");
    Linkify.addLinks(textview, Linkify.WEB_URLS);
    textview.setMovementMethod(LinkMovementMethod.getInstance());

Он может работать для всех URL-адресов.

Ответ 5

Здесь, из ответа Shawns и комментария SpunkerBaba, я вышел с этим вспомогательным классом. Это останавливает проблему двойного добавления того, что вы меняете, добавляя к вашему URL-адресу.

package com.your.package;

public class Linkify {

    /**
     * @param textView
     *            textView who text you want to change
     * @param linkThis
     *            a regex of what text to turn into a link
     * @param toThis
     *            the url you want to send them to
     */
    public static void addLinks(TextView textView, String linkThis, String toThis) {
        Pattern pattern = Pattern.compile(linkThis);
        String scheme = toThis;
        android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() {
            @Override
            public boolean acceptMatch(CharSequence s, int start, int end) {
                return true;
            }
        }, new TransformFilter() {

            @Override
            public String transformUrl(Matcher match, String url) {
                return "";
            }
        });
    }

}

Useage:

 Linkify.addLinks(profileTextView, "BlundellApps.com", "http://www.BlundellApps.com");

Ответ 6

Я думаю, что вам действительно нужно что-то простое:

final TextView textView = ((BodyViewHolder) holder).textView;
textView.setText(text);
Linkify.addLinks(textView, Linkify.WEB_URLS); // I would do this only during view creation, btw.

Вы отслеживаете URL-адрес. Некоторые люди предлагают использовать Linkigy.ALL, но вы этого не хотите:

public static final int ALL = WEB_URLS | EMAIL_ADDRESSES | PHONE_NUMBERS | MAP_ADDRESSES;

Кроме того, другие люди предлагают добавить:

textview.setMovementMethod(LinkMovementMethod.getInstance());

после добавления правил ссылки, но addLinks уже делает это в своих внутренностях; -)

Ура!

Ответ 7

Для Koltin с лямбда-выражением это будет так:

val pattern = Pattern.compile(link.title)
Linkify.addLinks(view, pattern, null, null, { matcher, url -> link.href })

Ответ 8

Проблема решена. Решение первой проблемы - это ответ, предоставленный Яном Лесли. Решение второй проблемы заключается в следующем. Поведение API "Linkify.addLinks" таково, что оно добавляет строку, которую вы хотите связать с концом URL. Для ex..если вы хотите связать текст "Android" с "www.android.com". Конечный URL-адрес "www.android.comAndroid", который не то, что мне нужно. Так я использовал

public static final void addLinks (TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter)
TransformFilter transformFilter = new TransformFilter() {
public final String transformUrl(final Matcher match, String url) { 
return ""; 
} }; 

Api transformFilter возвращает пустую строку. Поэтому мой окончательный URL-адрес "www.android.com"

Ответ 9

TextView noteView = (TextView) findViewById(R.id.noteview);
noteView.setText(someContent);
Linkify.addLinks(noteView, Linkify.ALL);

Ответ 10

 Linkify.addLinks(yourTextView, yourPattern, linkToGoto, null, 
       new Linkify.TransformFilter() {
          @Override
          public String transformUrl(Matcher match, String url) {
           return "";
          }
       });