How to create button pressed effect?

Hello,

I need to create a button/image/whatever that changes image while pressed to create the button pressed effect. How can i get to the 'while pressed' state? Even if using custom renderers, i cant do it. Could some one give me some hints?

Thanks

Tagged:

Answers

  • MommMomm USMember ✭✭✭

    You will need to create a CustomRenderer for the ImageRenderer and override:

    • On Android: OnTouchEvent
    • On iOS: TouchesBegan, TouchesCancelled and TouchesEnded

    These methods will have to call a EventHandler, which will change the image based on the press state.

  • @NMackay i have to use a specific image, it is not my choice, but thanks.

    @Momm thanks, can you provide a quick example?

  • NMackayNMackay GBInsider, University mod

    Not sure what you mean by a "specific image" :neutral:

  • I mean that i do not want to animate it. I've been given a button.png and button_pressed.png

  • NMackayNMackay GBInsider, University mod

    Ahhh okay.

    It's straight forward enough to change the image when you Tap it. I don't think there's any event like MouseUp currently (without implementing a custom renderer) to change the image back so you'd have to use a timer or something to check the Tapcount and change the image back. A custom renderer as @Momm suggested is your best bet probably or if it's just for Android you could use a drawable to do this kind of thing.

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <!-- Non focused states -->
      <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@color/tab_selected" />
      <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@color/tab_selected" />
    
      <!-- Focused states -->
      <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@color/tab_unselected" />
      <item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@color/tab_unselected" />
    
      <!-- Pressed -->
      <!--    Non focused states -->
      <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@color/tab_pressed" />
      <item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@color/tab_pressed" />
    
      <!--    Focused states -->
      <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@color/tab_unselected" />
      <item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@color/tab_selected" />
    </selector>
    
  • I need to do it for all three platforms. I'm open to use renderers, my problem is how to do it.

    I'm also aware i could do it using xml in android, but i don't think i can associate it with an image programatically. So i guess my only chance is to get a pressed event or something, like @Momm said. But i don't know how do it...

  • NMackayNMackay GBInsider, University mod

    If you don't have the time to figure out the customer renderer approach you could use use MrGestures.

    http://www.mrgestures.com/

    That can detect the Up on the image and change the image back. The benefit is you can do it all in the PCL (I think).

    Best asking @MichaelRumpler the author just to double check.

    The gesture support out of the box in Forms is too basic and not really extendible.

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    That's correct.

    With MR.Gestures you get the Down and Up events on Images (and all other controls). You can change the Source in those event handlers. No need to write any platform specific renderers.

  • Yes but that is a paid library.

  • Really? I asked help writing the custom renderers and all i got was you telling me to use a paid library? Are you their partner? Do you share their profit?

  • ChaseFlorellChaseFlorell CAInsider, University mod

    Yes, MRGestures is owned/created by Michael Rumpler

  • PedroNeves.7715PedroNeves.7715 USMember ✭✭

    Lol. I actually laughed. You are right. Still, i won't get the library because the project's budget won't allow it

  • TorbenKruseTorbenKruse DEMember ✭✭✭

    Nice Budget. The library is 10€. I don't think the effort of writing something like this on your own will be cheaper than this.

    If you still want to write this on your own, maybe this is a good way to start.

  • PedroNeves.7715PedroNeves.7715 USMember ✭✭
    edited October 2015

    Thanks.

    As a matter of curiosity, don't you think this is a very basic action to do in any programming platform for mobile? Is this as exotic as the need for workarounds may make it look?

  • RaleighMobileGroupRaleighMobileGroup USMember, Developer Group Leader

    @PedroNeves.7715 - Thanks for sharing the code snippet. This is exactly what i was looking for. I am also impressed with @MichaelRumpler work. Great Stuff!

  • UmairAliUmairAli USMember

    @PedroNeves.7715 You are awesome.

  • RayQuRayQu NZMember

    @PedroNeves.7715
    Hi Pedro, if I implement this in the renderer in Android, the click event in Forms no longer working. Any solution?

    @PedroNeves.7715 said:
    Answering my own question, here it goes:

    PCL:
    public class FancyButton : Button { }

    Android:
    [assembly: ExportRenderer(typeof(App2.FancyButton), typeof(FancyButtonAndroid))] namespace App2.Droid { public class FancyButtonAndroid : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) { base.OnElementChanged(e); Android.Widget.Button thisButton = Control as Android.Widget.Button; thisButton.Touch += (object sender, Android.Views.View.TouchEventArgs e2) => { if (e2.Event.Action == MotionEventActions.Down) System.Diagnostics.Debug.WriteLine("TouchDownEvent"); else if (e2.Event.Action == MotionEventActions.Up) System.Diagnostics.Debug.WriteLine("TouchUpEvent"); }; } } }

    iOS:
    [assembly: ExportRenderer(typeof(App2.FancyButton), typeof(FancyButtoniOS))] namespace App2.iOS { public class FancyButtoniOS : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); UIButton thisButton = Control as UIButton; thisButton.TouchDown += delegate { System.Diagnostics.Debug.WriteLine("TouchDownEvent"); }; thisButton.TouchUpInside += delegate { System.Diagnostics.Debug.WriteLine("TouchUpEvent"); }; } } }

    Windows Phone:
    [assembly: ExportRenderer(typeof(App2.FancyButton), typeof(FancyButtonWP))] namespace App2.WinPhone { public class FancyButtonWP : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) { base.OnElementChanged(e); System.Windows.Controls.Button thisButton = Control as System.Windows.Controls.Button; thisButton.ManipulationStarted += delegate { System.Diagnostics.Debug.WriteLine("TouchDownEvent"); }; thisButton.ManipulationCompleted += delegate { System.Diagnostics.Debug.WriteLine("TouchUpEvent"); }; } } }

  • VinnieVivaceVinnieVivace NZMember ✭✭

    @RayQu I also found the same issue as you above (Click event not firing for Android). Did you manage to resolve?

  • RayQuRayQu NZMember

    @VinnieVivace
    Yes. I call Control.CallOnClick() manually.

    case MotionEventActions.Down: //Pressed //Set text color lighter when pressed Control.SetTextColor(Android.Graphics.Color.Argb(100, defaultTextColor.R, defaultTextColor.G, defaultTextColor.B)); break; case MotionEventActions.Up: //Released Control.SetTextColor(defaultTextColor); Control.CallOnClick(); break; default: break;

  • VinnieVivaceVinnieVivace NZMember ✭✭

    @RayQu nice one, thanks very much

  • sid12sid12 INMember ✭✭

    @NMackay can u help me to add same effect of your custom Image Button to StackLayOut or somthing like that.

  • sid12sid12 INMember ✭✭

    I tried same code for stacklayout and it works..

  • Pamelarios.2249Pamelarios.2249 USUniversity ✭✭

    @PedroNeves.7715 said:
    Really? I asked help writing the custom renderers and all i got was you telling me to use a paid library? Are you their partner? Do you share their profit?

    no need to be upset . it was just a suggestion . :(

  • GarettBreenGarettBreen USMember ✭✭
    edited November 2017

    Seems like for iOS at least, in the custom renderer you could leverage the built in button.setImage which takes a state. Has anyone attempted to do it this way instead of custom handling the touchdown and touchup events?

    Here is a stackoverflow question with an example of what I mean:

    /questions/10778694/how-to-change-custom-buttons-image-when-tapping-in-ios (it won't let me post a link)

    I'll try this later and report back to see if this would work. Might be a little simpler and use some built in functionality. Still would need the custom renderer but you wouldn't have to handle the up/down yourself I believe.

  • RayGoudieRayGoudie CAMember ✭✭

    For the record, this library is no longer 10 Euros.

    @TorbenKruse said:
    Nice Budget. The library is 10€. I don't think the effort of writing something like this on your own will be cheaper than this.

    If you still want to write this on your own, maybe this is a good way to start.

  • PieterjanDeClippelPieterjanDeClippel USMember ✭✭
    edited June 2018

    Such overkill,
    It's probably better to use Paint.Net and just create a new image with adapted brightness

    using some code like this:

    private void btnLogin_Pressed(object sender, EventArgs e)
    {
        btnLogin.Image = "login_pressed.png";
    }
    
    private void btnLogin_Released(object sender, EventArgs e)
    {
        btnLogin.Image = "login.png";
    }
    

    What an irony

  • AndreiMisiukevich_AndreiMisiukevich_ USMember ✭✭✭✭

    That's really what you look for https://github.com/AndreiMisiukevich/TouchEffect

  • bifedefrangobifedefrango Member ✭✭

    you just need this, no plugins needed

    <ImageButton BackgroundColor="Transparent"
                            HeightRequest = "90" 
                            Source="budget"
                            Clicked="Budget_btnClicked">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal">
                                            <VisualState.Setters>
                                                <Setter Property="Scale"
                                                    Value="1" />
                                            </VisualState.Setters>
                                        </VisualState>
    
                                        <VisualState x:Name="Pressed">
                                            <VisualState.Setters>
                                                <Setter Property="Scale"
                                                    Value="0.8" />
                                            </VisualState.Setters>
                                        </VisualState>
    
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </ImageButton>
    
Sign In or Register to comment.