第1個(gè)Android應(yīng)用程序 Android制作簡(jiǎn)單單頁(yè)導(dǎo)航
本例子演示如何添加一個(gè)簡(jiǎn)單的單頁(yè)導(dǎo)航,在此基礎(chǔ)上,再演示如何在第2個(gè)頁(yè)面中顯示第1個(gè)頁(yè)面中撥打過(guò)的所有電話號(hào)碼。
(1)通過(guò)該例子理解Android App的基本架構(gòu)。
(2)通過(guò)該例子理解實(shí)現(xiàn)Android多屏幕導(dǎo)航的基本技術(shù)。
本例子只是為了讓我們對(duì)Android App開(kāi)發(fā)有一個(gè)較全面的感性認(rèn)識(shí),讀者不必一開(kāi)始就糾結(jié)于代碼中的細(xì)節(jié)問(wèn)題,涉及到的相關(guān)概念在后面還會(huì)分別介紹。
運(yùn)行截圖
運(yùn)行截圖(Api19、Api21、Api23的實(shí)現(xiàn)代碼都相同):
界面操作
單擊“將文本轉(zhuǎn)換為數(shù)字”,觀察結(jié)果。
單擊【轉(zhuǎn)換】按鈕,如果轉(zhuǎn)換成功,則【撥號(hào)】按鈕可用,單擊【撥號(hào)】按鈕,觀察彈出的對(duì)話框。
如果單擊【撥號(hào)】按鈕,就會(huì)自動(dòng)撥號(hào)。
下面介紹主要設(shè)計(jì)步驟。
1、新建項(xiàng)目
選擇模板:Blank App (Android),項(xiàng)目名:PhonewordApp。
項(xiàng)目創(chuàng)建成功后,刪除GettingStarted.Xamarin(廣告文件)。
2、界面設(shè)計(jì)
(1)雙擊打開(kāi)Main.axml,分別觀察設(shè)計(jì)界面【Design】和源碼【Source】的內(nèi)容。
(2)按Delete鍵刪除【Hello World,Click Me】按鈕。
(3)從【工具箱】中拖放一個(gè)【Text (Large)】到設(shè)計(jì)界面,修改下面的屬性:
id:@+id/PhoneText
text:電話
注:此時(shí)系統(tǒng)會(huì)自動(dòng)在【Source】中添加對(duì)應(yīng)的代碼(下同)。
(4)從【工具箱】中拖放一個(gè)【Plain Text】到設(shè)計(jì)界面,放到【Text (Large)】的下方,修改下面的屬性:
id:@+id/PhoneNumberText
text:138 4912 2599
(5)從【工具箱】中拖放一個(gè)【Button】到設(shè)計(jì)界面,放到【Plain Text】的下方,修改下面的屬性:
id:@+id/buttonTranslate
text:轉(zhuǎn)換
(6)從【工具箱】中拖放一個(gè)【Button】到設(shè)計(jì)界面放到上一個(gè)按鈕的下方,修改屬性:
id:@+id/buttonCall
text:撥號(hào)
經(jīng)過(guò)以上步驟后,即得到下圖所示的設(shè)計(jì)界面:
(7)保存文件,并單擊【解決方案資源管理器】上方的【刷新】按鈕。
注意:這一步的目的是為了讓系統(tǒng)能找到設(shè)計(jì)界面內(nèi)的資源并自動(dòng)生成對(duì)應(yīng)的ID,以便在后面鍵入C#代碼時(shí)能看到與設(shè)計(jì)界面資源相關(guān)的智能提示。
3、編寫(xiě)C#代碼
(1)鼠標(biāo)右擊項(xiàng)目名à添加類(lèi),在彈出的窗口中,選擇【Class】模板,名稱:PhoneTranslator.cs,如下圖所示,單擊【添加】按鈕。
然后將PhoneTranslator.cs改為下面的代碼:
using System.Text; namespace PhonewordApp { public static class PhonewordTranslator { public static string ToNumber(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return ""; } else { raw = raw.ToUpperInvariant(); } var newNumber = new StringBuilder(); foreach (var c in raw) { if ("- 0123456789".Contains(c)) newNumber.Append(c); else { var result = TranslateToNumber(c); if (result != null) newNumber.Append(result); } } return newNumber.ToString(); } static bool Contains(this string keyString, char c) { return keyString.IndexOf(c) >= 0; } static int? TranslateToNumber(char c) { if ("ABC".Contains(c)) return 2; else if ("DEF".Contains(c)) return 3; else if ("GHI".Contains(c)) return 4; else if ("JKL".Contains(c)) return 5; else if ("MNO".Contains(c)) return 6; else if ("PQRS".Contains(c)) return 7; else if ("TUV".Contains(c)) return 8; else if ("WXYZ".Contains(c)) return 9; return null; } } }
(2)打開(kāi)MainActivity.cs,將該文件改為下面的代碼:
using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; using Android.Widget; using Android.OS; using System.Collections.Generic; namespace PhonewordApp { [Activity(Label = "PhonewordApp", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { static readonly List<string> phoneNumbers = new List<string>(); protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Main); var phoneNumberText = FindViewById<EditText>(Resource.Id.PhoneNumberText); var buttonTranslate = FindViewById<Button>(Resource.Id.buttonTranslate); var buttonCall = FindViewById<Button>(Resource.Id.buttonCall); buttonCall.Enabled = false; //禁用【撥號(hào)】按鈕 string translatedNumber = string.Empty; buttonTranslate.Click += (s, e) => { translatedNumber = PhonewordTranslator.ToNumber(phoneNumberText.Text); if (string.IsNullOrWhiteSpace(translatedNumber)) { buttonCall.Text = "撥號(hào)"; buttonCall.Enabled = false; } else { buttonCall.Text = "播出號(hào)碼:" + translatedNumber + ",單擊確認(rèn)!"; buttonCall.Enabled = true; } }; var buttonCallHistory = FindViewById<Button>(Resource.Id.buttonCallHistory); buttonCallHistory.Click += (sender, e) => { var intent = new Intent(this, typeof(CallHistoryActivity)); intent.PutStringArrayListExtra("phone_numbers", phoneNumbers); StartActivity(intent); }; buttonCall.Click += (s, e) => { phoneNumbers.Add(translatedNumber); buttonCallHistory.Enabled = true; // 當(dāng)單擊【撥號(hào)】時(shí),嘗試撥號(hào) var callDialog = new AlertDialog.Builder(this); callDialog.SetMessage("電話:" + translatedNumber + ",撥號(hào)嗎?"); callDialog.SetNeutralButton("撥號(hào)", delegate { var callIntent = new Intent(Intent.ActionCall); callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber)); StartActivity(callIntent); }); callDialog.SetNegativeButton("取消", delegate { }); callDialog.Show(); }; } } }
(3)重新生成項(xiàng)目,確保無(wú)錯(cuò)誤。
注:drawable文件夾下的Icon.png是要顯示的圖標(biāo),也可將其換為其他圖標(biāo)文件。
(4)選擇主菜單下該項(xiàng)目的屬性,在彈出的窗口中,勾選【CALL PHONE】權(quán)限:
注:
(1)這一步必須做,否則因該App無(wú)撥號(hào)權(quán)限,撥號(hào)功能會(huì)失敗。
(2)設(shè)置后,查看Properties文件夾下AndroidManifest.xml文件中自動(dòng)添加的代碼,理解權(quán)限設(shè)置的作用。
4、調(diào)試運(yùn)行及代碼片段解釋
選擇一種模擬器,然后按<F5>鍵調(diào)試運(yùn)行。
注意:如果使用低于API 23的模擬器,必須設(shè)置項(xiàng)目屬性(主菜單à項(xiàng)目屬性),使用對(duì)應(yīng)版本的API來(lái)編譯應(yīng)用程序,否則在模擬器上運(yùn)行時(shí)可能會(huì)出現(xiàn)應(yīng)用程序一閃就退出或者顯示“應(yīng)用程序已停止運(yùn)行”的情況。
下面解釋前面已經(jīng)實(shí)現(xiàn)的代碼片段的含義:
(1)如何顯示Alert對(duì)話框
AlertDialog的詳細(xì)用法見(jiàn)【第6章 UI設(shè)計(jì)(三)--對(duì)話框】。
(2)如何撥號(hào)
下面的代碼演示了如何調(diào)用系統(tǒng)功能實(shí)現(xiàn)撥號(hào):
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber));
StartActivity(callIntent);
注意:運(yùn)行前需要先勾選【CALL PHONE】設(shè)置允許撥號(hào)權(quán)限,否則運(yùn)行會(huì)出現(xiàn)異常:
5、創(chuàng)建第2個(gè)屏幕跟蹤歷史記錄
(1)打開(kāi)values文件夾下的Strings.xml文件,添加下面的代碼:
<?xml version="1.0" encoding="utf-8"?> <resources> …… <string name="CallHistory">撥號(hào)記錄</string> </resources>
(2)單擊【解決方案資源管理器】上方的“刷新”按鈕,或者重新生成項(xiàng)目。
注:選擇其中之一即可,目的是為了讓C#代碼能識(shí)別它。
(3)打開(kāi)Main.axml,從【工具箱】中拖放一個(gè)【Button】到Main.axml設(shè)計(jì)界面,將其放到上一個(gè)按鈕的下方,修改屬性:
id:@+id/buttonCallHistory
text:@string/CallHistory
enabled:false
注: @string/CallHistory的含義是在values文件夾下的Strings.xml文件中提供該變量的值。
此時(shí),可看到“STRING/CALLHISTORY”會(huì)自動(dòng)變成“撥號(hào)記錄”。
說(shuō)明:這一步設(shè)置變量值的做法是實(shí)際的Android App項(xiàng)目中建議的做法,這樣做的好處是能提高安卓App運(yùn)行的效率。而步驟1的做法是一種硬編碼的做法,硬編碼在安卓App中不是建議的做法,步驟1只是為了剛?cè)腴T(mén)時(shí)理解更容易。
(4)鼠標(biāo)右擊項(xiàng)目名,選擇【添加…】à【新建項(xiàng)】,在彈出的窗口中,選擇“Activity”模板,文件名:CallHistoryActivity.cs,單擊【添加】。然后將該文件改為下面的內(nèi)容(省略了using……):
namespace PhonewordApp { [Activity(Label = "CallHistoryActivity")] public class CallHistoryActivity : ListActivity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); var phoneNumbers = Intent.Extras.GetStringArrayList("phone_numbers") ?? new string[0]; this.ListAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, phoneNumbers); } } }
其中,c = a??b; 的含義相當(dāng)于:if (a != null ){ c = a;} else { c = b;}
(5)修改MainActivity.cs文件,目標(biāo)是收集第1個(gè)屏幕界面運(yùn)行時(shí)撥打過(guò)的所有電話號(hào)碼,并將其在第2個(gè)屏幕上顯示出來(lái)。在MainActivity.cs文件中添加下面的代碼:
…… using System.Collections.Generic; namespace E01PhonewordApp { [Activity(Label = "E01PhonewordApp", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { static readonly List<string> phoneNumbers = new List<string>(); protected override void OnCreate(Bundle bundle) { …… var buttonCallHistory = FindViewById<Button>(Resource.Id.buttonCallHistory); buttonCallHistory.Click += (sender, e) => { var intent = new Intent(this, typeof(CallHistoryActivity)); intent.PutStringArrayListExtra("phone_numbers", phoneNumbers); StartActivity(intent); }; buttonCall.Click += (s, e) => { phoneNumbers.Add(translatedNumber); buttonCallHistory.Enabled = true; // 當(dāng)單擊【撥號(hào)】時(shí),嘗試撥號(hào) var callDialog = new AlertDialog.Builder(this); callDialog.SetMessage("播出號(hào)碼:" + translatedNumber + ",撥號(hào)嗎?"); callDialog.SetNeutralButton("撥號(hào)", delegate { // Create intent to dial phone var callIntent = new Intent(Intent.ActionCall); callIntent.SetData(Android.Net.Uri.Parse("tel:" + translatedNumber)); StartActivity(callIntent); }); callDialog.SetNegativeButton("取消", delegate { }); callDialog.Show(); }; } } }
(6)重新生成項(xiàng)目,確保無(wú)錯(cuò)誤。
(7)運(yùn)行,再撥一個(gè)號(hào)(例如12345678901),然后查看撥號(hào)記錄。下圖是用另一種模擬器查看的運(yùn)行效果(你可以創(chuàng)建多種不同的模擬器,分別觀察同一個(gè)項(xiàng)目的運(yùn)行效果):
到這里,我們就完成了用C#編寫(xiě)的第1個(gè)Android應(yīng)用程序。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android應(yīng)用 坐標(biāo)系詳細(xì)介紹
- 非常實(shí)用的小功能 Android應(yīng)用版本的更新實(shí)例
- Android應(yīng)用開(kāi)發(fā)中使用GridView網(wǎng)格布局的代碼示例
- Android應(yīng)用自動(dòng)更新功能實(shí)現(xiàn)的方法
- Android應(yīng)用開(kāi)發(fā)中WebView的常用方法筆記整理
- Android應(yīng)用中使用Fragment組件的一些問(wèn)題及解決方案總結(jié)
- 詳解Android應(yīng)用中DialogFragment的基本用法
- Android應(yīng)用中設(shè)置alpha值來(lái)制作透明與漸變效果的實(shí)例
- Android應(yīng)用中實(shí)現(xiàn)手勢(shì)控制圖片縮放的完全攻略
- Docker 實(shí)現(xiàn)瀏覽器里開(kāi)發(fā)Android應(yīng)用的功能
相關(guān)文章
android開(kāi)發(fā)之listView組件用法實(shí)例簡(jiǎn)析
這篇文章主要介紹了android開(kāi)發(fā)之listView組件用法,結(jié)合實(shí)例形式簡(jiǎn)單分析了listView組件的相關(guān)屬性與使用技巧,需要的朋友可以參考下2016-01-01Android實(shí)現(xiàn)大圖滾動(dòng)顯示效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)大圖滾動(dòng)顯示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android使用 Coroutine + Retrofit打造簡(jiǎn)單的HTTP請(qǐng)求庫(kù)
這篇文章主要介紹了Android使用 Coroutine + Retrofit打造簡(jiǎn)單的HTTP請(qǐng)求庫(kù),幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03Android中如何優(yōu)雅的處理重復(fù)點(diǎn)擊實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于Android中如何優(yōu)雅的處理重復(fù)點(diǎn)擊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09詳解Android使用Html.fromHtml需要注意的地方
本篇文章主要介紹了詳解Android使用Html.fromHtml需要注意的地方,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07