0

Is there a simple way of creating custom links and handling their 'on touch' behavior for Android TextView component?

I did't find any solution in the Internet, but came with my own.

Yan
  • 1,569
  • 18
  • 22
  • Does [linkify](https://stackoverflow.com/questions/4746293/android-linkify-textview) solve your problem? – isabsent Sep 03 '17 at 15:15
  • In case of Linkify you have to implement your own schema and still you will need to override Linkmovement method or writing your own in order to react to touch events. The method below uses the framework's Html wrapper, which is quite convenient, i think. – Yan Sep 04 '17 at 06:23

1 Answers1

2

There is a simple way of creating custom links for textview and handling their behavior as a result of touch event. In order to avoid composing and writing your own pattern wrapper, the Html wrapper is used.

    TextView tView = ((TextView)v.findViewById(R.id.otp_activation_notification));
    Spanned ssBuilder =  Html.fromHtml("Not a link <a href=\"foo://haha/arg1/arg2?q1=1&q2=2\">The first link</a> bla bla "
    + " <a href=\"foo://haha2?q3=3\">The second link</a>");
    tView.setText(ssBuilder);
    tView.setMovementMethod(new LinkMovementMethod(){

        @Override
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            //TODO: In order to override the links actions
            int x = (int) event.getX();
            int y = (int) event.getY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            try {
                URLSpan[] urlSpans = buffer.getSpans(off, off, URLSpan.class);
                if (urlSpans != null && urlSpans.length > 0) {
                    Uri uri = Uri.parse(urlSpans[0].getURL());
                    String scheme = uri.getScheme();
                    if ("foo".equals(scheme)) {
                        String command = uri.getAuthority();
                        if ("haha".equals(command)) {
                            List<String> arguments = uri.getPathSegments();
                            String q1 = uri.getQueryParameter("q1");
                            String q2 = uri.getQueryParameter("q2");
                            //TODO: Execute command (pay attention for MotionEvent)
                            return true;
                        } else if ("haha2".equals(command)) {
                            String q3 = uri.getQueryParameter("q2");
                            //TODO: Execute command2 (pay attention for MotionEvent)
                            return true;
                        }
                        return false;
                    }
                }
            } catch (Exception e) {
                //Log: unable to parse link;
            }
            //return false in case you don't want to use default behavior.
            return super.onTouchEvent(widget, buffer, event);

        }
    });
Yan
  • 1,569
  • 18
  • 22