0

バックグラウンド

再投稿だと言う前に、他の投稿を読んでみましたので、読み続けてください。

textView 内にリンクを表示する基本的な方法は、次の方法で実行できます。

final Spanned text = Html.fromHtml(getString(R.string.test));
textView.setText(text);
textView.setMovementMethod(LinkMovementMethod.getInstance());

また、string.xml ファイルには以下を含めることができます。

<string name="test" formatted="false">
<![CDATA[
        This<br />
        is<br />
        <<a href="http://www.google.com">a</a><br />
        test
        ]]>
    </string>

ただし、リンクをクリックしたイベントをキャプチャして、自分で処理したい場合があります。それだけでなく、リンクは実際の URL である必要はありません。

それを行う方法を示すために多くの投稿が存在しますが、私が試したものはどれもうまく処理できませんでした。

インテントをアプリで処理できるものもありますが、これは非常に面倒で、他のアプリでも処理できる可能性があります (そうですか?)。リンクが特定のパターンにある必要があると思います。

一部は LinkMovementMethod に処理させますが、リンクのクリック可能性効果を台無しにします。色を何かに変えると言う人もいますが、それは同じではありません。

問題

どのテキスト領域がクリックされたかを知らせるリスナーを textview に追加するにはどうすればよいでしょうか?

私が試したこと

現在、私は LinkMovementMethod を使用しています。私のコードの問題は次のとおりです。

  • 通常のリンクのようにクリックを模倣する方法がわからないため、クリックすると奇妙に見えます。背景が正しく見えません。デバイスのデフォルトのものを使用する必要があると思いますが、方法がわかりません。一部の人が言うかもしれないことに反対するように、それは次のコードを使用することによるものではありません:

textview.getLinkTextColors().getDefaultColor()

  • 場合によっては、テキストがクリックされたままになることがあります。

コードは次のとおりです。

MainActivity.java (使い方のサンプル)

public class MainActivity extends Activity {

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final String a = "<a href='/a'>aaaa</a>123456<a href='/b'>bbbb</a>7890";
        final TextView textView = (TextView) findViewById(R.id.span);
        textView.setText(Html.fromHtml(a));
        final LinkClickMovementMethodExt linkMovementMethod = new LinkClickMovementMethodExt();
        linkMovementMethod.setOnLinkClickedListener(new OnLinkClickedListener() {

            @Override
            public void onLinkClicked(final TextView clickedTextView, final URLSpan clickedSpan) {
                Toast.makeText(MainActivity.this, clickedSpan.getURL(), Toast.LENGTH_SHORT).show();
            }
        });
        textView.setMovementMethod(linkMovementMethod);
    }

}

LinkClickMovementMethodExt.java

/** a class to handle clicking on links of textViews . based on http://stackoverflow.com/a/16182500/878126 */
public class LinkClickMovementMethodExt extends LinkMovementMethod {
    // TODO check how to get the default background of a clicked link
    private final BackgroundColorSpan LINK_COLOR = new BackgroundColorSpan(0xFFACE0F4);
    private final Class<URLSpan> spanClass = URLSpan.class;
    private OnLinkClickedListener mOnLinkClickedListener;

    public interface OnLinkClickedListener {
        public void onLinkClicked(TextView textView, URLSpan clickedSpan);
    }

    @Override
    public boolean onTouchEvent(final TextView textView, final Spannable buffer, final MotionEvent event) {
        final int action = event.getAction();

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= textView.getTotalPaddingLeft();
            y -= textView.getTotalPaddingTop();

            x += textView.getScrollX();
            y += textView.getScrollY();

            final Layout layout = textView.getLayout();
            final int line = layout.getLineForVertical(y);
            final int off = layout.getOffsetForHorizontal(line, x);
            /**
             * get you interest span
             */
            final Object[] spans = buffer.getSpans(off, off, spanClass);
            if (spans.length != 0) {
                if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(spans[0]), buffer.getSpanEnd(spans[0]));
                    for (final Object span : spans) {
                        if (span instanceof URLSpan) {
                            final int start = Selection.getSelectionStart(textView.getText());
                            final int end = Selection.getSelectionEnd(textView.getText());
                            final Spannable selectedSpan = (Spannable) textView.getText();
                            selectedSpan.setSpan(LINK_COLOR, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                            textView.setText(selectedSpan);
                            if (mOnLinkClickedListener != null)
                                mOnLinkClickedListener.onLinkClicked(textView, (URLSpan) span);
                        }
                    }
                    return false;
                } else if (action == MotionEvent.ACTION_UP) {
                    final Spannable span = (Spannable) textView.getText();
                    span.removeSpan(LINK_COLOR);
                    textView.setText(span);
                    return false;
                }
            }
        }
        return super.onTouchEvent(textView, buffer, event);
    }

    @Override
    public boolean canSelectArbitrarily() {
        return true;
    }

    @Override
    public boolean onKeyUp(final TextView widget, final Spannable buffer, final int keyCode, final KeyEvent event) {
        return false;
    }

    public void setOnLinkClickedListener(final OnLinkClickedListener onLinkClickedListener) {
        this.mOnLinkClickedListener = onLinkClickedListener;
    }
}
4

1 に答える 1

0

XML の場合:

<TextView
    android:id="@+id/msgtext"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dip"
    android:linksClickable="true"
    android:textColor="#000000"
    android:textColorLink="#EE4E1D"
    android:text="TextView" />

Java の場合:

TextView tvmsg = (TextView)textEntryView.findViewById(R.id.msgtext);
         tvmsg.setMovementMethod(LinkMovementMethod.getInstance());
         tvmsg.setText(Html.fromHtml(message));
于 2013-10-28T05:43:25.507 に答える