'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 |