Building your first end-to-end Cross Platform app – Part 3 – Android App

Building your first end-to-end Cross Platform app – Part 3 – Android App

Hello and Welcome again to the third part of the series.  Till now we have created Weather.Common (Building your first end-to-end Cross Platform app) and Weather.Windows Building your first end-to-end Cross Platform app – Part 2 – Windows Universal App) . Now, we will be creating an android app which can run on phone and tablets, so let’s begin.

Step 1: Add a new android project to the solution.

image

Step 2: Add reference to Weather.Common project and the following dll’s.

image

Step 3: Delete MainActivity.cs and add a class DebugTrace for tracing warning and errors.

public class DebugTrace : IMvxTrace
    {
        public void Trace(MvxTraceLevel level, string tag, Func<string> message)
        {
            Debug.WriteLine(tag + ":" + level + ":" + message());
        }

        public void Trace(MvxTraceLevel level, string tag, string message)
        {
            Debug.WriteLine(tag + ":" + level + ":" + message);
        }

        public void Trace(MvxTraceLevel level, string tag, string message, params object[] args)
        {333333
            try
            {
                Debug.WriteLine(string.Format(tag + ":" + level + ":" + message, args));
            }
            catch (FormatException)
            {
                Trace(MvxTraceLevel.Error, tag, "Exception during trace of {0} {1}", level, message);
            }
        }
    }

Step 4: Now add a class called Setup.

public class Setup : MvxAndroidSetup
    {
        public Setup(Context applicationContext) : base(applicationContext)
        {
        }

        protected override IMvxApplication CreateApp()
        {
            return new App();
        }
		
        protected override IMvxTrace CreateDebugTrace()
        {
            return new DebugTrace();
        }
    }

Step 5: Now add a class called LinkerPleaseInclude.cs.

public class LinkerPleaseInclude
    {
        public void Include(Button button)
        {
            button.Click += (s,e) => button.Text = button.Text + "";
        }

        public void Include(CheckBox checkBox)
        {
            checkBox.CheckedChange += (sender, args) => checkBox.Checked = !checkBox.Checked;
        }
        
        public void Include(Switch @switch)
        {
            @switch.CheckedChange += (sender, args) => @switch.Checked = [email protected];
        }

        public void Include(View view)
        {
            view.Click += (s, e) => view.ContentDescription = view.ContentDescription + "";
        }

        public void Include(TextView text)
        {
            text.TextChanged += (sender, args) => text.Text = "" + text.Text;
			text.Hint = "" + text.Hint;
        }
        
        public void Include(CheckedTextView text)
        {
            text.TextChanged += (sender, args) => text.Text = "" + text.Text;
            text.Hint = "" + text.Hint;
        }

        public void Include(CompoundButton cb)
        {
            cb.CheckedChange += (sender, args) => cb.Checked = !cb.Checked;
        }

        public void Include(SeekBar sb)
        {
            sb.ProgressChanged += (sender, args) => sb.Progress = sb.Progress + 1;
        }

        public void Include(Activity act)
        {
            act.Title = act.Title + "";
        }

        public void Include(INotifyCollectionChanged changed)
        {
            changed.CollectionChanged += (s,e) => { var test = string.Format("{0}{1}{2}{3}{4}", e.Action,e.NewItems, e.NewStartingIndex, e.OldItems, e.OldStartingIndex); } ;
        }

        public void Include(ICommand command)
        {
            command.CanExecuteChanged += (s, e) => { if (command.CanExecute(null)) command.Execute(null); };
        }
		
		public void Include(Cirrious.CrossCore.IoC.MvxPropertyInjector injector)
		{
			injector = new Cirrious.CrossCore.IoC.MvxPropertyInjector ();
		} 

		public void Include(System.ComponentModel.INotifyPropertyChanged changed)
		{
			changed.PropertyChanged += (sender, e) =>  {
				var test = e.PropertyName;
			};
		}
    }

Step 6: Add a splash.png file under folder Resources\drawable.

Step 7: Add a SplashScreen.axml file under folder Resources\layout.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</LinearLayout>

Step 8: Add a MvxBindingAttributes.xml file under folder Resources\values.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="MvxBinding">
    <attr name="MvxBind" format="string"/>
    <attr name="MvxLang" format="string"/>
  </declare-styleable>
  <declare-styleable name="MvxControl">
    <attr name="MvxTemplate" format="string"/>
  </declare-styleable>
  <declare-styleable name="MvxListView">
    <attr name="MvxItemTemplate" format="string"/>
    <attr name="MvxDropDownItemTemplate" format="string"/>
  </declare-styleable>
  <declare-styleable name="MvxExpandableListView">
    <attr name="GroupItemTemplate" format="string"/>
  </declare-styleable>
  <item type="id" name="MvxBindingTagUnique"/>
  <declare-styleable name="MvxImageView">
    <attr name="MvxSource" format="string"/>
  </declare-styleable>
</resources>

Step 9: Add a SplashScreen.cs file to the project.

[Activity(
		Label = "Weather"
		, MainLauncher = true
		, Icon = "@drawable/icon"
		, Theme = "@style/Theme.Splash"
		, NoHistory = true
		, ScreenOrientation = ScreenOrientation.Portrait)]
    public class SplashScreen : MvxSplashScreenActivity
    {
        public SplashScreen()
            : base(Resource.Layout.SplashScreen)
        {
        }
    }

Step 10: Create a folder called Views and then add FirstView.cs file to it.

[Activity(Label = "Weather")]
    public class FirstView : MvxActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.FirstView);
        }
    }

Step 11: Add FirstView.axml file under folder Resources\ layout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:layout_width="wrap_content">
        <LinearLayout
            android:orientation="vertical"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content">
            <TextView
                android:text="City : "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp" />
            <TextView
                android:text="Date : "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp" />
            <TextView
                android:text="Temp : "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp" />
        </LinearLayout>
        <LinearLayout
            android:orientation="vertical"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                local:MvxBind="Text DailyTempraure.City" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                local:MvxBind="Text DailyTempraure.ShortDate" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20dp"
                local:MvxBind="Text DailyTempraure.Temprature" />
        </LinearLayout>
    </LinearLayout>
    <Button
        android:text="Prev"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        android:id="@+id/buttonprevious"
        local:MvxBind="Click PreviousCommand; Enabled IsPrevious"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true" />
    <Button
        android:text="Next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="10dp"
        android:id="@+id/buttonNext"
        local:MvxBind="Click NextCommand; Enabled IsNext"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true" />
</RelativeLayout>

Step 12: Verify if Resource.Designer.cs file exits under folder Resources and has the above content if not then add a new file.

[assembly: global::Android.Runtime.ResourceDesignerAttribute("WeatherAndroid.Resource", IsApplication=true)]

namespace WeatherAndroid
{
	
	
	[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
	public partial class Resource
	{
		
		static Resource()
		{
			global::Android.Runtime.ResourceIdManager.UpdateIdValues();
		}
		
		public static void UpdateIdValues()
		{
		}
		
		public partial class Attribute
		{
			
			// aapt resource value: 0x7f010005
			public const int GroupItemTemplate = 2130771973;
			
			// aapt resource value: 0x7f010000
			public const int MvxBind = 2130771968;
			
			// aapt resource value: 0x7f010004
			public const int MvxDropDownItemTemplate = 2130771972;
			
			// aapt resource value: 0x7f010003
			public const int MvxItemTemplate = 2130771971;
			
			// aapt resource value: 0x7f010001
			public const int MvxLang = 2130771969;
			
			// aapt resource value: 0x7f010006
			public const int MvxSource = 2130771974;
			
			// aapt resource value: 0x7f010002
			public const int MvxTemplate = 2130771970;
			
			static Attribute()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Attribute()
			{
			}
		}
		
		public partial class Drawable
		{
			
			// aapt resource value: 0x7f020000
			public const int Icon = 2130837504;
			
			// aapt resource value: 0x7f020001
			public const int monoandroidsplash = 2130837505;
			
			// aapt resource value: 0x7f020002
			public const int splash = 2130837506;
			
			static Drawable()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Drawable()
			{
			}
		}
		
		public partial class Id
		{
			
			// aapt resource value: 0x7f040000
			public const int MvxBindingTagUnique = 2130968576;
			
			// aapt resource value: 0x7f040001
			public const int button1 = 2130968577;
			
			static Id()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Id()
			{
			}
		}
		
		public partial class Layout
		{
			
			// aapt resource value: 0x7f030000
			public const int FirstView = 2130903040;
			
			// aapt resource value: 0x7f030001
			public const int SplashScreen = 2130903041;
			
			static Layout()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Layout()
			{
			}
		}
		
		public partial class Style
		{
			
			// aapt resource value: 0x7f050001
			public const int Mono_Android_Theme_Splash = 2131034113;
			
			// aapt resource value: 0x7f050000
			public const int Theme_Splash = 2131034112;
			
			static Style()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Style()
			{
			}
		}
		
		public partial class Styleable
		{
			
			public static int[] MvxBinding = new int[] {
					2130771968,
					2130771969};
			
			// aapt resource value: 0
			public const int MvxBinding_MvxBind = 0;
			
			// aapt resource value: 1
			public const int MvxBinding_MvxLang = 1;
			
			public static int[] MvxControl = new int[] {
					2130771970};
			
			// aapt resource value: 0
			public const int MvxControl_MvxTemplate = 0;
			
			public static int[] MvxExpandableListView = new int[] {
					2130771973};
			
			// aapt resource value: 0
			public const int MvxExpandableListView_GroupItemTemplate = 0;
			
			public static int[] MvxImageView = new int[] {
					2130771974};
			
			// aapt resource value: 0
			public const int MvxImageView_MvxSource = 0;
			
			public static int[] MvxListView = new int[] {
					2130771971,
					2130771972};
			
			// aapt resource value: 1
			public const int MvxListView_MvxDropDownItemTemplate = 1;
			
			// aapt resource value: 0
			public const int MvxListView_MvxItemTemplate = 0;
			
			static Styleable()
			{
				global::Android.Runtime.ResourceIdManager.UpdateIdValues();
			}
			
			private Styleable()
			{
			}
		}
	}
}

In this we have created a page which shows the city name, date and temperature on that date, along with two buttons to navigate between previous and next day’s temperature.

Hurray you’re done creating out first android app, please go ahead and run the project.

 

image
Hope you have enjoyed it and see you in part 4.

Shashank Bisen

Shashank Bisen is curious blogger and speaker who love to share his knowledge and experience which can help anyone in their day to day work.