Skip to content

Conversation

@Judas
Copy link
Contributor

@Judas Judas commented Oct 24, 2025

The original Android TextView has an issue concerning the sizing of multiline text.
When a text has multiple lines, the TextView forcefully sets the width to match_parent, even if the text layout does not span the whole width. This can easily be seen when the text contains a long word.

This PR aims to fix this by wrapping the width of the CustomTextView to the minimal size possible.

Screenshot 2025-10-24 at 14 53 39

I used a conservative approach: the default behavior is to not use this option but user can ask for it specifically.

MarkdownText(
    ...
    wrapMultilineTextWidth = true,
    ...
)

Some of the markers are excluded manually because we don't want to wrap their widths (especially tables)

Most of the code is taken from this Medium article that explains the problem in details : https://medium.com/@mxdiland/android-textview-multiline-problem-61f8c3499bbb

@jeziellago jeziellago requested a review from Copilot October 27, 2025 12:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds optional width wrapping functionality for multiline TextViews to prevent them from unnecessarily expanding to match_parent when the actual text content doesn't require the full width. This addresses a known Android TextView sizing issue where multiline text always claims maximum width even when the longest line is shorter.

Key changes:

  • Added a new wrapMultilineTextWidth parameter (defaults to false for backward compatibility)
  • Implemented custom measurement and drawing logic to calculate and apply the minimal required width
  • Excluded specific markdown elements (tables, code blocks, block quotes) from width wrapping

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
MarkdownText.kt Added the wrapMultilineTextWidth parameter to the public API and passed it to CustomTextView
CustomTextView.kt Implemented the width wrapping logic with custom onMeasure() and onDraw() overrides, plus helper methods to calculate minimal width and filter excluded markdown spans

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


private var extraPaddingRight: Int? = null
private var isTextSelectable: Boolean = false
var wrapMultilineTextWidth: Boolean = true
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value is inconsistent with the parameter default in MarkdownText.kt. This should be false to match the conservative approach described in the PR and the default value of the wrapMultilineTextWidth parameter (line 54 in MarkdownText.kt).

Suggested change
var wrapMultilineTextWidth: Boolean = true
var wrapMultilineTextWidth: Boolean = false

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)

if (!layout.shouldWrap()) return
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential null pointer exception if layout is null. The shouldWrap() extension checks for null, but direct access to layout before the null-safe call could throw an exception if the layout hasn't been initialized yet.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one though...

syntaxHighlightTextColor: Color = Color.Unspecified,
headingBreakColor: Color = Color.Transparent,
enableUnderlineForLink: Boolean = true,
importForAccessibility: Int = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO,
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing KDoc documentation for the new wrapMultilineTextWidth parameter. Consider adding documentation explaining what this parameter does and when users should enable it, especially since this addresses a specific Android TextView behavior.

Suggested change
importForAccessibility: Int = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO,
importForAccessibility: Int = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO,
/**
* If true, enables a workaround for Android TextView's multiline text wrapping behavior.
* This is useful when markdown content does not wrap as expected in multiline scenarios.
* Enable this if you notice issues with text not wrapping correctly in your markdown.
*/

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants