XamarinAndroid automatically binds the View variable and xamarinandroidview
In Android programming, we must use the FindIdByView function. This is also required in Xamarin Android development. This job is boring and annoying. In conventional Android development, people have invented some ways to avoid this problem, such as Android Data Binding and butterknife. I will not elaborate on them. However, these two solutions cannot be used in Xamarin Android development. This article introduces a function to free programmers from this work. For the original article, see http://redth.codes/auto-wire-up-views-xamarin-activity /.
Run the code below.
This is an Activity.
1 using Android.App; 2 using Android.Widget; 3 using Android.OS; 4 5 namespace AndApp2 6 { 7 [Activity(Label = "AndApp2", MainLauncher = true, Icon = "@drawable/icon")] 8 public class MainActivity : Activity 9 {10 int count = 1;11 Button myButton;12 TextView txtName;13 14 protected override void OnCreate(Bundle bundle)15 {16 base.OnCreate(bundle);17 this.BindView(Resource.Layout.Main);18 19 myButton.Click += (s,e)=> {20 myButton.Text = string.Format("{0} clicks!", count++);21 txtName.Text = "Bruce";22 };23 }24 }25 }
BindView is an extension method, including SetContent and the variables that bind the View to the Activity.
Layout has a Button myButton and a TextView txtName.
The following shows the BindView extension method:
1 public static class ActivityExtensions 2 { 3 public static void BindView(this Activity activity, int layoutResId) 4 { 5 activity.SetContentView(layoutResId); 6 //Get all the View fields from the activity 7 var members = from m in activity.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 8 where m.FieldType.IsSubclassOf(typeof(View)) 9 select m;10 11 if (!members.Any())12 return;13 14 members.ToList().ForEach(m =>15 {16 try17 {18 //Find the android identifier with the same name19 var id = activity.Resources.GetIdentifier(m.Name, "id", activity.PackageName);20 //Set the activity field's value to the view with that identifier21 m.SetValue(activity, activity.FindViewById(id));22 }23 catch (Exception ex)24 {25 throw new MissingFieldException("Failed to wire up the field "26 + m.Name + " to a View in your layout with a corresponding identifier", ex);27 }28 });29 }30 }
This method uses reflection, and some people worry about its performance. However, a View with a small number of values in an Activity is negligible.
Of course, there is no problem at all. The original Article has already pointed out that an exception will be thrown if you want to use a View that does not exist in layout. This problem is actually a good solution. For example, modify the BindView function so that we can specify that all automatically bound view variables start with m, and other variables do not start with m. So far, I think it is enough to add annotations to variables to solve the problem.