'justificationMode with LinkMovementMethod make text cut off

I want to achieve both justify text and add a link (show more) to TextView so I use justificationMode with movementMethod. justificationMode working well but after set movementMethod, some last character on each line of my TextView is cut.

val textView = findViewById<TextView>(R.id.myTextView)
textView.text = "Lorem ipsum dolor sit amet, consectetuabc adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
textView.movementMethod = LinkMovementMethod()

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/myTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="10dp"
        android:textSize="20sp" />

</LinearLayout>


Solution 1:[1]

I had the same problem, the solution I found was to use the android:autoLink="all" tag on my Textview, instead of using LinkMovementMethod...

Solution 2:[2]

8 months later, this issue is still here and I just ran into it on SDK 31. The android:autoLink="all" workaround did not work for me and was also unsatisfactory for my application. Here is my workaround; it's not perfect but it solved the issue for me, and I think there is enough here to fix OP's issue while providing guidance for others:

1. Add OnTouchListener to TextView

// A lot of this code was lifted from LinkMovementMethod.onTouchEvent
binding.tv.setOnTouchListener { tv, event ->
        require(tv is TextView)
        val action = event.action
        if (action == MotionEvent.ACTION_UP) {
            val x = event.x.toInt() - tv.totalPaddingLeft + tv.scrollX
            val y = event.y.toInt() - tv.totalPaddingTop + tv.scrollY
            val line = tv.layout.getLineForVertical(y)
            val offset = tv.layout.getOffsetForHorizontal(line, x.toFloat())
            val spannable = tv.text as SpannedString // Risky business
            val links: Array<ClickableSpan> = spannable.getSpans(offset, offset, ClickableSpan::class.java)
            if (links.isNotEmpty()) {
                logger.debug("x=${event.x}; y=${event.y}")
                links.first().onClick(tv)
            }
        }
        true
    }

2. Add ClickableSpans to TextView

val builder = SpannableStringBuilder()
builder.setSpan(object : ClickableSpan() {
    // You can cache data here using closure
    val textOrUrl = "Clicked!"
    override fun onClick(widget: View) {
        // Do stuff
        Toast.makeText(widget.context, textOrUrl, Toast.LENGTH_SHORT).show()
    }

    // optional override if you don't want your links formatted
    override fun updateDrawState(ds: TextPaint) = Unit
}, beginIndex, endIndex, 0)
// Add builder to TextView 
binding.tv.text = builder

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabio Gunkel
Solution 2 not43s