[BUG]: Multiplying by powers of 10: the content of the page is not showing completly in the text box
Describe the bug
In the Multiplying by powers of 10 lesson there is a page where its content is not being displayed completly in the text box The last letters do not appear in the text box.
This happens in English and Portuguese language.
Steps To Reproduce
Steps:
- Go to Multiplication
- Go to Multiplying by powers of 10
- Playthrough the lesson
- See a text box that the content is not shown completly
Expected Behavior
It expected to see the content fully
Screenshots/Videos
What device/emulator are you using?
OPPPO A79 5G
Which Android version is your device/emulator running?
Android 14
Which version of the Oppia Android app are you using?
0.14-beta-17f2ef3044
Additional Context
No response
Reproduced this for both English and Portuguese, and will likely be able to repro it in RTL as well.
Generally, this is occuring when we have text in numbered lists(also spotted in rounding numbers in Place values). It appears that there is no padding to the end of the content textview.
Hi @adhiamboperes,
I checked this issue and found that the problem only occurs with ordered lists, not with unordered lists.
The class OlSpan in ListItemLeadingMarginSpan.kt overrides the following functions:
getLeadingMargin(first: Boolean)drawLeadingMargin(...)
Typical Order of Function Calls
-
getLeadingMargin(first: Boolean)is called first- This happens during the text layout phase, to determine how much space to leave at the start of each line of text (i.e., how much to indent).
- It’s called once per line of the paragraph that has the span.
- The first line gets
first = true, and the remaining lines getfirst = false.
-
Then,
drawLeadingMargin(...)is called- This occurs during the drawing phase, when the layout is rendered onto the canvas.
- It is typically called only once, for the first line of the paragraph.
The Issue
In our case, the getLeadingMargin() method returns a computedLeadingMargin, which depends on drawLeadingMargin() for accurate calculation (e.g., the width of prefix text like "1.", "2.", "3.", etc.).
This is because we can access the Paint object only from inside the drawLeadingMargin() method.
Proposed Solution
We need to calculate the width of the text outside of drawLeadingMargin(), so that getLeadingMargin() can return the correct computedLeadingMargin independently.
✅ Suggested Fix
Pass a reference of the TextView so that we can use it to:
- Construct a matching
TextPaintobject - Dynamically calculate the prefix width (e.g., "1.", "10.") using its font, text size, and other styling
This will allow us to decouple getLeadingMargin() from drawLeadingMargin() and compute the margin correctly during layout.
class OlSpan(
override val parent: ListItemLeadingMarginSpan?,
context: Context,
private val numberedItemPrefix: String,
private val longestNumberedItemPrefix: String,
private val displayLocale: OppiaLocale.DisplayLocale,
private val textView: TextView? = null //subha
) : ListItemLeadingMarginSpan() {
private val paint = textView?.paint
private val textWidth = Rect().also {
paint?.getTextBounds(
numberedItemPrefix, /* start= */ 0, /* end= */ numberedItemPrefix.length, it
)
}.width()
private val longestTextWidth = Rect().also {
paint?.getTextBounds(
longestNumberedItemPrefix,
/* start= */ 0,
/* end= */ longestNumberedItemPrefix.length,
it
)
}.width()
private var computedLeadingMargin =
longestTextWidth + spacingBeforeText + spacingBeforeNumberPrefix
override fun getLeadingMargin(first: Boolean) :Int { return computedLeadingMargin }
override fun drawLeadingMargin(...) {...}
}
Output:
| Before | After |
|---|---|
|
|
|
@subhajitxyz, do you mind putting up a PR with the solution you proposed above? I have found it quite difficult to implement it myself, due to the fact that it is not clear where the textView will be passed in from, and the paint object created in private val paint = textView?.paint doesn't appear to be used.
Ok.