very difficult to long click TextView when set the part of the textView is clickable using SpannableString

160 views Asked by At

I set the part of the textView is clickable using SpannableString. But it is very difficult for me to detect a long press my textView.

private fun makeTextLink(textView: TextView, str: String, underlined: Boolean, color: Int?, action: (() -> Unit)? = null) {
    val spannableString = SpannableString(textView.text)
    val textColor = color ?: textView.currentTextColor
    val clickableSpan = object : ClickableSpan() {
        override fun onClick(textView: View) {
            action?.invoke()
        }
        override fun updateDrawState(drawState: TextPaint) {
            super.updateDrawState(drawState)
            drawState.isUnderlineText = underlined
            drawState.color = textColor
        }
    }
    val index = spannableString.indexOf(str)
    spannableString.setSpan(clickableSpan, index, index + str.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    textView.text = spannableString
    textView.movementMethod = LinkMovementMethod.getInstance()
    textView.highlightColor = Color.TRANSPARENT
}
3

There are 3 answers

0
Dhruv Sakariya On
TextView textView = findViewById(R.id.text_view);
        String text = "First Click THIS and then THIS ";
  
        SpannableString ss = new SpannableString(text);
          
        // creating clickable span to be implemented as a link
        ClickableSpan clickableSpan1 = new ClickableSpan() {
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "First Clickable Text", Toast.LENGTH_SHORT).show();
            }
        };
          
        // creating clickable span to be implemented as a link
        
          
        // setting the part of string to be act as a link
        ss.setSpan(clickableSpan1, 12, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        
  
        textView.setText(ss);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
0
Devesh Kumawat On
private void setClickableSpan(Activity context, TextView textView, String mainString, String selectedString)
    {
        ModelSettingData settingData = new StorageUtil(context).getSettingData();

        ClickableSpan termsAndConditionSpan = new ClickableSpan()
        {
            @Override
            public void onClick(@NonNull View textView) {
               // code hear
            }

            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void updateDrawState(@NonNull TextPaint ds) {
                super.updateDrawState(ds);
                if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP){
                    // Do something for lollipop and above versions
                    ds.setUnderlineText(false);
                    ds.setColor(getResources().getColor(R.color.TRANSPARENT));
                }
            }
        };


    
        SpannableString content = new SpannableString(mainString);
        int startPosition = mainString.indexOf(selectedString);
        int endPosition = mainString.lastIndexOf(selectedString) + selectedString.length();

        content.setSpan(termsAndConditionSpan, startPositionS1, endPositionS1, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);

        textView.setText(content);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setHighlightColor(Color.TRANSPARENT);
    }
0
Cheticamp On

You don't explain what "very difficult to long click TextView" really means. I assume that you want to set a long click listener to the TextView. You can do that as follows in your makeText function:

textView.setOnLongClickListener { v ->
    // your long click code goes here
    true
}

Returning true usually means that the long click listener has consumed the touch event and no further processing is needed. Unfortunately, this return value seems to be ignored with a clickable span. If you want the click code to run on a long click when a long click is detected in the clickable span then this is not a problem; otherwise, you will need to find a way to suppress click processing on a long click

This code will also make the entire TextView long clickable and that also may not be what you want.