XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2015/09/30

Xamarin.Android Templates Pack 範本解密2

我們有方案總管的畫面目錄結構,由上而下來開始解析,首先來了解 [BaseActivity.cs]。
當我們使用這個專案範本的時候,所有的 Activity 都是繼承了 BaseActivity,而 BaseAcitity 則是繼承了 AppCompatActivity。
[Android Support v7 AppCompat] 這個套件,讓我們可以使用 Android 5.0 Lollipop系統內的 Material Desigan 相關 UI,並且可以讓之前舊 Android 版本也可以跑這個App。當我們從 Xamarin Component Store 或者 NuGet 內安裝了 Support Library v7 AppCompat,Support v4 程式庫也會安裝進來,而我們使用的這個專案範本,已經自動幫我們加入進來了,所以,我們就可以直接使用 AppCompatActivity類別。
image
底下列出了 BaseActivity 類別的定義,我們可以看到他定義了 Toolbar 這個物件,這個物件是屬於 Toolbar 這個類別,而 Toolbar 的UI則是在 Android 5.0系統裡才會有的,如同前面所述,我們可以讓Android 5.0之前的作業系統,也可以使用這樣的物件功能。
在 OnCreate 方法內,當系統內有 Toolbar UI的時候,我們呼叫了 SetSupportActionBar這個方法,這讓 Toolbar 的行為會如同 Actionbar 一樣;SupportActionBar.SetDisplayHomeAsUpEnabled(true)則是允許讓我們移動到上一個畫面中,也就是起用了上一層按鈕功能;SupportActionBar.SetHomeButtonEnable(true)則是啟用了回首頁的功能
namespace AndroidNavigationDrawerAppCompat.Activities
{
    public abstract class BaseActivity : AppCompatActivity
    {
        public Toolbar Toolbar
        {
            get;
            set;
        }
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(LayoutResource);
            Toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
            if (Toolbar != null)
            {
                SetSupportActionBar(Toolbar);
                SupportActionBar.SetDisplayHomeAsUpEnabled(true);
                SupportActionBar.SetHomeButtonEnabled(true);
            }
        }

        protected abstract int LayoutResource
        {
            get;
        }

        protected int ActionBarIcon
        {
            set { Toolbar.SetNavigationIcon(value); }
        }
    }
}

在底下,我們說明了 MainActivity.cs 這個檔案內的內容,您可以參考註解說明。

在 MainActivity內,定義了兩個變數 drawerLayout & navigationView,透過這兩個變數的設定,可以讓您的App輕鬆做到有滑動子視窗的預覽列功能,在預覽列中,我們可以透過功能表的定義出各項App提供的子功能,讓使用者方便選擇與使用。

另外,在OnCreate方法內,我們也看到了 Google Metrial Design的新功能 Snackbar.Make,透過 Snackbar物件,我們可以取代將之前Toast要提供功能。

在OnCreate方法內,我們則是透過了 CloseDrawers()方法,將浮動導覽列收合起來。
namespace AndroidNavigationDrawerAppCompat.Activities
{
    // 定義了該 Activity 為程式啟動的主要第一個畫面,
    // 該App的名稱定義為 Home,並且指定了該 App 的圖示為 @drawable/Icon
    [Activity(Label = "Home", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, Icon = "@drawable/Icon")]
    public class MainActivity : BaseActivity
    {
        /// <summary>
        /// 定義該畫面上的主要 DrawerLayout,並且在後面透過 Resource.Id.drawer_layout來取得該物件
        /// DrawerLayout可以讓你很方便建立左側選單
        /// 請參考 Google API 文件 https://developer.android.com/intl/zh-tw/reference/android/support/v4/widget/DrawerLayout.html
        /// </summary>        DrawerLayout drawerLayout;
        /// <summary>
        /// 定義導覽列的UI物件,當使用 NavigationView的時候,我們必須要搭配 DrawerLayout來使用,而 DrawerLayout必須是在最外層
        /// 請參考 Google API 文件 https://developer.android.com/intl/zh-tw/reference/android/support/design/widget/NavigationView.html
        /// </summary>        NavigationView navigationView;

        protected override int LayoutResource
        {
            get            {
                return Resource.Layout.main;
            }
        }

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // 取得 DrawerLayout UI 實際物件
            drawerLayout = this.FindViewById<DrawerLayout>(Resource.Id.drawer_layout);

            //設定漢堡按鈕的圖片資源            SupportActionBar.SetHomeAsUpIndicator(Resource.Drawable.ic_menu);

            //設定 navigation view            navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);

            //定義事件,當 navigation view 內的功能表選單有被選取的時候,要做何相對應的處置            navigationView.NavigationItemSelected += (sender, e) =>
            {
                e.MenuItem.SetChecked(true);

                switch (e.MenuItem.ItemId)
                {
                    case Resource.Id.nav_home_1:
                        ListItemClicked(0);
                        break;
                    case Resource.Id.nav_home_2:
                        ListItemClicked(1);
                        break;
                }

                // 這是 Google 新推出的 Metrial Design
                // 詳細說明,請參考 https://www.google.com/design/spec/material-design/introduction.html
                // 底下為產生類似 Toast 的簡短提示訊息通知效果
                Snackbar.Make(drawerLayout, "You selected: " + e.MenuItem.TitleFormatted, Snackbar.LengthLong)
                    .Show();

                // 使用動畫撥放方式,關閉所有正在開啟的 Drawer views                drawerLayout.CloseDrawers();
            };


            //if first time you will want to go ahead and click first item.
            if (savedInstanceState == null)
            {
                ListItemClicked(0);
            }
        }

        int oldPosition = -1;
        private void ListItemClicked(int position)
        {
            //this way we don't load twice, but you might want to modify this a bit.
            if (position == oldPosition)
                return;

            oldPosition = position;

            Android.Support.V4.App.Fragment fragment = null;
            switch (position)
            {
                case 0:
                    fragment = Fragment1.NewInstance();
                    break;
                case 1:
                    fragment = Fragment2.NewInstance();
                    break;
            }

            SupportFragmentManager.BeginTransaction()
                .Replace(Resource.Id.content_frame, fragment)
                .Commit();
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            switch (item.ItemId)
            {
                case Android.Resource.Id.Home:
                    drawerLayout.OpenDrawer(Android.Support.V4.View.GravityCompat.Start);
                    return true;
            }
            return base.OnOptionsItemSelected(item);
        }
    }
}

接著我們來看看這個 Activity 用到的視覺定義內容,也就是 main.axml。這個視覺畫面定內容相當的簡單,我們將會看到最後面的 [android.support.design.widget.NavigationView] 這個物件,裡面的屬性 app:headerLayout 定義了該導覽列的頁首內容,這個內容定義在 nav_header.xml內,而app:menu屬性,定義了導覽列中的功能清單配置,該配置定義在 nav_menu.xml內。

另外,我們看到了裡面定義了 android.support.design.widget.AppBarLayout 這個物件,這是一個可以伸縮摺疊的Toolbar(Collapsing Toolbar)。其實,這部分的UI是屬於 Goole Support Design Library內的功能,您可以參考這個連結,得到更多詳細資訊:http://android-developers.blogspot.tw/2015/05/android-design-support-library.html
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!-- The main content view -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.design.widget.AppBarLayout            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:id="@+id/toolbar_layout">
            <include
                android:id="@+id/toolbar"
                layout="@layout/toolbar"
                app:layout_scrollFlags="scroll|enterAlways" />
        </android.support.design.widget.AppBarLayout>
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_below="@id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    <android.support.design.widget.NavigationView        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

底下為 nav_header.axml的內容,這個檔案可以從方案總館內的 Resources\layout內找到。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="?attr/colorPrimaryDark"
    android:padding="16dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:orientation="vertical"
    android:gravity="bottom">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Username"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
</LinearLayout>
底下為 nav_menu.xml的內容,這個檔案可以從方案總館內的 Resources\menu內找到。
<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

  <group android:checkableBehavior="single">
    <item
        android:id="@+id/nav_home_1"
        android:icon="@drawable/ic_home_1"
        android:title="Home 1" />
    <item
        android:id="@+id/nav_home_2"
        android:icon="@drawable/ic_home_2"
        android:title="Home 2" />
  </group>

  <item android:title="Sub items">
    <menu>
      <item
          android:icon="@drawable/ic_home_1"
          android:title="Sub item 1" />
      <item
          android:icon="@drawable/ic_home_2"
          android:title="Sub item 2" />
    </menu>
  </item>
</menu>

這篇文章中所提到的內容,可以參考底下動畫,您就會更清楚這個框架可以幫您做到更友善的操作介面。



ezgif.com-video-to-gif (1)

沒有留言:

張貼留言