-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Android TextView being truncated under some conditions #27179
Conversation
@albyrock87 Just a random person here, but that looks like a solid explanation to add also in the code so it's easily discoverable also later to whoever reads the code. |
I've added the comments in the code. That said, I'm afraid this PR will generate UITests failures everywhere and it'll take forever to capture all the screenshots. |
We have another option to not break all the UI tests: keep the |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
In theory it should generated the needed screenshots and we can just replace, or we can ask for help to finish that tedious work of updating the screenshots. |
once we see the screenshots that'll give us an idea of the magnitude of change. There's definitely a lot :-) |
I think this change makes sense... I'm a little curious about the initial conversion from px to dp and if we should be rounding that Like, if a DP value is 294.0000000000001 it seems like we should just convert that to 294 when doing the PX to DP conversion I'm also wondering if we should midpoint round the width and height also. It seems like that's how Android suggests always doing the rounding https://developer.android.com/training/multiscreen/screendensities#dips-pels |
I'm afraid that value comes from the centering algorithm (in this specific example) and not from PX to DP conversion. Obviously the centering algorithm uses DP coming from a measure pass which is in PX, but that's a plain I also wonder why we're going through |
{ | ||
EnsureMetrics(self); | ||
|
||
return (float)Math.Round(dp * s_displayDensity, MidpointRounding.AwayFromZero); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the UITest, could be nice to include some device tests checking conversions.
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
Thanks @albyrock87 as always for looking into this and explaining it so succinctly. This adds more information to something that has puzzled me now for 14+ months. I think it's interesting that fix # 2 appears to a variation of the same "fix" (workaround) I posted back in June 2024 (8 months ago now), while this issue has been entirely ignored by Microsoft formally since report in Oct 2023 (14 months ago). My "workaround" posted here was to override the platform view type and then apply this same +1 you are doing to the width there:
At the time I frankly thought this was the wrong approach as it felt so crude and dumb to just add a pixel to the width. I felt like the rounding errors should be fixed intrinsically in how Maui handles things so that we don't have to do this. i.e. I feel like Maui should not be rounding things that it cannot safely be rounding. Thanks as always for adding clarity to such things. |
/rebase |
8df47ff
to
d320277
Compare
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
Failing tests look unrelated |
Detailed Issue information
Android emulators (e.g., with a display density multiplier of 2.625) expose an issue when arranging views.
Consider this label arrangement:
When converted to pixels (
Math.Ceiling
used by MAUI):Expected platform rectangle width: 492px.
Actual width due to rounding error: 491px, causing content to be cut off.
Issues Identified
The calculation of X + Width involves independent conversion of dp values to px, e.g.:
The use of
dp
instead ofpx
for layout leads to inaccuracies when scaling.A
DeviceTest
has been added to show what I'm talking about (failingAssert
has been commented):When converting a
Rect
to apx
one we basically have two possible strategiesleft
andright
.Less visually disruptive, except for text as explained by @kubaflo here.
left
andwidth
.Undesirable for grid layouts like ColumnDefinitions=",,," where content is positioned side by side.
Proposed Fixes
To prevent truncation:
For example,
294.00000000000006
should round to294px
instead of295px
because0.00000000000006
is less than a givenEpsilon = 0.0000000001
.Description of Change
We can fix this specific issue by using any of these solutions, so I decided to keep only the first one and defer the second one in case the issue reappears under some special conditions.
Issues Fixed
Fixes #17884
Fixes #26619