xamarin-android/Documentation
Dean Ellis 7c31899b04 [Xamarin.Android.Build.Tasks] Add Support for CodeBehind for layout files (#1238)
Support generating CodeBehind files for `.axml` layout files. This
removes the need to call `FindViewById<T>()` manually, as properties
generated into the CodeBehind file will call it instead.

The CodeBehind files are generated for all `.axml` files with a build
action of `@(AndroidResource)` *and* contain an XML namespace to
`http://schemas.android.com/tools` and a `tools:class` attribute
that contains the name of the `partial class` to generate:

	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	    android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"
	    xmlns:tools="http://schemas.xamarin.com/android/tools"
	    tools:class="UnnamedProject.MainActivity"> 
	  <Button
	      android:id="@+id/myButton"
	      android:layout_width="fill_parent"
	      android:layout_height="wrap_content"
	      android:text="@string/hello"
	  />
	</LinearLayout> 

The generated CodeBehind partial class will use the value of the
`//@tools:class` attribute, and will contain a property for each
element with an `//@android:id` attribute. The `//@android:id`
attribute is the name of a generated field, while the containing
element name is the type of the property.

The above XML fragment would partially produce:

	partial class MainActivity {
	  // Call instead of `SetContentView()`
	  private void InitializeContentView ();

	  // Called if `myButton` can't be found
	  partial void OnLayoutViewNotFound<T> (int resourceId, ref T type)
	    where T : global::Android.Views.View;

	  // One property per //@android:id
	  // Throws InvalidOperationException if it can't be found
	  public Button myButton { get; }
	}

This allows replacing the current code pattern of:

	SetContentView (Resource.Layout.NameOfLayoutFilename);
	var button = FindViewById<Button> (Resource.Id.myButton);
	button.Click += delegate {
	};

and instead rely on the CodeBehind properties:

	InitializeContentView ();
	myButton.Click += delegate {
	};

There are two other requirements to make this work:

 1. All declarations of the class specified by the `//@tools:class`
    attribute must be `partial` classes, otherwise a CS0260 error
    will be produced at build time.
 
 2. `InitializeContentView()` must be called instead of
    `SetContentView()`. `InitializeContentView()` itself calls
    `SetContentView()`, providing the `@(AndroidResource)` filename
    as the layout to use.

This feature was originally prototyped by @grendello.

The following is a sample of the kind of code which will be
generated by this new system:

	namespace UnnamedProject {
	  using System;
	  using Android.App;
	  using Android.Widget;
	  using Android.Views;
	  using Android.OS;

	  // Generated from layout file 'Resources/layout/Main.axml'
	  public partial class MainActivity {

	    private Func<Button> @__myButtonFunc;
	    private Button @__myButton;

	    partial void OnLayoutViewNotFound<T> (int resourceId, ref T type)
	      where T : global::Android.Views.View;

	    public Button myButton {
	      get {
	        if (@__myButtonFunc == null) {
	          @__myButtonFunc = this.@__Create_myButton;
	        }
	        return this.@__EnsureView<Button>(this.@__myButtonFunc, ref this.@__myButton);
	      }
	    }

	    private void InitializeContentView() {
	      this.SetContentView(Resource.Layout.Main);
	    }

	    private T @__FindView<T>(global::Android.Views.View parentView, int resourceId)
	      where T : global::Android.Views.View
	    {
	      T view = parentView.FindViewById<T>(resourceId);
	      if ((view == null)) {
	        this.OnLayoutViewNotFound(resourceId, ref view);
	      }
	      if ((view != null)) {
	        return view;
	      }
	      throw new System.InvalidOperationException($"View not found (ID: {resourceId})");
	    }

	    private T @__FindView<T>(global::Android.App.Activity parentView, int resourceId)
	      where T : global::Android.Views.View
	    {
	      T view = parentView.FindViewById<T>(resourceId);
	      if ((view == null)) {
	        this.OnLayoutViewNotFound(resourceId, ref view);
	      }
	      if ((view != null)) {
	        return view;
	      }
	      throw new System.InvalidOperationException($"View not found (ID: {resourceId})");
	    }

	    private T @__FindView<T>(global::Android.App.Fragment parentView, int resourceId)
	      where T : global::Android.Views.View
	    {
	      return this.@__FindView<T>(parentView.Activity, resourceId);
	    }

	    private T @__EnsureView<T>(System.Func<T> creator, ref T field)
	      where T : class
	    {
	      if ((field != null)) {
	        return field;
	      }
	      if ((creator == null)) {
	        throw new System.ArgumentNullException(nameof (creator));
	      }
	      field = creator();
	      return field;
	    }

	    private Button @__Create_myButton() {
	      return this.@__FindView<Button>(this, Resource.Id.myButton);
	    }
	  }
	}
2018-02-09 11:29:47 -05:00
..
DevelopmentTips.md [build] Use .csproj files, not .mdproj files (#1271) 2018-02-05 09:30:23 -05:00
HowToAddNewApiLevel.md [Mono.Android] API-26 Enumification (#662) 2017-08-03 05:12:27 -07:00
InstantApps.md [docs] Move InstantApps.md into Documentation 2017-09-11 09:36:56 -04:00
LayoutCodeBehind.md [Xamarin.Android.Build.Tasks] Add Support for CodeBehind for layout files (#1238) 2018-02-09 11:29:47 -05:00
UsingJenkinsBuildArtifacts.md [setup-windows] Link Xamarin.Android.Sdk{.props,.targets} (#854) 2017-09-14 10:59:57 -04:00
VS-Extensions-Revert.png [docs] Improve `.vsix` installation instructions (#661) 2017-06-22 11:44:22 -07:00
VSIX-Installer.png [docs] Improve `.vsix` installation instructions (#661) 2017-06-22 11:44:22 -07:00
banner.png [README] Add Xamarin.Android banner (#432) 2017-02-09 17:14:11 -05:00
binfmt_misc-warning-Linux.txt [mono-runtimes] Build AOT+LLVM cross-compilers (#125) 2016-07-26 09:27:31 -04:00
build_process.md [Xamarin.Android.Build.Tasks] Add `AndroidAarLibrary` Build Action (#1268) 2018-02-07 20:58:57 -05:00
exploring_sources.md Add first documentation: exploring_sources.md 2016-05-25 18:33:41 +09:00