| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.weex.ui.component.richtext; |
| |
| import android.annotation.SuppressLint; |
| import android.content.Context; |
| import android.graphics.drawable.Drawable; |
| import android.text.Layout; |
| import android.text.Selection; |
| import android.text.Spannable; |
| import android.text.Spanned; |
| import android.text.style.ClickableSpan; |
| import android.view.MotionEvent; |
| import android.widget.TextView; |
| |
| import org.apache.weex.ui.component.richtext.span.ImgSpan; |
| import org.apache.weex.ui.view.WXTextView; |
| |
| public class WXRichTextView extends WXTextView { |
| |
| public WXRichTextView(Context context) { |
| super(context); |
| } |
| |
| @SuppressLint("ClickableViewAccessibility") |
| @Override |
| public boolean onTouchEvent(MotionEvent event) { |
| boolean superResult = super.onTouchEvent(event); |
| boolean handled = false; |
| if (isEnabled() && getTextLayout() != null && getText() instanceof Spannable) { |
| Spannable spannable = (Spannable) getText(); |
| handled = updateSelection(event, spannable); |
| } |
| return handled || superResult; |
| } |
| |
| @Override |
| protected boolean verifyDrawable(Drawable who) { |
| super.verifyDrawable(who); |
| return true; |
| } |
| |
| @Override |
| public void setTextLayout(Layout layout) { |
| super.setTextLayout(layout); |
| if (layout.getText() instanceof Spanned) { |
| Spanned spanned = (Spanned) layout.getText(); |
| ImgSpan[] imgSpan = spanned.getSpans(0, spanned.length(), ImgSpan.class); |
| if (imgSpan != null) { |
| for (ImgSpan span : imgSpan) { |
| span.setView(this); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Mostly copied from |
| * {@link android.text.method.LinkMovementMethod#onTouchEvent(TextView, Spannable, MotionEvent)}. |
| */ |
| private boolean updateSelection(MotionEvent event, Spannable buffer) { |
| int action = event.getActionMasked(); |
| |
| if (action == MotionEvent.ACTION_UP || |
| action == MotionEvent.ACTION_DOWN) { |
| int x = (int) event.getX(); |
| int y = (int) event.getY(); |
| |
| x -= getPaddingLeft(); |
| y -= getPaddingTop(); |
| |
| x += getScrollX(); |
| y += getScrollY(); |
| |
| Layout layout = getTextLayout(); |
| int line = layout.getLineForVertical(y); |
| int off = layout.getOffsetForHorizontal(line, x); |
| |
| ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); |
| |
| if (link.length != 0) { |
| if (action == MotionEvent.ACTION_UP) { |
| link[0].onClick(this); |
| } else { |
| Selection.setSelection(buffer, |
| buffer.getSpanStart(link[0]), |
| buffer.getSpanEnd(link[0])); |
| } |
| |
| return true; |
| } else { |
| Selection.removeSelection(buffer); |
| } |
| } |
| |
| return false; |
| } |
| |
| |
| } |