Добавление OnTouch и OnClickListener к ссылкам в TextView и изменение цвета фона ссылки

У меня есть текстовое представление и ссылки в нем. Я хочу, чтобы ссылки выделялись, когда я их касаюсь, а также я хочу открыть Alertdialog, когда я их долго щелкаю. Я попытался найти решение, настроив URLSpan, но, поскольку я не могу получить доступ к mView до вызова OnClick, я не могу настроить слушателей:

class ConfirmSpan extends URLSpan{
    View mView;
    URLSpan span;

    public ConfirmSpan(URLSpan span) {
        super(span.getURL());
        this.span = span;

      //there is a nullpointerexception here since mView is null now.
        mView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                ((TextView)v).setBackgroundColor(0xcccccccc);
                return false;
            }
        });

      //this is also an exception
        mView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {

                Log.d("INFO","long click yay!");
                return false;
            }
        });
    }

  //this should be called to reach the view. But then I can't handle touch state.
    @Override
    public void onClick(View widget) {
        mView = widget;

        //bla bla..
    }

    public void openURL() {
        super.onClick(mView);
    }

}

Я думаю, что я должен настроить класс LinkMovementMethod, но как? Любой комментарий будет оценен. ОБНОВЛЕНИЕ: теперь я могу обрабатывать событие касания с этим кодом:

public class CustomLinkMovementMethod extends LinkMovementMethod {
private static CustomLinkMovementMethod sInstance;

@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
    // Here I am changing backgorund color
    if(event.getAction() == MotionEvent.ACTION_DOWN)
        widget.setBackgroundColor(0xcccccccc);
    if(event.getAction() == MotionEvent.ACTION_UP)
        widget.setBackgroundColor(0xffffffff);
    return super.onTouchEvent(widget, buffer, event);
}
public static MovementMethod getInstance() {
    if (sInstance == null)
        sInstance = new CustomLinkMovementMethod();

    return sInstance;
}

}

Но TextView с именем виджет, параметр OnTouchEvent(), не то, что я хочу. Это весь текст. Поэтому, когда я нажимаю на ссылку, текст становится серым. Я думаю, что мне нужны некоторые другие методы, такие как окрашивание фона ссылки путем нахождения координат начальной и конечной линий ссылки.

1 ответ

Решение

Спасибо, что задали этот вопрос. Думаю, у меня есть решение для вас.

Проверьте код в https://gist.github.com/qtyq/90f9b4894069a8b3676c

Это вспомогательный класс фабрики для SpannableString, который позволяет вам легко создать SpannableString:

  1. передача исходной строки в метод static (String s)
  2. вызов метода makeLink(...) для превращения нужной подстроки в ссылку
  3. при необходимости вызывая другие методы, такие как makeBold(...) (который уже вызывается в makeLink) или setColor(...), чтобы настроить внешний вид
  4. и, наконец, вызов метода create() для создания объекта SpannableString, который вы можете просто применить к своему textView с помощью setText(...).

Вот пример его использования:

SpannableString ss = SpannableBuilder.init(bottomText)
        .setColor("Terms & Conditions", getResources().getColor(R.color.orange))
        .makeLink(getContext(), "Terms & Conditions", terms)
        .setColor("Privacy Policy", getResources().getColor(R.color.orange))
        .makeLink(getContext(), "Privacy Policy", policy)
        .create();
textView1.setText(ss);

И, конечно, вы можете настроить методы уже в этом классе или добавить свои собственные, если вам нужна дополнительная настройка, просто прочитайте документацию Google для SpannableString для получения дополнительной информации о том, что вы можете сделать.

Другие вопросы по тегам