1
votes

In my Xamarin.forms app, I have two buttons. I need to achieve following...

  1. By default both buttons will have white background
  2. When user clicks on a button it's background should change to Blue
  3. If user presses and holds then color should change to Blue and when user releases color should revert back to white
  4. Obviously only one button can have Blue background.

Sample

enter image description here

2

2 Answers

3
votes

You will have to design a custom renderer in order to achieve this.

In your Core/PCL project create a button class :

public class CustomButton : Button
{
    public event EventHandler OnPressed;

    public event EventHandler OnReleased;

    public void OnPressed()
    {
      OnPressed?.Invoke(this, EventArgs.Empty);
    }

    public void OnReleased()
    {
      OnReleased?.Invoke(this, EventArgs.Empty);
    }
}

Then in your iOS and Android create the Renderer :

Eg: Android :

[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
namespace yourproject.Droid.Renderer
{
    public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);

            var customRendererButton = e.NewElement as CustomButton;

            var control = Control as Android.Widget.Button;
            control.Touch += (object sender, TouchEventArgs args) =>
            {
                if (args.Event.Action == MotionEventActions.Up)
                {
                    customRendererButton.OnReleased();
                }

                else if (args.Event.Action == MotionEventActions.Down)
                {
                    customRendererButton.OnPressed();
                }
            };
        }
    }
}

iOS :

[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]
namespace yourproject.iOS.Renderer
{
    public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);

            var customRendererButton = e.NewElement as CustomButton;

            var control = Control as UIButton;
            control.TouchDown += delegate
            {
                customRendererButton.OnPressed();
            };
            thisButton.TouchUpInside += delegate
            {
                customRendererButton.OnReleased();
            };
        }
    }
}

Then in your xaml file, link the button to custombutton :

define namespace as custom in your main tag of xaml:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:custom="clr-namespace:yourproject.Core.namespaceofCustomButton;assembly=yourproject.Core">

then,

<custom:CustomButton x:Name="CustomButton"

Then in UI you can access as below :

CustomButton.OnPressed += (sender, args) =>
{
    //Your code
};

CustomButton.OnReleased += (sender, args) =>
{
     //Your code.
};

Hope this helps!!

1
votes

You could use x:Name="myButton" in your xaml and then:

myButton.Touch += (object sender, TouchEventArgs args) =>
{
    if (args.Event.Action == MotionEventActions.Up)
    {
        myButton.BackgroundColor = Color.Blue;
    }

    else if (args.Event.Action == MotionEventActions.Down)
    {
        myButton.BackgroundColor = Color.Red;
    }
};