2015-05-26 1 views
4

У меня есть RecyclerView с TextViews, который может содержать пользовательские хэштеги, которые должны быть доступны для кликов. Поэтому я создал подкласс TextView, в котором с помощью шаблона я создаю ClickableSpan. Для того, чтобы ClickableSpan быть активным, я добавилПереадресовать событие касания на TextView с ClickableSpan на родительский вид

setMovementMethod(LinkMovementMethod.getInstance()) 

Этот метод изменяет свойства TextView:

setFocusable(true); 
setClickable(true); 
setLongClickable(true); 

Нажмите на ссылках работает, но он предотвращает пульсацию вытяжки будет показан на элементе списка, и нажмите «TextView» вне хэштегов, игнорируются.

Так что мне интересно, как я могу перенаправить касания TextView (все, кроме хэштега) к его родительскому?

ответ

1

Так что я не нашел решение в Интернете, поэтому я в конечном итоге реализовал его сам.

Таким образом, вместо использования простого TextView с MovementMethod, я создал новый класс, расширяющий текстовое представление с помощью onTouchEvent.

public class MyTextView extends TextView { 
@Override 
    public boolean onTouchEvent(@NonNull MotionEvent event) { 
    if (linksActive) { 
     Layout layout = this.getLayout(); 
     if (layout != null) { 
     int line = layout.getLineForVertical((int) event.getY()); 
     int offset = layout.getOffsetForHorizontal(line, event.getX()); 

     if (getText() != null && getText() instanceof Spanned) { 
      Spanned spanned = (Spanned) getText(); 

      ClickableSpan[] links = spanned.getSpans(offset, offset, ClickableSpan.class); 

      if (links.length > 0) { 

      if (event.getAction() == MotionEvent.ACTION_DOWN) { 
       return true; 
      } else if (event.getAction() == MotionEvent.ACTION_UP) { 
       links[0].onClick(this); 
      } else { 
       return super.onTouchEvent(event); 
      } 
      } 
     } 
     } 
    } 

    return super.onTouchEvent(event); 
    } 
} 

Кроме того, я создал класс, который расширяет ClickableSpan, который обрабатывает щелчки:

public class URLSpan extends ClickableSpan { 
    private String url; 
    private int spanType; 

    public URLSpan(String url, int spanType) { 
    this.url = url; 
    this.spanType = spanType; 
    } 

    public int getType() { 
    return spanType; 
    } 

    @Override 
    public void onClick(@NonNull View widget) { 
    if (widget instanceof OnSpanClickListener) { 
     ((OnSpanClickListener) widget).onSpanClicked(url, type); 
    } else { 
     // ignored 
    } 
    } 

} 

И в этом случае я должен управлять пролеты самостоятельно (в setText() методом)

public static void formatPhoneNumbers(@NonNull Spannable spannable, @ColorInt int color) { 
    Matcher matcher = MY_Patterns.PHONE_NO.matcher(spannable); 
    while (matcher.find()) { 
     if (!Linkify.sPhoneNumberMatchFilter.acceptMatch(spannable, matcher.start(), matcher.end())) { 
     continue; 
     } 

     removeSpans(spannable, SpanType.PHONE_NO, matcher.start(), matcher.end()); 

     if (hasClickableSpans(spannable, matcher.start(), matcher.end())) { 
     // ignore different clickable spans overlap 
     continue; 
     } 

     final ForegroundColorSpan span = new ForegroundColorSpan(color); 
     final ClickableSpan urlSpan = new URLSpan(matcher.group(), SpanType.PHONE_NO); 

     spannable.setSpan(urlSpan, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
     spannable.setSpan(span, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
    } 
    } 

    private static void removeSpans(@NonNull Spannable spannable, int type, int start, int end) { 
    URLSpan[] arr = spannable.getSpans(start, end, URLSpan.class); 
    for (URLSpan span : arr) { 
     if (span.getType() == type) { 
     spannable.removeSpan(span); 
     } 
    } 
    } 

    private static boolean hasClickableSpans(@NonNull Spannable spannable, int start, int end) { 
    ClickableSpan[] arr = spannable.getSpans(start, end, ClickableSpan.class); 
    return arr.length > 0; 
    } 
+0

у меня есть та же проблема, Это решение уже работает? Не могли бы вы поставить onClick на родителя (и эффект пульсации) вместо TextView? –

+0

когда вы устанавливаете ссылкиActive? – kenyee

+0

Я добавил это свойство как атрибут xml, а также добавил общедоступный набор для этого класса –