Control onclicklistener in autolink enabled textview

前端 未结 9 2600
一向
一向 2020-12-08 19:13

I am using a TextView for which I have set autolink=\"web\" property in XML file. I have also implemented the onClickListener for this TextView. Th

相关标签:
9条回答
  • 2020-12-08 19:28

    You can set the property android:linksClickable="false" in your TextView, in conjuction with android:autoLink="web"; this makes the links visible, but not clickable.

    0 讨论(0)
  • 2020-12-08 19:31

    Use textView.getSelectionStart() and textView.getSelectionEnd().If u click any text other than link textView.getSelectionStart() and textView.getSelectionEnd() will be -1 .So by using a if condition in onClickListner you can block the onClick action when link is clicked .

    //inside onClickListner
    
    if(textView.getSelectionStart()==-1&&textView.getSlectionEnd==-1){
    
        //onClick action
    }
    
    0 讨论(0)
  • 2020-12-08 19:32

    if you wish, you can use the next code which allows to customize the clickable links within the string ( based on this post ) :

    usage:

    final TextView textView = (TextView) findViewById(R.id.textView);
    final Spanned text = Html.fromHtml(getString(...));
    textView.setText(text);
    textView.setMovementMethod(new LinkMovementMethodExt());
    

    LinkMovementMethodExt.java

    public class LinkMovementMethodExt extends LinkMovementMethod {
        private static LinkMovementMethod sInstance;
    
        public static MovementMethod getInstance() {
            if (sInstance == null)
                sInstance = new LinkMovementMethodExt();
            return sInstance;
        }
    
        @Override
        public boolean onTouchEvent(final TextView widget, final Spannable buffer, final MotionEvent event) {
            final int action = event.getAction();
            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
                final int x = (int) event.getX() - widget.getTotalPaddingLeft() + widget.getScrollX();
                final int y = (int) event.getY() - widget.getTotalPaddingTop() + widget.getScrollY();
                final Layout layout = widget.getLayout();
                final int line = layout.getLineForVertical(y);
                final int off = layout.getOffsetForHorizontal(line, x);
                final ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
                if (link.length != 0) {
                    //do something with the clicked item...
                    return true;
                }
            }
            return super.onTouchEvent(widget, buffer, event);
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 19:33
    private void fixTextView(TextView tv) {
        SpannableString current = (SpannableString) tv.getText();
        URLSpan[] spans =
                current.getSpans(0, current.length(), URLSpan.class);
    
        for (URLSpan span : spans) {
            int start = current.getSpanStart(span);
            int end = current.getSpanEnd(span);
    
            current.removeSpan(span);
            current.setSpan(new DefensiveURLSpan(span.getURL()), start, end,
                    0);
        }
    }
    
    public static class DefensiveURLSpan extends URLSpan {
    
        public final static Parcelable.Creator<DefensiveURLSpan> CREATOR =
                new Parcelable.Creator<DefensiveURLSpan>() {
    
            @Override
            public DefensiveURLSpan createFromParcel(Parcel source) {
                return new DefensiveURLSpan(source.readString());
            }
    
            @Override
            public DefensiveURLSpan[] newArray(int size) {
                return new DefensiveURLSpan[size];
            }
    
        };
    
    private String mUrl;
    
    public DefensiveURLSpan(String url) {
        super(url);
        mUrl = url;
    }
    
        @Override
        public void onClick(View widget) {
            // openInWebView(widget.getContext(), mUrl); // intercept click event and do something.
            // super.onClick(widget); // or it will do as it is.
        }
    }
    

    You would then call fixTextView(textViewContent); on the view after it is declared (via inflation or findViewById) or added to the window (via addView)

    This includes the missing requirement to set a CREATOR when extending a Parcelable.

    It was proposed as an edit, but rejected. Unfortunately, now future users will have to find out the original one is incomplete first. Nice one, reviewers!

    0 讨论(0)
  • 2020-12-08 19:45

    You can achieve this using a work around in getSelectionStart() and getSelectionEnd() functions of the Textview class,

    tv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ClassroomLog.log(TAG, "Textview Click listener ");
            if (tv.getSelectionStart() == -1 && tv.getSelectionEnd() == -1) {
                //This condition will satisfy only when it is not an autolinked text
                //Fired only when you touch the part of the text that is not hyperlinked 
            }
        }
    });
    

    It may be a late reply, but may be useful to those who are searching for a solution.

    0 讨论(0)
  • 2020-12-08 19:45

    Kotlin version:

    Similar to older answers in Java. Simply:

    1. In Layout Editor/XML, add the types of things you'd like to hyperlink via the autoLink property.

      <TextView
          ...
          android:autoLink="web|phone|email" />
      
    2. Add an onClickListener to your TextView in Kotlin code to handle clicks on the plain text part. Check to make sure the person didn't click on a link by checking selectionStart and selectionEnd.

      binding.messageText.setOnClickListener { view ->
          if (binding.messageText.selectionStart == -1 && binding.messageText.selectionEnd == -1) {
              // do whatever you want when they click on the plain text part
          }
      }
      
    0 讨论(0)
提交回复
热议问题