Skip to content
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

[Android] Correctly scale Button image #19834

Merged
merged 20 commits into from
Mar 16, 2024
Merged

[Android] Correctly scale Button image #19834

merged 20 commits into from
Mar 16, 2024

Conversation

jsuarezruiz
Copy link
Contributor

@jsuarezruiz jsuarezruiz commented Jan 11, 2024

Description of Change

Correctly scale the Button image on Android and Windows.

NOTE: We require the server's snapshots for the golden test. The PR is a Draft until the snapshots are generated.

Issues Fixed

Fixes #9734
Fixes #18242

@jsuarezruiz jsuarezruiz added platform/windows 🪟 platform/android 🤖 legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor area-controls-button Button, ImageButton labels Jan 11, 2024
@jsuarezruiz jsuarezruiz changed the title [Android, Windows] Correctly scale Button image [Android, iOS, Windows] Correctly scale Button image Jan 16, 2024
@jsuarezruiz jsuarezruiz marked this pull request as ready for review January 18, 2024 07:32
@jsuarezruiz jsuarezruiz requested a review from a team as a code owner January 18, 2024 07:32
@jsuarezruiz jsuarezruiz requested review from mattleibow, tj-devel709 and jfversluis and removed request for jfversluis January 18, 2024 07:32
@tj-devel709
Copy link
Member

It's looking pretty good to me on iOS and android!
image

@mattleibow
Copy link
Member

/rebase

@mattleibow
Copy link
Member

/rebase

@tj-devel709
Copy link
Member

It appears that there is an issue on iOS with an ImageButton inside a scrollview. The image does not resize with the width request as android and Windows does. Check out the bottom imagebutton in each of the screenshots:

iOS:
image

Android:
image

Windows:
image

This is the relevant xaml:

<ScrollView HeightRequest="100" WidthRequest="50">
   <ImageButton Source="dotnet_bot.png" />
</ScrollView>

@jsuarezruiz jsuarezruiz changed the title [Android, iOS, Windows] Correctly scale Button image [Android] Correctly scale Button image Mar 4, 2024
@jsuarezruiz
Copy link
Contributor Author

We already have the changes to fix Windows merged on main branch and the iOS fix will be #20953

tj-devel709
tj-devel709 previously approved these changes Mar 4, 2024
Copy link
Member

@tj-devel709 tj-devel709 left a comment

Choose a reason for hiding this comment

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

Not sure why the windows changes still appear in this PR as main was merged into here and those changes are present in https://github.com/dotnet/maui/pull/20949/files. But otherwise, LGTM

@mattleibow mattleibow changed the base branch from release/8.0.1xx-sr3 to main March 14, 2024 14:50
// Which is why we don't have to worry about calling setCompoundDrawablePadding
// ourselves for our custom implemented IconGravityBottom
materialButton.IconPadding = (int)context.ToPixels(contentLayout.Spacing);

// For IconGravityTextEnd and IconGravityTextStart, setting the Icon twice
// is needed to work around the Android behavior that caused
// https://github.com/dotnet/maui/issues/11755
switch (contentLayout.Position)
Copy link
Member

Choose a reason for hiding this comment

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

Instead of toggling the icon here, we are doing that as part of the measure. This makes the updates happen all together instead of here, and then it is better for maintenance.

Comment on lines +126 to 127
// The TextView might need an additional measurement pass at the final size
this.PrepareForTextViewArrange(frame);
Copy link
Member

Choose a reason for hiding this comment

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

This is needed because TextView controls may be measured with an "AtMost" which means the measure is more "give me the smallest size". Because the text in a TextView is positioned using an absolute coordinate, it needs to be re-measured with the final sizes to get the new coordinates.

Comment on lines +190 to +192
button.Icon = platformImage is null
? null
: new MauiMaterialButton.MauiResizableDrawable(platformImage);
Copy link
Member

Choose a reason for hiding this comment

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

When we set the icon, we wrap it in a special "resizable drawable" that allows us to give the icon a specific size that is used by the measure and layout passes.

{
}

protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
public override int IconGravity
Copy link
Member

Choose a reason for hiding this comment

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

If we set an invalid/new value here, then the measure and layout passes will not work properly. Luckily, we can pretend that bottom is top, and then swap to the bottom at the last minute after the layout has completed.

Comment on lines +45 to +55
// if there is BOTH an icon AND text, but the text layout has NOT been measured yet,
// we need to measure JUST the text first to get the remaining space for the icon
if (Layout is null && TextFormatted?.Length() > 0)
{
// remove the icon and measure JUST the text
Icon = null;
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);

// restore the icon
Icon = currentIcon;
}
Copy link
Member

Choose a reason for hiding this comment

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

Due to the way TextView measures, it appears to prioritize the icon and will clip/squash the text. However, we want the text to be the priority. In order for this to happen, we have to measure the initial pass without an icon and this sets us up to re-measure with a smaller/fitting icon.

Comment on lines +78 to +86
if (ForceBottomIconGravity)
{
var icons = TextViewCompat.GetCompoundDrawablesRelative(this);
if (icons[1] is { } icon)
{
TextViewCompat.SetCompoundDrawablesRelative(this, null, null, null, icon);
icon.SetBounds(0, 0, icon.IntrinsicWidth, icon.IntrinsicHeight);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Here we flip at the end.

@mattleibow mattleibow self-assigned this Mar 15, 2024
@PureWeen PureWeen dismissed mattleibow’s stale review March 15, 2024 22:28

Matt took over as the owner of this PR

@PureWeen PureWeen merged commit 1b423ab into main Mar 16, 2024
47 checks passed
@PureWeen PureWeen deleted the fix-18242 branch March 16, 2024 22:50
@romerotg
Copy link

@PureWeen is there a way to know on which version this fix is gonna be released?

@github-actions github-actions bot locked and limited conversation to collaborators Apr 18, 2024
@Eilon Eilon removed the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label May 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
9 participants