Custom Urlspan doesn't react on click

1.6k views Asked by At

I have made a custom URL span to use the chrome custom tab to open a link. The links are getting displayed correctly, I use the Html.fromHtml() function.

In the activity I use this for the TextView:

content_txt_view = (TextView)findViewById(R.id.textView_news);
content_txt_view.setTransformationMethod(new LinkTransformationMethod());
content_txt_view.setMovementMethod(LinkMovementMethod.getInstance());

The linkstransformation class looks like this:

public class LinkTransformationMethod implements TransformationMethod {

    @Override
    public CharSequence getTransformation(CharSequence source, View view) {
        if (view instanceof TextView) {

            TextView textView = (TextView) view;
          //  Linkify.addLinks(textView, Linkify.WEB_URLS);
            if (textView.getText() == null || !(textView.getText() instanceof Spannable)) {
                return source;
           }
            Spannable text= new SpannableString(textView.getText());
            URLSpan[] spans = text.getSpans(0, textView.length(), URLSpan.class);
            for (int i = spans.length - 1; i >= 0; i--) {
                URLSpan oldSpan = spans[i];
                int start = text.getSpanStart(oldSpan);
                int end = text.getSpanEnd(oldSpan);
                String url = oldSpan.getURL();
                text.removeSpan(oldSpan);
                text.setSpan(new CustomTabsURLSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
            return text;
        }
        return source;
    }

and the custom url span:

public class CustomTabsURLSpan extends URLSpan {
    private Context context;


    public CustomTabsURLSpan(String url) {

        super(url);
        Log.d("SensibleUrlSpan", "1");
    }

    public CustomTabsURLSpan(Parcel src) {
        super(src);
        Log.d("SensibleUrlSpan", "2");
    }

    @Override
    public void onClick(View widget) {
        Log.d("SensibleUrlSpan", "3");
        String url = getURL();
        Toast toast = Toast.makeText(context, "well done! you click ", Toast.LENGTH_SHORT);
        toast.show();
        // String url = "http://www.google.com";

    }
}

I would have expected that when I click on the link, I will get the toast message...But it seems the OnClick method is not called at all.

1

There are 1 answers

0
andreban On

The classes below implement the desired behaviour:

CustomClickURLSpan.java

import android.text.style.URLSpan;
import android.view.View;

public class CustomClickURLSpan extends URLSpan {
    private OnClickListener mOnClickListener;

    public CustomClickURLSpan(String url) {
        super(url);
    }

    public void setOnClickListener(OnClickListener onClickListener) {
        mOnClickListener = onClickListener;
    }

    @Override
    public void onClick(View widget) {
        if (mOnClickListener == null) {
            super.onClick(widget);
        } else {
            mOnClickListener.onClick(widget, getURL());
        }
    }

    public interface OnClickListener {
        void onClick(View view, String url);
    }
}

CustomTabsOnClickListener.java

import android.app.Activity;
import android.net.Uri;
import android.support.customtabs.CustomTabsIntent;
import android.view.View;

import java.lang.ref.WeakReference;

public class CustomTabsOnClickListener implements CustomClickURLSpan.OnClickListener {
    private WeakReference<Activity> mActivityWeakReference;
    private WeakReference<CustomTabActivityHelper> mCustomTabActivityHelperWeakReference;

    public CustomTabsOnClickListener(Activity hostActivity,
                                     CustomTabActivityHelper customTabActivityHelper) {
        mActivityWeakReference = new WeakReference<>(hostActivity);
        mCustomTabActivityHelperWeakReference = new WeakReference<>(customTabActivityHelper);
    }

    @Override
    public void onClick(View view, String url) {
        Activity activity = mActivityWeakReference.get();
        CustomTabActivityHelper customTabActivityHelper =
                mCustomTabActivityHelperWeakReference.get();
        if (activity != null && customTabActivityHelper != null) {
            CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(null)
                    .build();
            customTabsIntent.intent.setPackage(
                    CustomTabsHelper.getPackageNameToUse(view.getContext()));
            customTabsIntent.launchUrl(activity, Uri.parse(url));
        }
    }
}

A Utility class with the linkifyUrl methods that creates Spans for the URLs

import android.text.Spannable;
import android.text.Spanned;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Util {
    private static final Pattern URL_PATTERN = Pattern.compile("((http|https|rstp):\\/\\/\\S*)");

    public static void linkifyUrl(
            Spannable spannable, CustomClickURLSpan.OnClickListener onClickListener) {
        Matcher m = URL_PATTERN.matcher(spannable);
        while (m.find()) {
            String url = spannable.toString().substring(m.start(), m.end());
            CustomClickURLSpan urlSpan = new CustomClickURLSpan(url);
            urlSpan.setOnClickListener(onClickListener);
            spannable.setSpan(urlSpan, m.start(), m.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
}

Finally, invoke those classes to linkify the text:

TextView content = (TextView)findViewById(R.id.content);
Spannable spannable = new SpannableString(post.getText());
Util.linkifyUrl(spannable, new CustomTabsOnClickListener(this, mCustomTabActivityHelper));
content.setText(spannable);
content.setMovementMethod(LinkMovementMethod.getInstance());

The helper classes used are available on the Github Demo: CustomTabsHelper and CustomTabsActivityHelper