-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Android] Button Border can be set independent of other properties and will not change the size of the Button. **behavior change** #1570
Conversation
@samhouts to summarize the discussion we had yesterday, I'd recommend not using a defaultValueCreator, but using a default value of to mitigate the breaking change, you could e.g. deprecate |
7fbe368
to
b179366
Compare
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.
I reviewed the Core part, see comments.
I understand why you added DefaultValue fields, for avoiding comparing against magic hardcoded numbers in renderers. Actually, the BindableProperty.DefaultValue serves that purposes, no need for the extra field.
If you prefer not doing the change for CSS support in this PR, that's fine. I can do it in another one as this one is merged.
Overall, it's 👍
Xamarin.Forms.Core/Button.cs
Outdated
public const int DefaultCornerRadius = -1; | ||
public const double DefaultBorderWidth = -1; | ||
public static Color DefaultBorderColor = Color.Default; | ||
public static Color DefaultTextColor = Color.Default; |
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.
those 2 aren't magic. they do not require fields.
Xamarin.Forms.Core/Button.cs
Outdated
@@ -31,32 +39,42 @@ public class Button : View, IFontElement, ITextElement, IButtonController, IElem | |||
|
|||
public static readonly BindableProperty FontAttributesProperty = FontElement.FontAttributesProperty; | |||
|
|||
public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create("BorderWidth", typeof(double), typeof(Button), -1d); | |||
public static readonly BindableProperty BorderWidthProperty = BindableProperty.Create("BorderWidth", typeof(double), typeof(Button), DefaultBorderWidth); |
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.
I don't see the need to introduce a level of indirection here. one can check the default value by doing BorderWidthProperty.GetDefaultValue()
Xamarin.Forms.Core/VisualElement.cs
Outdated
@@ -7,6 +7,8 @@ namespace Xamarin.Forms | |||
{ | |||
public partial class VisualElement : Element, IAnimatable, IVisualElementController, IResourcesProvider | |||
{ | |||
public static Color DefaultBackgroundColor = Color.Default; |
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.
same
public static readonly BindableProperty BorderRadiusProperty = BindableProperty.Create("BorderRadius", typeof(int), typeof(Button), defaultValue: DefaultBorderRadius, | ||
propertyChanged: BorderRadiusPropertyChanged); | ||
|
||
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(int), typeof(Button), defaultValue: DefaultCornerRadius, |
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.
can we promote CornerRadius
to BorderElement
(shared with Frame
) so we could add the border-radius
CSS property targeting both ?
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.
I'm targeting 15-5, so that's not in this branch. We can add it when it goes to master. :)
#pragma warning disable 0618 // retain until BorderRadiusProperty removed | ||
bindable.SetValue(Button.BorderRadiusProperty, val); | ||
#pragma warning restore | ||
} |
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.
I'm trying to think about all the things that could go wrong here:
- binding => should be fine, unless user binds to the 2 properties and has a poor INPC implementation in VM
- clearvalue => could you please add a unit test for button making sure that when a property is Cleared (using
ClearValue
both are actually cleared ? i.e. IsSet() == false; ?
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.
Unit tests added! However, it looks like we don't clear the context when we call ClearValue
, so IsSet
returns true in that case. Added a test to BindableObject
to show that it's not specific to this case.
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.
😢
Is this still [breaking] and a behavior change ? |
bindable.ClearValue(bindableProperty); | ||
|
||
var isSet = bindable.IsSet(bindableProperty); | ||
Assert.IsTrue(isSet); |
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.
I'll look at fixing this, or investigating why it is that way. if ClearValue
is dropping the context, you could ClearValue
the other property when the first is !IsSet()
in your onPropertyChanged
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.
Great work.
How can I disable shadow for the button which I don't need it? |
it seems the new version added some Padding for the button? |
Description of Change
This fix reverts #1178 and restores the changes made in #941, which will allow Android
Button
s to have a border without aBorderRadius
specified.It goes further to allow a border to be added and/or border radius to be changed without changing the
BackgroundColor
of theButton
.It also keeps the size of the
Button
the same as a default Material button, draws a shadow, and preserves the "ripple" effect when theButton
is pressed.It does not preserve the state list animation that causes the
Button
to slowly fade to the pressed color and increase elevation when long pressed. That can be added in a future PR if necessaryThis PR has a potential breaking behavior change. It hardcodes the default color of the button on pre-AppCompat because the theme color does not seem to match the actual color that is used.
We have also marked
Button.BorderRadius
as obsolete in favor ofButton.CornerRadius
. TheBorderRadius
property will forward to theCornerRadius
property.Before (AppCompat):
Before (pre-AppCompat):
Note: The test description lies on pre-AppCompat, since the default
Button
color is actually darker than the color that the "darker" button is. Apparently, the definition ofColor.Gray
is different.with #941 (AppCompat):
with #941 (pre-AppCompat):
After (AppCompat):
After (pre-AppCompat):
Note that the shadow is a lighter color of the
BackgroundColor
, matching the pressed color of theButton
. When a blue background is paired with a red border color, it looks a bit odd, like theButton
is expanding past the border. However, it looks fine with a sensible color combination, as seen with the grayButton
with red border.Bugs Fixed
API Changes
Deprecated (note, marked obsolete but still present and functional):
Added:
Behavioral Changes
Button.BorderRadius
is now obsolete. Please useButton.CornerRadius
now.Button.BackgroundColor
is now hardcoded on pre-AppCompat instead of derived from a theme resource.BorderRadius
/BorderColor
/BorderWidth
are specified.PR Checklist