Declarative event handlers in Xamarin Android
In Android applications the UI components are totally isolated from associated activity so to ‘glue’ them you need to follow a ‘javascript like’ approach: find the element fist and then interact with it. Let’s say you have a .axml file containing a button with id MyButton
<Button android:id="@+id/MyButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/Hello" />
in the associated activity, to subscribe its Click event you have to write this code:
public class MainActivity : Activity { int count = 1; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); Button button = FindViewById<Button>(Resource.Id.MyButton); button.Click += button_Click; } void button_Click(object sender, EventArgs e) { (sender as Button).Text = string.Format("{0} clicks!", count++); } }
If you, like me, come from XAML and love the declarative approach I’ve got a good new for you, there’s an alternative, just follow this steps:
1-Add a reference to Mono.Android.Export library
2-Declare you handler in .axml file this way:
<Button android:id="@+id/MyButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/Hello" android:onClick="myHandler"/>
3-Refactor the code in associated activity this way:
public class MainActivity : Activity { int count = 1; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); } [Java.Interop.Export("myHandler")] public void button_Click(View v) { (v as Button).Text = string.Format("{0} clicks!", count++); } }
And you’re done!
As you see the trick is to export the function, using the Java.Interop.Export attribute that also allows you to use a export the method with a different name, leave it empty if you don’t need to differentiate.
Lot simpler, and cleaner… IMHO