android ClickableSpan intercepts the click event

前端 未结 5 984
慢半拍i
慢半拍i 2021-02-01 15:42

I have a TextView in a Layout. It\'s so simple. I put a OnClickListener in the layout and some part of the TextView is set to be ClickableSpan. I want the ClickableSpan to do s

5条回答
  •  别那么骄傲
    2021-02-01 16:45

    Declare a global boolean variable:

    boolean wordClicked = false;
    

    Declare and initialize l as final:

    final RelativeLayout l = (RelativeLayout)findViewById(R.id.contentLayout);
    

    Add an OnClickListener to textView:

    textView.setOnClickListener(new OnClickListener() {
    
        @Override
        public void onClick(View v) {
            if (!wordClicked) {
                // Let the click be handled by `l's` OnClickListener
                l.performClick();   
            }
        }
    });
    

    Change span to:

    ClickableSpan span = new ClickableSpan() {
    
        @Override
        public void onClick(View widget) {
            wordClicked = true;
            Toast.makeText(Trial.this, "just word", Toast.LENGTH_SHORT).show();
    
            // A 100 millisecond delay to let the click event propagate to `textView's` 
            // OnClickListener and to let the check `if (!wordClicked)` fail
            new Handler().postDelayed(new Runnable() {
    
                @Override
                public void run() {
                    wordClicked = false;                        
                }
            }, 100L);
        }
    };
    

    Edit:

    Keeping user KMDev's answer in view, the following code will meet your specifications. We create two spans: one for the specified length: spannableString.setSpan(.., 0, 5, ..); and the other with the remainder: spannableString.setSpan(.., 6, spannableString.legth(), ..);. The second ClickableSpan(span2) performs a click on the RelativeLayout. Moreover, by overriding updateDrawState(TextPaint), we are able to give the second span a non-distinctive (non-styled) look. Whereas, first span has a link color and is underlined.

    final RelativeLayout l = (RelativeLayout)findViewById(R.id.contentLayout);
        l.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                Toast.makeText(Trial.this, "whole layout", Toast.LENGTH_SHORT).show();
            }
        });
    
    TextView textView = (TextView)findViewById(R.id.t1);
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    textView.setHighlightColor(Color.TRANSPARENT);
    
    SpannableString spannableString = new SpannableString(textView.getText().toString());
    
    ClickableSpan span = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            Toast.makeText(Trial.this, "just word", Toast.LENGTH_SHORT).show();
        }
    };
    
    spannableString.setSpan(span, 0, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);     
    
    ClickableSpan span2 = new ClickableSpan() {
        @Override
        public void onClick(View widget) {
            l.performClick();
        }
    
        @Override
        public void updateDrawState(TextPaint tp) {
            tp.bgColor = getResources().getColor(android.R.color.transparent);
            tp.setUnderlineText(false);
        }
    };
    
    spannableString.setSpan(span2, 6, spannableString.length(), 
                                          Spannable.SPAN_INCLUSIVE_INCLUSIVE);  
    
    textView.setText(spannableString);
    

    Special thanks to user KMDev for noticing the issues with my original answer. There's no need for performing a (faulty) check using boolean variable(s), and setting an OnclickListener for the TextView is not required.

提交回复
热议问题