xamarin.forms - How to make Xamarin bubble up gestures -
i'm in process of developing sidedrawer xamarin.forms, because @ point, 1 telerik rather awful sideeffect-wise.
i know how in wpf, since it's rather easy, in xamarin it's way different.
my code gestureframe pretty same this.
i've used sources @ some github project/xamarin docs/xlabs started. @ first going well, i'm placing controls within gestureframe not receive events anymore, because childcontrols appear consume touch/gesture events there are.
does ring bell anyone? right i'm not sure might doing wrong control behave way
the gestures xamarin forms handles tap , doubletap these bubble default. android, windows , presumably ios each handle other gestures differently.
quick review of event handling in xamarin.forms world:
on android gestures handled renderer each renderer has touch event. touch raised in renderer when gesture occurs. subscribing touch event , intupreting eventargs can determine happening on screen. make determinations of user doing or use mono.android.gesturedetector make decisions you. gesturedetector requires gesturelistener notifies when believes event tap or double have occured. gesture listener can contain whatever code want respond these events.
on windows each native control determines when event has occurred , exposes set of eventhandlers events. respond these events create custom renderer , subscribe events on native controls execute own code.
on ios? don't know yet haven't got far in project https://github.com/indiponics/indixam-lib maybe else can give piece.
bubbling events lets @ simple bubbling situation:
public class app : application { public app() { // root page of application mainpage = new contentpage { content = new frame { content = new label { text = "hold me, thrill me, kiss me" } } }; } }
lets put custom renderers , @ whats happening. start we'll need renderer every control in stack in our case label renderer , frame renderer.
we'll start windows:
[assembly: exportrenderer(typeof(label), typeof(mylabelcustomrenderer))] [assembly: exportrenderer(typeof(frame), typeof(myframecustomrenderer))] namespace app4.winphone { public class myframecustomrenderer:framerenderer { protected override void onelementchanged(elementchangedeventargs<xamarin.forms.frame> e) { base.onelementchanged(e); if(e.newelement!=null) { this.control.hold += control_hold; } } void control_hold(object sender, system.windows.input.gestureeventargs e) { system.diagnostics.debug.writeline("frame held"); e.handled = false; } } public class mylabelcustomrenderer : labelrenderer { protected override void onelementchanged(elementchangedeventargs<xamarin.forms.label> e) { base.onelementchanged(e); if (e.newelement != null) { this.control.hold += control_hold; } } void control_hold(object sender, system.windows.input.gestureeventargs e) { system.diagnostics.debug.writeline("label held"); e.handled = false; } } }
running find bubbling occurs default in windows. if wanted turn off bubbling changing
e.handled = true;
in our label renderer , frame never notified of hold event.
now android on android things bit messier. again we'll create 2 renderers.
[assembly: exportrenderer(typeof(label), typeof(mylabelcustomrenderer))] [assembly: exportrenderer(typeof(frame), typeof(myframecustomrenderer))] namespace app4.droid { public class myframecustomrenderer : framerenderer { protected override void onelementchanged(elementchangedeventargs<xamarin.forms.frame> e) { base.onelementchanged(e); if (e.newelement != null) { this.touch += myframecustomrenderer_touch; } } void myframecustomrenderer_touch(object sender, android.views.view.toucheventargs e) { system.diagnostics.debug.writeline("you touched frame"); e.handled = false; } } public class mylabelcustomrenderer : labelrenderer { protected override void onelementchanged(elementchangedeventargs<xamarin.forms.label> e) { base.onelementchanged(e); if (e.newelement != null) { this.touch += myframecustomrenderer_touch; } } void myframecustomrenderer_touch(object sender, android.views.view.toucheventargs e) { system.diagnostics.debug.writeline("you touched label"); e.handled = false; } } }
if run appears works same windows geta touch event in label , touch event in frame. bubbling appears automatic. gets messy when attempt disable bubbling. if change
e.handled=true;
in label renderer , run app again--- touch fires twice in label renderer. once when touch screen , once when stop. if set labelrenderer's e.handled=false; , set frame true. label touch fires followed frame frame fires second time.
in addition if remove e.handled=false both renderer , run app find labelrenderer's touch event fires. implying default handled appears true. if not set e.handled=false in renderer event fire in labelrenderer , not bubble stack framerenderer.
in conclusion: bubbling works out of box on windows. on android doesn't work might expect. first have explicitly set handled=false in every child parent gets notification , handler handled event gets notified touch event ended rest of stack gets notified of start never knows over.
Comments
Post a Comment