読者です 読者をやめる 読者になる 読者になる

TextViewのAutoLinkのURL起動先を、デフォルトブラウザでなく独自のActivityにする

基本的にはLinkMovementMethodの一部ソースをコピったあと、ブラウザに飛ばすであろう箇所のコードを削除し、自分でIntentを書けばOK。あまりいい解決法とも思えないが・・・

MainActivity.java

.
.
.
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = (TextView) findViewById(R.id.text_view);
        tv.setMovementMethod(MyLinkMovementMethod.getInstance());
    }
.
.
.

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    <TextView
        android:id="@+id/text_view"
        android:autoLink="web"
        android:text="hello, www.google.com world."
        android:textColorLink="@android:color/holo_red_dark"
        android:textColorHighlight="@android:color/holo_red_light"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

MyLinkMovementMethod.java

package com.tatuas.textview.link.sample;

import android.content.Context;
import android.content.Intent;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.MotionEvent;
import android.widget.TextView;

import com.tatuas.textview.link.sample.MyBrowserActivity;

public class MyLinkMovementMethod extends LinkMovementMethod {
    private static MyLinkMovementMethod sInstance;

    public static MyLinkMovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new MyLinkMovementMethod();
        }
        return sInstance;
    }

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

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

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

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

            Layout layout = widget.getLayout();
            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) {
                    /*
                     * Delete this code
                     */
                    //link[0].onClick(widget);

                    /*
                     * Write your custom logic
                     */
                    if (link[0] instanceof URLSpan) {
                        String url = ((URLSpan) link[0]).getURL();
                        Context context = widget.getContext();
                        Intent intent = new Intent(context, MyBrowserActivity.class);
                        intent.putExtra("bundle_key_link_url", url);
                        context.startActivity(intent);
                    }
                } else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer,
                            buffer.getSpanStart(link[0]),
                            buffer.getSpanEnd(link[0]));
                }

                return true;
            } else {
                Selection.removeSelection(buffer);
            }
        }

        return super.onTouchEvent(widget, buffer, event);
    }
}

なお、TextViewのオプションで、textColorLinkでリンクそのものの色を、textColorHighLightでリンクを押した時の色を、それぞれ変えられる。