Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Follow this walkthrough to migrate your Crosslight Android Classic to Crosslight Android Material. At the end of this tutorial, you should have the following result:

Panel

Samples:

basic-inventory.zip

Follow these steps:

Table of Contents
maxLevel3
stylecircle

Anchor
preqreuisite
preqreuisite

Prerequisite

Prerequisites

It is recommended that you have read through these conceptual topics in order to get a better understanding:

To use this walkthrough, you will need to use at least Crosslight version 5.0.500.545 543 in order to achieve the desired result.

Let's get started. 

Configuring Your Project

  1. Open your Crosslight Android Classic application. In this walkthrough, let's try to migrate the MyInventory classic sample to use the new Crosslight Android Material Design.
  2. Open the project properties, and set the TargetFramework to Android 5.0 (Lollipop)
  3. Afterwards, set the Minimum Android version to 4.0.3 (API Level 15) and Target Android version (API Level 21)
  4. Install the Crosslight Android v7 Nuget NuGet Package using the Intersoft Package Manager Console. 

    To learn more on how to use Crosslight NuGet Packages, see Introduction to Crosslight NuGet Packages.

    Modern note

    To use the Intersoft Package Manager Console, you need to have properly installed Intersoft Mobile Studio 2016 and above.

  5. Ensure that the Crosslight references and its dependencies are properly installed.

Applying Crosslight Android Material Theme

  1. To properly incorporate Android Material theme to your application, you can simply use one of the two built-in Crosslight themes that are designed specifically for Material Design: Theme.Crosslight.Material and Theme.Crosslight.Material.Light. It is most recommended to use the default Theme.Crosslight.Material.Light theme. 

    Code Block
    languagexml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <uses-sdk android:minSdkVersion="15" />
        <application android:theme="@style/Theme.Crosslight.Material.Light" android:label="MyInventory"></application>
    </manifest>
  2. Copy-paste the following code to the colors.xml file located inside Android/Resources/values/ folder.

    Code Block
    languagec#
    <?xml version="1.0" encoding="utf-8" ?>
    <resources>
      <color name="primary">#673AB7</color>
      <color name="accent">#7E57C2</color>
      <color name="navigation_bar">#9575CD</color>
      <color name="primary_dark">#7E57C2</color>
      <color name="window_background">#eaeaea</color>
      <color name="action_menu_background">#673AB7</color>
      <color name="window_dark_background">#000000</color>
      <color name="window_light_background">#ffffff</color>
    
      <color name="action_menu_foreground">#ffffff</color>
      <color name="button_foreground">#ffffff</color>
    
      <color name="progress_dialog_background">#673AB7</color>
      <color name="progress_text_color">#ffffff</color>
      <color name="progress_bar_color">#ffffff</color>
      <color name="progress_text_color_inverse">#7E57C2</color>
      <color name="progress_bar_color_inverse">#7E57C2</color>
    </resources>
  3. Clean up old styles or resources as they are no longer relevant.

Converting Your Activities and Fragments to Crosslight Material Fragments

There are several fundamental principles when converting classic Activities to new Material Fragments:

  • Activity is now only used as view container and very minimal Activities definitions are needed. In most cases, you'll only need StartActivity, DrawerActivity, and SearchActivity.
  • Configuring layout id and other properties and behaviors still use property overrides.
  • Assigning values that are considered as settings should be done in the Initialize method (override as needed) in the Fragment level and you can directly set the property there.
  • To configure bar items, you can still use menu AXML. Although, it is very much recommended to use the new Crosslight Android Material's new API with predefined CommandItemTypes which will allow you to define bar items easily.
  • Crosslight Android Material provides you with some built-in layout and styles so you do not need to provide it, unless you want to change it. See the complete reference here: Crosslight Android Material Theme Reference.
  • To learn how to configure more settings and behaviors introduced in Material Fragment, see Defining Android Material Views.
  1. Converting ListActivity
    Since the ListActivity is the main Activity, this needs to be converted into an Activity for view container and Fragment as it content view. For example, here's how the old ItemListActivity looks like.

    Code Block
    titleClassic ItemListActivity
    languagec#
    using Android.App;
    using Android.Content.PM;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android
    {
        [ImportBinding(typeof(ItemListBindingProvider))]
        [Activity(Label = "My Inventory", LaunchMode = LaunchMode.SingleTop, Icon = "@drawable/icon")]
        public class ItemListActivity : SearchableListActivity<ItemListViewModel>
        {
            #region Properties
    
            protected override ContextualActionBarSettings ContextualActionBarSettings
            {
                get
                {
                    return new ContextualActionBarSettings
                    {
                        ActionBarLayoutId = Resource.Layout.contextualactionbarlayout,
                        MenuCheckAllId = Resource.Id.MenuCheckAll,
                        MenuMoreId = Resource.Id.MenuMore,
                        PopupMenuLayoutId = Resource.Layout.popupmenulayout
                    };
                }
            }
    
            public override EditingOptions EditingOptions
            {
                get { return EditingOptions.AllowEditing | EditingOptions.AllowMultipleSelection; }
            }
    
            protected override int GroupItemLayoutId
            {
                get { return Resource.Layout.ItemGroupLayout; }
            }
    
            public override ListViewInteraction InteractionMode
            {
                get { return ListViewInteraction.Navigation; }
            }
    
            protected override int ListItemLayoutId
            {
                get { return Resource.Layout.ItemListLayout; }
            }
    
            protected override int MenuLayoutId
            {
                get { return Resource.Layout.actionbarlistlayout; }
            }
    
            protected override int SearchButtonId
            {
                get { return Resource.Id.SearchButton; }
            }
    
            public override string SearchScope
            {
                get { return "Name"; }
            }
    
            #endregion
    
            #region Methods
    
            protected override void InitializeView()
            {
                base.InitializeView();
    
                this.RegisterViewIdentifier("TableView", this.ListView);
            }
    
            #endregion
        }
    }


    Here's the new file AppCompatActivity that will act as the view container. You can safely remove the previous ItemListActivity and replace it with the new AppCompatActivity.

    Code Block
    titleMaterial AppActivity
    languagec#
    using System;
    using Android.App;
    using Android.Runtime;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android.v7;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android
    {
        [Activity()]
        public class AppActivity : AppCompatActivity<ItemListViewModel>
        {
            #region Constructors
    
            public AppActivity()
            {
    
            }
    
            public AppActivity(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
    
            }
            #endregion
        }
    }


    Introduce a new ItemListFragment that inherits the new SearchableRecyclerViewFragment available in the v7 library.

    Code Block
    titleItemListFragment
    languagec#
    using System;
    using Android.Graphics;
    using Android.Graphics.Drawables;
    using Android.Runtime;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android;
    using Intersoft.Crosslight.Android.v7;
    using Intersoft.Crosslight.Android.v7.ComponentModels;
    using MyInventory.ViewModels;
    using EditAction = Intersoft.Crosslight.Android.v7.ComponentModels.EditAction;
    
    namespace MyInventory.Android
    {
        [ImportBinding(typeof(ItemListBindingProvider))]
        [RegisterNavigation(DeviceKind.Phone)]
        public class ItemListFragment : SearchableRecyclerViewFragment<ItemListViewModel>
        {
            #region Constructors
    
            public ItemListFragment()
            {
    
            }
    
            public ItemListFragment(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
    
            }
    
            #endregion
    
            #region Properties
    
            protected override int ItemLayoutId
            {
                get { return Resource.Layout.item_layout; }
            }
    
            #endregion
    
            #region Methods
    
            protected override void Initialize()
            {
                base.Initialize();
    
                this.ImageLoaderSettings.AnimateOnLoad = true;
                this.Appearance.Background = new ColorDrawable(Color.WhiteSmoke);
                this.ShowGroupSeparator = false;
    
                // Defines floating action button.
                this.FloatingActionButtons.Add(new FloatingActionButton("AddButton")
                {
                    Position = FloatingActionButtonPosition.BottomRight,
                    CommandItemType = CommandItemType.Add,
                    Direction = FloatingActionButtonDirection.Up,
                    HideOnScrollUp = true
                });
    
                // Defines contextual action.
                ListContextualToolbarSettings settings = this.ContextualToolbarSettings as ListContextualToolbarSettings;
                if (settings != null)
                {
                    settings.Mode = ContextualMode.Default;
                    settings.CheckAllEnabled = true;
                    settings.CheckAllMargin = 4;
                    settings.BarItems.Add(new BarItem("DeleteButton", "Delete"));
                    settings.BarItems.Add(new BarItem("MarkSoldButton", "Mark As Sold"));
                }
    
                // Defines editing action from swipe gesture.
                this.EditActions.Add(new EditAction("Sold"));
                this.EditActions.Add(new EditAction("Delete", true));
    
                // Recycler View configuration
                this.InteractionMode = ListViewInteraction.Navigation;
                this.EditingOptions = EditingOptions.AllowEditing | EditingOptions.AllowMultipleSelection;
    
                // Defines shared elements
                this.SourceSharedElementIds.Add(Resource.Id.Icon);
    
                this.AddBarItem(new BarItem("SearchButton", CommandItemType.Search));
    
                this.FilterScope = "Name";
                this.IconId = Resource.Drawable.ic_toolbar;
            }
    
            #endregion
        }
    }
  2. Converting ItemEditActivity. The old FormActivity used to look like this.

    Code Block
    titleClassic ItemEditActivity
    languagec#
    using Android.App;
    using Intersoft.Crosslight.Android;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android
    {
        [Activity(Label = "Edit Item", Icon = "@drawable/icon")]
        public class ItemEditActivity : FormActivity<ItemEditorViewModel>
        {
            #region Properties
    
            protected override int MenuLayoutId
            {
                get { return Resource.Layout.actionbareditinglayout; }
            }
    
            protected override bool ShowActionBarUpButton
            {
                get { return true; }
            }
    
            #endregion
        }
    }


    You can safely delete the file altogether and replace it with the new FormFragment. With the new Crosslight v7 library, you don't have to deal with creating Activities anymore. Also, you don't have to specify the ShowActionBarUpButton behavior as this is automatic. You need to provide a new constructor overload that accepts one IntPtr object and one JniHandleOwnership object as this is needed for Fragment initialization.

    Code Block
    titleMaterial ItemEditFragment
    languagec#
    using System;
    using Android.Runtime;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android.v7;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android
    {
        [ImportBinding(typeof(ItemListBindingProvider))]
        public class ItemEditFragment : FormFragment<ItemEditorViewModel>
        {
            #region Constructors
    
            public ItemEditFragment()
            {
    
            }
    
            public ItemEditFragment(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
    
            }
    
            #endregion
    
            #region Methods
    
            protected override void Initialize()
            {
                base.Initialize();
    
                this.AddBarItem(new BarItem("SaveButton", CommandItemType.Done));
            }
    
            #endregion
        }
    }

    To add the bar item, you can simply take advantage of the new AddBarItem method that is provided in the new Fragment library. You can use this API in all Fragments existed in the new v7 library. Now that you've got your new FormFragment ready, let's proceed by converting ViewImageActivity next.

  3. The old ViewImageActivity used to look like this.

    Code Block
    titleClassic ViewImageActivity
    languagec#
    using Android.App;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android.Activities
    {
        [Activity(Label = "View Image", Icon = "@drawable/icon")]
        [ImportBinding(typeof(ItemDetailBindingProvider))]
        [RegisterNavigation("PhotoDetail")]
        public class ViewImageActivity : Activity<ItemDetailViewModel>
        {
            #region Constructors
    
            public ViewImageActivity()
                : base(Resource.Layout.viewimagelayout)
            {
    
            }
    
            #endregion
        }
    }

    Let's convert this to a Fragment instead.

    Code Block
    titleMaterial ViewImageFragment
    languagec#
    using System;
    using Android.Runtime;
    using Intersoft.Crosslight;
    using Intersoft.Crosslight.Android.v7;
    using MyInventory.ViewModels;
    
    namespace MyInventory.Android
    {
        [ImportBinding(typeof(ItemDetailBindingProvider))]
        [RegisterNavigation("PhotoDetail")]
        public class ViewImageFragment : Fragment<ItemDetailViewModel>
        {
            #region Constructors
    
            public ViewImageFragment()
            {
    
            }
    
            public ViewImageFragment(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
    
            }
    
            #endregion
    
            #region Properties
    
            protected override int ContentLayoutId
            {
                get { return Resource.Layout.view_image_layout; }
            }
    
            #endregion
        }
    }

    At a first glance, the new Fragment definition seems longer and more tedious. However, it is more consistent. Previously, it was quite confusing determining which view context can accept a layout ID in the constructor, and which ones cannot. In this new library, the process is streamlined to overriding ContentLayoutId instead, making it more consistent, no matter what view context you're dealing with. Next, let's upgrade the look and feel of the existing item list to use CardView. Open up the item_layout.axml inside the Resources/layout folder and use the following code.

    Code Block
    languagec#
    <?xml version="1.0" encoding="utf-8"?>
    <intersoft.crosslight.android.v7.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        app:cardElevation="2dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="80dp">
            <ImageView
                android:layout_width="72dp"
                android:layout_height="72dp"
                android:id="@+id/Icon"
                android:layout_margin="4dp"
                android:gravity="center_vertical"
                android:layout_centerVertical="true" />
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/Icon"
                android:gravity="center_vertical"
                android:layout_centerVertical="true"
                android:orientation="vertical">
                <TextView
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:id="@+id/TextLabel"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:singleLine="true" />
                <TextView
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:id="@+id/Text2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:singleLine="true" />
            </LinearLayout>
        </RelativeLayout>
    </intersoft.crosslight.android.v7.CardView>

    You can now take advantage of modern view libraries and properties available in v7 libraries, such as the CardView and view properties like app:cardElevation to give your apps a modern Material look.

Conclusion

Congratulations! You've just finished migrating your MyInventory application from classic android to Material Android.

Sample

You can check out the old project here: http://git.intersoftsolutions.com/projects/CROS/repos/samples/browse/MyInventory and the new project here: http://git.intersoftsolutions.com/projects/CS/repos/basic-inventory/browse.

If you wish to run the sample, simply download the new project and open using Xamarin Studio or Visual Studio and hit Run.

 

Related Topics

Content by Label
spacescrosslight
showLabelsfalse
max5
sorttitle
labelsandroid-material -migrating-to-android-material
showSpacefalse
typepage