Textview onclicklistener with links

13,890

Solution 1

I do the hack for you, try this code!

EXPLANATION:

1.use customized ClickableSpan to handle click on url.

2.clickablespan will handle the click event before the textview, make a flag when a link is clicked.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView textView = (TextView) findViewById(R.id.main_text);
    textView.setMovementMethod(LinkMovementMethod.getInstance());

    CharSequence charSequence = textView.getText();
    SpannableStringBuilder sp = new SpannableStringBuilder(charSequence);

    URLSpan[] spans = sp.getSpans(0, charSequence.length(), URLSpan.class);

    for (URLSpan urlSpan : spans) {
        MySpan mySpan = new MySpan(urlSpan.getURL());
        sp.setSpan(mySpan, sp.getSpanStart(urlSpan),
                sp.getSpanEnd(urlSpan), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
    }

    textView.setText(sp);

    textView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // 2.if clicking a link
            if (!isClickingLink) {
                Log.w("log", "not clicking link");
            }
            isClickingLink = false;
        }
    });
}


private boolean isClickingLink = false;

private class MySpan extends ClickableSpan {

    private String mUrl;

    public MySpan(String url) {

        super();
        mUrl = url;
    }

    @Override
    public void onClick(View widget) {

        isClickingLink = true;
        // 1. do url click
    }

}

Solution 2

You could try modifying the onClickListener like mentioned here: Control onclicklistener in autolink enabled textview

texttv.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                             if(texttv.getSelectionStart()==-1&&texttv.getSelectionEnd()==-1){ 

                       // Method B

                             }

                    }
                });

Basically check where and when links start and end and only if you arent over the hyperlink, then call your method B , otherwise it anyway fires A on the links But this is just a workaround I guess

Docs here: http://developer.android.com/reference/android/text/Selection.html#getSelectionEnd(java.lang.CharSequence)

Share:
13,890
Simon
Author by

Simon

I'm a Computer Science and Engineering student at TU Delft in The Netherlands. Also, I work part time as a software engineer.

Updated on July 09, 2022

Comments

  • Simon
    Simon almost 2 years

    I have a textview with a html string with anchors in it. When I click the textview I want to call eg a method called A, and when I click a link in the textview I want to call a method called B. I got this working but I got a problem: when I click a link, method B is called, but method A is called too. How can I make sure only method B, and not B and A, is called when I click a link?

    My code:

    for (int i = 0; i < ingevoegd.length(); i++) {
            JSONObject soortingevoegd = ingevoegd.getJSONObject(i);
            String type = soortingevoegd.getString("type");         
            if (type.equals("Vis")) {
                String link = "<a href = 'com.aquariumzoeken.pro://Soortweergave?selected="
                        + naam + "&type=Vis" + "'>" + naam + "</a>";
                text = text.replaceAll(naam, link);
            }
        }
    
        TextView texttv = (TextView) v.findViewById(R.id.textviewer);   
    
    
        texttv.setText(Html.fromHtml(text));
        texttv.setMovementMethod(LinkMovementMethod.getInstance());
    

    And the textview onclicklistener:

    texttv.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
                try {
    
                    switchToEditMode sw = new switchToEditMode();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
            }
        });
    

    Thanks in advance, Simon