BackgroundColor changes Button size?

JamesCarterJamesCarter USMember
edited April 2016 in Xamarin.Forms

I have two buttons in a Horizontal Stack panel.

<StackLayout Orientation="Horizontal" VerticalOptions="End">
  <Button Text="Reset" />
  <Button Text="Search" HorizontalOptions="FillAndExpand" BackgroundColor="#3b5998" />
</StackLayout>

When I apply a BackgroundColor to one, it changes in size to fill the StackPanel. Am I misunderstand something or is this a bug? I have tried to apply a margin to this but it simply expands the StackPanel and causes the other button to expand further!

Without BackgroundColor:

With BackgroundColor:

I would appreciate any advice, many thanks.

Edit: I am using Xamarin.Forms 2.2.0.4-pre1 because of my use of Prism.Unity.Forms

Best Answer

Answers

  • Matthew.4307Matthew.4307 USMember ✭✭✭

    Could certainly be a bug, one theory I have is that a different drawable is being used because you've requested a solid colour, note that the RESET has a shadow and SEARCH does not once it is blue.

    On Android (if you are supporting that platform), if you enable Show Layout Bounds in Developer Options you will see the actual boundaries of the controls and it might be clear whether the button is getting larger, or just that the different drawable makes it appear to. Windows RT has a similar option if debugging from VS.

  • JamesCarterJamesCarter USMember
    edited April 2016

    Hi Matthew,

    Thanks for the help - I am developing primarily for Android so I've used your suggestion to check out the boundary boxes.

    It looks like your right, it must use a different operation to draw the button when I use the colour option to draw with. See below:


    I am using the plain Button with only that BackgroundColor property attached.

    However I have specified the use of the Material theme:

     [Activity(Theme = "@android:style/Theme.Material.Light"
    

    So perhaps I need to do something special to get the colour I need for this button? If anyone knows what is the correct way to affect these styling options I would appreciate a point in the right direction.

    Many thanks.

    Edit: I've noticed there is a 'ripple' light effect when you click on an Android button 6.x, I would of course like to preserve that behavior. Perhaps I am thinking too generically by trying to set this in my XAML and I need to get down to the Android layer. I just assumed I would not have to for something simple like this? [Another Edit, using the default theme produces the same result]

  • Matthew.4307Matthew.4307 USMember ✭✭✭

    Android is a bit of a nightmare as it uses drawables which can be an image, color or shape. In the case of the standard button theme it will be an image and asking for a color uses the Color drawables instead losing you shadows etc. that you get for free normally.

    You can use custom renderer to change the behaviour of the drawables, creating a StateDrawable which applies the desired appearance when enabled, disabled etc.
    This would also allow the addition of padding, shadows (possibly).

    You should be able to set the Tint colour as blue and preserve the normal styling of the button, but Xamarin haven't implemented that on Compound Buttons so likely not for Button either.

  • JamesCarterJamesCarter USMember

    Okay, I understand a bit further now. I need to specify a certain @drawable for the button when on Android. First try I used the following:

     <Setter Property="BackgroundColor" Value="@drawable/btn_default_mtrl_shape"></Setter>
    

    However this cannot be converted into a Xamarin.Forms.Color.

    Looks like as you say I could use a CustomRenderer on a button, that checks the Style or BackgroundColor and sets the Tint. I will look into trying to do this now. If there is a better way I would appreciate a prod in the right direction.

    It looks like this is the default drawable for a button: https://github.com/android/platform_frameworks_base/blob/master/core/res/res/drawable/btn_default_material.xml

    I should be able to create a btn_primary_material.xml to use for my Primary button style.

    Thanks for your help.

  • Matthew.4307Matthew.4307 USMember ✭✭✭

    Depending on exactly how you do it you would create a series of images and set which to use for the various states, enabled, disabled, pressed. Personally I dislike the approach of creating images and do as much as possible with code/custom renders.

    It depends on exactly what aesthetic you wish to achieve, but the important bit is to achieve consistent design of all buttons regardless of colouring. Personally I'd set all the buttons to have a solid colouring with a State Drawable creating the ShapeDrawble I desired similar to below which I used for Switches prior to switching to Material Design.

                var on = new ShapeDrawable(new RectShape());
                on.Paint.Color = StyleHelper.Action.ToAndroid();
    
                var off = new ShapeDrawable(new RectShape());
                off.Paint.Color = StyleHelper.BackgroundColorDarkest.ToAndroid();
    
                var disabled = new ShapeDrawable(new RectShape());
                disabled.Paint.Color = StyleHelper.BackgroundColorDarker.ToAndroid();
    
                var native = (Android.Widget.Switch)this.Control;
    
                StateListDrawable drawable = new StateListDrawable();
                drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, on);
                drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, disabled);
                drawable.AddState(new int[] { }, off);
    
                this.Control.ThumbDrawable = drawable;
    
  • MeteorsoftWindowsMeteorsoftWindows MYMember ✭✭

    I am having the same problem as well on Xamarin.Forms.2.1.0.6529.
    Is there anyway to override the BackgoundColor instead of using Tint?

  • SwathiSudarSwathiSudar USMember ✭✭
    edited June 2017

    Hi, I am new to Xamarin I create custom Renderer Button but it shows failed to resolve the assembly version

  • Umar3xUmar3x FRMember ✭✭✭
    edited October 2017

    This behavior is still actual. I want my buttons with shadow but when I apply a background color shadow disappears ... Does someone still have this issue on XF2.4 ?
    But when changing color from within a customRenderer it works ... prob is that it applies the color to all buttons, so I need to create a customRenderer for each button just for color and shadow.

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
            {
                base.OnElementChanged(e);
    
               if (Control != null)
                {
                     Control.SetBackgroundColor(global::Android.Graphics.Color.Orange);
                }
            }
    

    While myButton.BackgroundColor = Color.Orange; displays a button w/o shadow and more rounded....

  • Umar3xUmar3x FRMember ✭✭✭

    Nothing about that ? No one has this prob when setting a background color ?I'd like to open a bug on bugzilla.

  • GaetanFGaetanF USMember ✭✭

    I do just now. Pretty annoying...

  • SteveShaw.5557SteveShaw.5557 USMember ✭✭✭
    edited June 6

    @JamesCarter

    reset the drawable back to the default button

    try "BackgroundColor = Transparent" -- IIRC that removes the override that is suppressing original drawable. But I could be wrong.

    @Umar3x - I am seeing buttons with background color darken when pressed (Android, emulator, API 25).

    If you are starting with black or near-black background color, or want button to get brighter instead of darker, will have to do something manually. Try adding a tint effect. Or add custom properties that custom renderer uses to set native background. Or use native material theme instead of forms styles.

  • SamanthaHoutsSamanthaHouts USXamarin Team Xamurai

    Starting in 2.5.1, you can apply a platform specific property to your Xamarin.Forms Button to add the Android default padding and shadow when the color or border is changed. Thanks! See https://github.com/xamarin/Xamarin.Forms/pull/1935#issuecomment-375728802 for more info. Thanks!

  • MeteorsoftWindowsMeteorsoftWindows MYMember ✭✭

    This problem can actually be solved by setting your renderer inherit from "Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer" instead of "Xamarin.Forms.Platform.Android.ButtonRenderer".

    [assembly: ExportRenderer(typeof(Button), typeof(MyButtonRenderer))]
        namespace MXApp.Droid.Renderers {
            public class MyButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer {
                public MyButtonRenderer(Context context) : base(context) { 
    
                }
            }
        }
    

    But recently the problem resurfaced again on the newer version of Xamarin.Forms. I m still not sure how to fix the problem yet.

  • MeteorsoftWindowsMeteorsoftWindows MYMember ✭✭

    @SamanthaHouts said:
    Starting in 2.5.1, you can apply a platform specific property to your Xamarin.Forms Button to add the Android default padding and shadow when the color or border is changed. Thanks! See https://github.com/xamarin/Xamarin.Forms/pull/1935#issuecomment-375728802 for more info. Thanks!

    As stated by Samantha, i found the answer by setting the default padding and shadow on the new update.

    using Xamarin.Forms.PlatformConfiguration;
    using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
    
    ...
    
    var MyButton = new Button()
    MyButton.On<Android>().SetUseDefaultPadding(true).SetUseDefaultShadow(true);
    
  • DarrenKayDarrenKay GBUniversity ✭✭

    I recently had a similar issue about buttons changing size (and style). It appears a change in XF caused it and you can revert back to the defaults. My post may help you? https://forums.xamarin.com/discussion/comment/350174/#Comment_350174

Sign In or Register to comment.