2016年5月22日 星期日

如果使用Xamarin.Forms開發, 某功能開發Xamarin.Forms沒有支援該怎麼辦??


  1. 使用shareCode Project分享程式碼
  2. 針對每一個平台撰寫程式碼
  3. 使用assembly-level
  4. 使用DenpendencyService

Platform-Specific Code

這個方式, 可在Layout中, 針對iOS, Android及WINPHONE不同的版型進行設定, 使Layout看起來更加的優美, 在指令上, 開頭皆是DEVICE開頭, 如:


其中Device.OnPlatform(40,20,20)即是針對(iOS, Android, Winphone)設定不同的邊距

另外還有很多指令可針對不同平台設定..

為什麼要學Xamarin.Forms

Xamarin最大的特色是跨平台開發, 在Layout共用的情形下, 並在其中可針對不同平台作設定, 在開發上速度快很多, 程式碼也將少很多, 是很好的方式

2016年2月26日 星期五

checkBox

Layout :

<TextView
        android:text="未選擇"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txt" />
    <CheckBox
        android:text="香蕉"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cbBanana" />
    <CheckBox
        android:text="西瓜"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cbWatermelon" />
    <CheckBox
        android:text="鳳梨"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cbAnanas" />
    <CheckBox
        android:text="草莓"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/cbStrawberry" />

Activity:

            FindViewById<CheckBox>(Resource.Id.cbBanana)
                .CheckedChange += CheckedChange;
            FindViewById<CheckBox>(Resource.Id.cbWatermelon)
                .CheckedChange += CheckedChange;
            FindViewById<CheckBox>(Resource.Id.cbAnanas)
                .CheckedChange += CheckedChange;
            FindViewById<CheckBox>(Resource.Id.cbStrawberry)
                .CheckedChange += CheckedChange; //checkedchange副程式在底下

//..Smart 寫法 (將上面四個FindViewById改成下述程式碼 )
//不用每個checkBox都定義,以迴圈方式自動定義,則可自由新增checkBox而不受影響
            var cbLayout = FindViewById<LinearLayout>(Resource.Id.cbLayout);//定義LinearLayout裡面的所有cbLayout
            int cbCount = cbLayout.ChildCount;
            for (int i = 0; i < cbCount; i++)
            {
                var cbItem = cbLayout.GetChildAt(i);
                if (cbItem is CheckBox)
                {
                    ((CheckBox)cbItem)
                        .CheckedChange += CheckedChange;
                }
            }

//..Smart 寫法

private List<string> _cacheSelect = new List<string>(); //如果checkbox被選取,值就會寫到List中


void CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
        {
            var txt =
                FindViewById<TextView>(Resource.Id.txt);
            var cb = ((CheckBox)sender);
            if (e.IsChecked)
                _cacheSelect.Add(cb.Text);  //被選到的cb,其text會被加到_cacheSelect
            else
                _cacheSelect.Remove(cb.Text);
            txt.Text = GenSelectString();
        }

private string GenSelectString() //將所有被選擇的CB值集合至此處一次顯示
        {
            StringBuilder select = new StringBuilder();
            foreach (var s in _cacheSelect)
                select.AppendFormat(",{0}", s);
            if (string.IsNullOrEmpty(select.ToString()))
                return "未選擇";
            else
                return "你選擇了" + select.ToString().Substring(1);
        }




2016年2月17日 星期三

Adapter使用方法 (以Spinner為例)

//資料陣列
(1)string[] dataSpinner = {"Visual Studio","Xamarin Studio"};

//由資料來源建立Adapter
(2)ArrayAdapter<string> sourceSpinner = new ArrayAdapter<string>(this,Android.Resource.Layout.SimpleSpinnerItem, dataSpinner);
//Layout.SimpleSpinnerItem:顯示Style          

(3) spinner1.Adapter = sourceSpinner;

流程:
建立資料後,將資料匯入Adapter裡,

1,資料 ==> 2.Adapter (含Spinner顯示屬性) ==> 3.spinner


Spinner

Values:
<resources>
   
    <string name="ApplicationName">UserInterface1</string>
    <string name="SpinnerTitle">請選擇一個值</string>//Spinner Dialog型式之Title
    <string-array name="SpinnerData"> //陣列形式作為選單資料
      <item>string Visual Studio</item>
      <item>string Xamarin Studio</item>    
    </string-array>
   
</resources>

Layout:
<Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:spinnerMode="dialog" //點下拉選單後,會跳出新視窗
        android:prompt="@string/SpinnerTitle" //Spinner Dialog型式之Title
        android:id="@+id/spinner1" />
    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:spinnerMode="dialog"
        android:prompt="@string/SpinnerTitle"
        android:id="@+id/spinnerR" />
    <TextView
        android:text="Text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtSpinner1" />

註:@string/SpinnerTitle:呼叫string.xml之SpinnerTitle

Activity:
//...Spinner
            string[] dataSpinner = {"Visual Studio","Xamarin Studio"};

            var spinner1 = this.FindViewById<Spinner>(Resource.Id.spinner1);
            var txtSpinner1 = this.FindViewById<TextView>(Resource.Id.txtSpinner1);

            //由資料來源建立Adapter
            ArrayAdapter<string> sourceSpinner = new ArrayAdapter<string>
                (this, Android.Resource.Layout.SimpleSpinnerItem, dataSpinner);            
            spinner1.Adapter = sourceSpinner;

            //偵測誰被選擇
            spinner1.ItemSelected += (sender, e) =>
            {                          
                txtSpinner1.Text = "你選擇了" + dataSpinner[e.Position];
                //被選擇的dataSpinner, 更新至txtSpinner1
            };

            //換比較好看的Style,也可以到Adapter設定,將SimpleSpinnerItem換成SimpleListItemSingleChoice即可,dropdown也可用
            sourceSpinner.SetDropDownViewResource
                (Android.Resource.Layout.SimpleListItemSingleChoice);

            //由字串資源檔取回下拉選單資料
            var spinnerR = this.FindViewById<Spinner>(Resource.Id.spinnerR);
            ArrayAdapter sourceFromR = ArrayAdapter.CreateFromResource(
                    this,Resource.Array.SpinnerData,
                    Android.Resource.Layout.SimpleSpinnerItem);
            spinnerR.Adapter = sourceFromR;
            sourceFromR.SetDropDownViewResource
             (Android.Resource.Layout.SimpleListItemSingleChoice);

 //...Spinner

2016年2月16日 星期二

單選選單

Layout:RadioGroup內預設包含3個RadioButton

<RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/radioGroup1">
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true" // 預設點選此項,如果沒有的話,就沒有點選
            android:text="Visual Studio"
            android:id="@+id/radioVS" />
        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Xamarin Studio"
            android:id="@+id/radioXS" />
        <TextView  //用來顯示誰被點選
            android:text="點選上方選項"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/txtRadio" />
        <Button
            android:text="取得值"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/btnRadio" />
    </RadioGroup>



Activity:重點在於判斷誰被點選,並將值取出
            //...RadioGroup / Button
            var txtRadio = this.FindViewById<TextView>(Resource.Id.txtRadio);
            var radioGroup = this.FindViewById<RadioGroup>(Resource.Id.radioGroup1);
            //判斷誰被點選了
            radioGroup.CheckedChange += (sender, e) =>
            {
                int id = e.CheckedId; //被點選者資訊傳給id
                var select = this.FindViewById<RadioButton>(id);//讀取被點選RadioButton資訊
                txtRadio.Text = string.Format("你點選了{0}", select.Text);
                //讀取select之Text屬性內容,覆寫至txtRadio之Text屬性內容

            };
            //另一種判斷誰被點選方式by btn
            var btnRadio = this.FindViewById<Button>(Resource.Id.btnRadio);
            btnRadio.Click += (sender, e) =>
            {
                var select = this.FindViewById<RadioButton>
                    (radioGroup.CheckedRadioButtonId); //重點指令
                txtRadio.Text = string.Format("按鈕取得了{0}", select.Text);
            };
            //...RadioGroup / Button




EditText & AUtoComplet TextView

<EditText
        android:inputType="number" //定義欄位屬性,會自動跳出對應的鍵盤
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText1"
        android:hint="數字 EditText" /> //欄位提示字元


inputType屬性表

說明
none
text任何的字元
textCapCharacters鍵盤英文為大寫
textCapWords每一個英文單字字母為大寫
textAutoCorrect自動完成,表示輸入完成後會自動跳入下一個EditText
textAutoComplete同textAutoCorrect
textMultiLine多行輸入
textImeMultiLine輸入法多行(不一定有支援)
textNoSuggestions不提示
textUri網址
textEmailAddressEmail 地址
textEmailSubjectEmail 主旨
textShortMessage短訊息
textLongMessage長訊息
textPersonName人名
textPostalAddress地址
textPassword密碼
textVisiblePassword可見密碼
textWebEditText網頁表單的本文格式
textFilter本文篩選格式
textPhonetic拼音輸入
number數字鍵盤
 numberSigned帶有符號數字格式
numberDecimal帶小數點的浮點數字格式
phone電話格式
datetime時間日期
date日期鍵盤
time時間鍵盤

<AutoCompleteTextView
        android:hint="自動完成"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtAutoComplete" />

.cs檔內容(Adapter用法)
 //AutoCompleteTextView
            string[] data = { "aaa","abc", "abb", "app", "apk"}

            //由資料來源建立Adapter
            ArrayAdapter<string> source = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleDropDownItem1Line, data);
            var txt = this.FindViewById<AutoCompleteTextView>(Resource.Id.txtAutoComplete);

            //將資料Adapter設定給AutoCompleteTextView
            txt.Adapter = source;
            txt.Threshold = 1;//設定輸入幾個字後跳提示,預設為2 


data(字串) ==> Adapter ==> AutoCompleteTextView

專有名詞釐清


  1. 匿名委派
  2. 繼承
  3. 建構子
  4. Adapter

Button

有三種方式,定義按下的行為

protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);

            //一般註冊事件方式
            FindViewById<Button>(Resource.Id.button1).Click += Activity1_Click;

            //使用匿名委派
            FindViewById<Button>(Resource.Id.button1)
                .Click += delegate(object sender, EventArgs e)
            {
                //do Some things
            };

            //使用Lambada運算式
            FindViewById<Button>(Resource.Id.button1)
                .Click += (sender, e) =>
                {
                    //do Some things
                };

        }


按下按鈕後,若要跳到不同的頁面,需以intent方式進行,可參考
http://xamarinnote.blogspot.tw/2016/02/navigation.html

TextView

        android:text="網址 www.hinet.net" // 網址及www.hinet.net要空一行for分隔
        android:autoLink="all" // 自動判斷連結及對應之應用程式開啟
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView1" />

layout13.jpg

TextView01.jpg

卡關了,問題在那裡?

對於沒有C#、物件導向或MVC架構基礎的人,由於後續進入多Activity互傳資料時,更進階了,因為常用到封裝、繼承及建構子概念,要硬吞下去,真的很痛苦,而且也沒有益處,因為根本不懂其原理,日後也無法變通,還是回頭去瞭解C#物件導向之觀念,再繼續進行較好。

2016年2月4日 星期四

學習流程


Xamarin Tutorials
1. 環境建置,安裝及設定
2. 手機usb debug模式開始
3. 入門及觀念(hello, android MultiScreen)

開發實戰書藉
4. 3-1(基礎)及3-2(Layout)
5. 第四章頁面巡覽至4-1-4
6. 3-3
7. C#物件導向

Navigation 頁面巡覽


  •  [Activity(Label = "LoginActivity", MainLauncher = true, Icon = "@drawable/icon")] : 紅字為首度執行之cs檔。
  • intent 頁面巡覽基本方式
              FindViewById<Button>(Resource.Id.btnGoLogin) :定義Button by Id
                .Click += (sender, e) => 設定點擊後的行為
                {
                    Intent i = new Intent(this, typeof(LoginActivity)); 定義i為執行LoginActivity                   
                    this.StartActivity(i); 啟動LoginActivity
                    this.Finish(); 按上一頁後, 結束此Activity
                };

  • {0}:第一個變數
  • 透過Intent傳遞變數
將user變數塞至UserName中

取UserName值至userName 

取第一個變數資料,即userName內之文字字串

2016年2月3日 星期三

Layout


  • Linearlayout:從上而下的Layout方式
  • Relativelayout:以控制項元件之間的位置關係作Layout
  • Tablelayout:切割表格作Layout,預設是3x3

Ch3 Android 控制項簡介


  • 可利用文件大綱調整控制項順序。(快捷鍵:Ctrl+Alt+T)

Understanding Android API Levels


  • API Levels就是在講開發不同版本之android system相容性

2016年2月2日 星期二

Hello Android & Multiscreen

2016/02/02
  • Main.axml:Layout設計總管
  • SetContentView(Resource.Layout.Main); = 設定主Layout檔案,此行即以Main.axml為主要Layout檔。想:可控制此項切換Layout版型?
2016/02/03
  • Android程式可視為由多區塊組合而成,可分類成Activity及Service。Activity可看成一項獨立功能,而且都會對應到UI,如登入畫面或LIst清單等,Service即是背景程式,不會有畫面,如音樂播放解碼程式等。
  • Intent:各Block之訊息傳遞,使用時機如camera app to take and save, gathering location information, or navigating from one screen to the next.(常用)
  • 以intent方式,啟動另一個activity

  •  以intent方式,Launching Another Application with an Intent
  • String Resources – In our Phoneword application, we set the text of the CallHistoryButton to "@string/callHistory". The @string syntax means that the string’s value is stored in the String Resources File, Strings.xml. We entered the following value for the callHistory string in Strings.xml。

2016年2月1日 星期一

Setup and Installation


2016/02/02
  • 安裝時VS2015整合度較高,compiler較沒問題
  • 如果要使用VS內建的模擬器,要下載intel之HAXM Driver,增加模擬器之CPU選項,速度明顯改善。
  • 安裝HAXM,加速模擬器

  • 昕力資訊上課時是使用GenyMotion,有virtuabox內建版。
  • 如果要用手機模擬,要去extra處加上usb drivers,並打開手機之USB偵錯模式才行。
  • USB偵錯模式,要進入設定==>關於==>軟體資訊後,點七下即可開啟(適用多數手機)
  • 要使用手機載入程式,必須確認ADB Interface安裝無誤,可從裝置管理員確認,如果沒有安裝好,看教學