13

How can I open TextView's links into WebView when I click on links of TextView.

dove
  • 20,469
  • 14
  • 82
  • 108
Saki Make
  • 259
  • 1
  • 6
  • 16

5 Answers5

30
Spanned spanned = Html.fromHtml("<a href=\"http://google.com\">google.com</a>");
textView.setText(spanned);

EDIT: That's not an ideal way to handle clicks on a link, but I don't know any other way.

Your main activity contains a TextView with a link. The link URL has a custom scheme.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TextView link = (TextView)findViewById(R.id.link);
        link.setText(
            Html.fromHtml("<a href='myscheme://www.google.com'>link</a>"));
        link.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

When this link is clicked Android starts an Activity with ACTION_VIEW using the link URL. Let's assume you have a WebViewActivity which handles URIs with this custom scheme. It gets the passed URI and replaces its scheme with http.

public class WebViewActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );

        if( savedInstanceState == null ) {
            String url =
                getIntent().getDataString().replace("myscheme://", "http://");
            // do something with this URL.
        }
    }
}

To handle custom URI schemes WebViewActivity must have an intent filter in the AndroidManifest.xml file:

<activity android:name=".WebViewActivity" android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="myscheme" />
    </intent-filter>
</activity>
Michael
  • 53,859
  • 22
  • 133
  • 139
  • Thanks Pixie, But it will open in default browser not in WebView. :( – Saki Make Aug 31 '11 at 09:57
  • 1
    Oh, I misunderstood your question. In this case you can create an URL with your own schema and register it with an intent filter in the AndroidManifest.xml. – Michael Aug 31 '11 at 10:02
  • Thank You Again, But can you explain it little bit more. – Saki Make Aug 31 '11 at 10:08
  • @Michael, what if I fetch the text from the web and I can't modify the scheme? – X09 May 14 '16 at 10:55
  • @Ozuf What do you mean you can't? You can always create a link with a custom scheme and add another link to it as a query parameter. Then when handling this URI you can extract the inner link and open it in the `WebView`. – Michael May 14 '16 at 14:56
  • @Michael: I fetch the text from external source (web), and the url is handed down to me. Please, how can I modify the scheme? – X09 May 14 '16 at 14:59
1

Following worked for me. I just used the onTouchEvent code from LinkMovementMethod. You set the link in textView as Michael mentioned above or you can set it in strings.xml. I use this library for opening links https://github.com/DreaminginCodeZH/CustomTabsHelper.

textView.setMovementMethod(new MovementMethod() {
        @Override
        public void initialize(TextView widget, Spannable text) {

        }

        @Override
        public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {
            return false;
        }

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

        @Override
        public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
            return false;
        }

        @Override
        public void onTakeFocus(TextView widget, Spannable text, int direction) {

        }

        @Override
        public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
            return false;
        }

        /**
         * Borrowed code for detecting and selecting link from
         * {@link LinkMovementMethod#onTouchEvent(TextView, Spannable, MotionEvent)}
         */
        @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) {
                        // do whatever else you want here on link being clicked
                        Selection.removeSelection(buffer);

                    } else if (action == MotionEvent.ACTION_DOWN) {
                        Selection.setSelection(buffer,
                                buffer.getSpanStart(link[0]),
                                buffer.getSpanEnd(link[0]));
                    }

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

            return false;
        }

        @Override
        public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {
            return false;
        }

        @Override
        public boolean canSelectArbitrarily() {
            return false;
        }
    });
Sohail
  • 1,137
  • 2
  • 12
  • 22
1

If you copy a Kotlin solution of nastylion, you can use it like:

textView.handleUrlClicks { url ->
    Timber.d("click on found span: $url")
    // Call WebView here.
}

Also you can see an article with its LinkMovementMethod and linkify, but it's too difficult (contains different masks and popup menus).

CoolMind
  • 26,736
  • 15
  • 188
  • 224
0

set the property android:autolink to your textview layout

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"        
    android:text="your text"
    android:autoLink="web" />
Raneez Ahmed
  • 3,808
  • 3
  • 35
  • 58
-3
hotel_website=(TextView)viewflipper.findViewById(R.id.tv_website);
hotel_website.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
    String url = "http://" +hotel_website.getText().toString();
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.setData(Uri.parse(url));
    startActivity(i);
   }
});

and in XML

<TextView
  android:clickable="true"
</TextView>
MilapTank
  • 9,988
  • 7
  • 38
  • 53
Nikhil Lamba
  • 593
  • 1
  • 6
  • 17