Reputation: 158
I'm trying to implement the functionality of the android button through a ButtonRender. The problem occurs when I try to join ".LongClick" and ".touch", since it does not launch the long click event.
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
this.SetBackgroundResource(Resource.Drawable.button);
base.OnElementChanged(e);
Android.Widget.Button thisButton = Control as Android.Widget.Button;
thisButton.LongClickable = true;
thisButton.LongClick += delegate
{
string s = "";
};
thisButton.Touch += (object sender, Android.Views.View.TouchEventArgs e2) =>
{
if (e2.Event.Action == MotionEventActions.Down)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.Up)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.HoverExit || e2.Event.Action == MotionEventActions.Cancel)
{
.
.
.
}
else if (e2.Event.Action == MotionEventActions.Move)
{
.
.
.
}
};
}
Upvotes: 0
Views: 1442
Reputation: 16652
To invoke the event of native control, we need to create event handlers in our custom control, and together an interface which inherits from IViewController
in order to set values from renderers.
Here is my demo, first of all, create a custom button:
public class MyButton : Xamarin.Forms.Button, IMyButtonController
{
public event EventHandler Touched;
void IMyButtonController.SendTouched()
{
Touched?.Invoke(this, EventArgs.Empty);
}
public event EventHandler LongClicked;
void IMyButtonController.SendLongClicked()
{
LongClicked?.Invoke(this, EventArgs.Empty);
}
public event EventHandler Released;
void IMyButtonController.SendReleased()
{
Released?.Invoke(this, EventArgs.Empty);
}
}
The IMyButtonController
inherits from IViewController
like this:
public interface IMyButtonController : IViewController
{
void SendTouched();
void SendLongClicked();
void SendReleased();
}
Then in android project, implement the ButtonRenderer
and IMyButtonController
like this:
[assembly: ExportRenderer(typeof(MyButton), typeof(MyButtonRenderer))]
namespace ProjectNameSpace.Droid
{
public class MyButtonRenderer : Xamarin.Forms.Platform.Android.ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
if (Control != null)
{
Control.SetOnTouchListener(ButtonTouchListener.Instance.Value);
Control.LongClickable = true;
Control.SetOnLongClickListener(ButtonLongClickListener.Instance.Value);
}
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (Control != null)
{
Control.SetOnTouchListener(null);
Control.SetOnLongClickListener(null);
}
}
base.Dispose(disposing);
}
private class ButtonTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
{
public static readonly Lazy<ButtonTouchListener> Instance = new Lazy<ButtonTouchListener>(() => new ButtonTouchListener());
public bool OnTouch(Android.Views.View v, Android.Views.MotionEvent e)
{
var renderer = v.Tag as ButtonRenderer;
if (renderer != null)
{
var buttonController = renderer.Element as IMyButtonController;
if (e.Action == Android.Views.MotionEventActions.Down)
{
buttonController?.SendTouched();
}
else if (e.Action == Android.Views.MotionEventActions.Up)
{
buttonController?.SendReleased();
}
}
return false;
}
}
private class ButtonLongClickListener : Java.Lang.Object, Android.Views.View.IOnLongClickListener
{
public static readonly Lazy<ButtonLongClickListener> Instance = new Lazy<ButtonLongClickListener>(() => new ButtonLongClickListener());
public bool OnLongClick(Android.Views.View v)
{
var renderer = v.Tag as ButtonRenderer;
((IMyButtonController)renderer?.Element)?.SendLongClicked();
return true;
}
}
}
}
Upvotes: 5