練習:建立電話號碼轉譯器應用程式
在本練習中,您會建構手機撥號應用程式的 UI,並實作此 UI 背後的邏輯。
您可以建置 UI,利用 .NET MAUI (多平台應用程式使用者介面) 和 .NET MAUI Essentials 套件的 UI 功能來撥打電話。
此應用程式可讓使用者在輸入欄位中輸入文字,並將該文字轉譯成數字。 它會使用電話鍵台上顯示的字母作為轉譯基礎。 例如,位數 2 有 a、b、c 這三個字母,因此會將字母 cab 轉譯成 222。
您將使用在前一個練習中建立的 Phoneword 解決方案來繼續進行操作。
將新的 C# 來源檔案新增至應用程式
如果您尚未在 Visual Studio 中開啟 Phoneword 解決方案,請開啟它。
在 [方案總管] 視窗中,以滑鼠右鍵按一下 [Phoneword] 專案,選取 [新增],然後選取 [類別]。
在 [新增項目] 對話方塊中,將類別檔案命名為 [PhonewordTranslator.cs],然後選取 [新增]。
新增轉譯邏輯
以下列程式碼取代類別檔案的內容,並儲存檔案。 PhonewordTranslator
類別中的靜態方法 ToNumber
方法會將號碼由英數字元文字轉譯成一般的數字電話號碼。
using System.Text;
namespace Core;
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
return null;
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);
// Bad character?
else
return null;
}
}
return newNumber.ToString();
}
static bool Contains(this string keyString, char c)
{
return keyString.IndexOf(c) >= 0;
}
static readonly string[] digits = {
"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"
};
static int? TranslateToNumber(char c)
{
for (int i = 0; i < digits.Length; i++)
{
if (digits[i].Contains(c))
return 2 + i;
}
return null;
}
}
建立 UI
開啟 Phoneword 專案中的 MainPage.xaml 檔案。
移除
ScrollView
控制項及其內容,只保留ContentPage
控制項:<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Phoneword.MainPage"> </ContentPage>
將
VerticalStackLayout
控制項以垂直方向、間距 15 個單位及邊框間距 20 個單位的方式新增至 ContentPage:<ContentPage ... > <VerticalStackLayout Spacing="15" Padding="20"> </VerticalStackLayout> </ContentPage>
新增控制項
Label
至 StackLayout:<ContentPage ... > <VerticalStackLayout ...> <Label Text = "Enter a Phoneword" FontSize ="20"/> </VerticalStackLayout> </ContentPage>
新增控制項
Entry
至 StackLayout,位於標籤下方。 控制項Entry
提供了一個可讓使用者輸入資料的文字方塊。 在此程式碼中,屬性x:Name
會命名控制項。 您稍後會於應用程式的程式碼中參考此控制項:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry x:Name = "PhoneNumberText" Text = "1-555-NETMAUI" /> </VerticalStackLayout> </ContentPage>
在 Entry 控制項之後,新增兩個
Button
控制項至 VerticalStackLayout。 目前這兩個按鈕不會有任何動作,且第二個按鈕在一開始的時候會處於停用狀態。 您會在下一個工作中新增這兩個按鈕來處理Clicked
事件所需的程式碼:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry ... /> <Button x:Name = "TranslateButton" Text = "Translate" Clicked = "OnTranslate"/> <Button x:Name = "CallButton" Text = "Call" IsEnabled = "False" Clicked = "OnCall"/> </VerticalStackLayout> </ContentPage>
回應 [TranslateButton] 按鈕點選
在 [方案總管] 視窗中,展開 MainPage.xaml 節點,然後開啟 MainPage.xaml.cs 程式碼後置檔案。
在
MainPage
類別中,移除count
變數及OnCounterClicked
方法。 該類別看起來應該如下所示:namespace Phoneword; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } }
將
translatedNumber
字串變數和下列OnTranslate
方法新增至建構函式後方的MainPage
類別中。OnTranslate
方法會從Entry
控制項的Text
屬性中擷取電話號碼,並將其傳遞至您先前建立PhonewordTranslator
類別的靜態ToNumber
方法中。public partial class MainPage : ContentPage { ... string translatedNumber; private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { // TODO: } else { // TODO: } } }
注意
您會在下一個步驟中填入此程式碼所遺漏的 TODO 位元。
在
OnTranslate
方法中,新增程式碼來變更 [撥號] 按鈕的Text
屬性,以附加成功轉譯的電話號碼。 可以使用已儲存於 translatedNumber 欄位中的值。 此外,請根據成功的轉譯,啟用和停用按鈕。 例如,若TranslateNumber
傳回 null,則停用按鈕;若是成功,則啟用按鈕。private void OnTranslate(object sender, EventArgs e) { string enteredNumber = PhoneNumberText.Text; translatedNumber = Core.PhonewordTranslator.ToNumber(enteredNumber); if (!string.IsNullOrEmpty(translatedNumber)) { CallButton.IsEnabled = true; CallButton.Text = "Call " + translatedNumber; } else { CallButton.IsEnabled = false; CallButton.Text = "Call"; } }
建立 CallButton 按鈕的事件方法
將
OnCall
事件處理方法新增至MainPage
類別結尾處。 此方法會使用非同步作業,因此請將其標示為async
:public partial class MainPage : ContentPage { ... async void OnCall(object sender, System.EventArgs e) { } }
在
OnCall
方法中,使用 Page.DisplayAlert 方法來提示使用者,詢問是否要撥打該電話號碼。DisplayAlert
的參數會是標題、訊息及用於 [接受] 和 [取消] 按鈕文字的兩個字串。 它會傳回布林值,以指出是否已按下 [接受] 按鈕以關閉對話方塊。async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { // TODO: dial the phone } }
測試應用程式
在 Visual Studio 工具列中,選取 [Windows 電腦] 設定檔,並開始進行偵錯。
點選 [轉譯] 按鈕,將預設文字轉換為有效的電話號碼。 [通話] 按鈕上的字幕文字應該會變為 [撥號 1-555-6386284]:
點選 [通話] 按鈕。 確認會顯示提示,要求您確認此作業。 選取 否。
返回 Visual Studio,並停止偵錯。
撥打電話號碼
在 MainPage.xaml.cs 程式碼後置檔案中,編輯 OnCall 方法,並以後續
try/catch
區塊取代 TODO 註解:async void OnCall(object sender, System.EventArgs e) { if (await this.DisplayAlert( "Dial a Number", "Would you like to call " + translatedNumber + "?", "Yes", "No")) { try { if (PhoneDialer.Default.IsSupported) PhoneDialer.Default.Open(translatedNumber); } catch (ArgumentNullException) { await DisplayAlert("Unable to dial", "Phone number was not valid.", "OK"); } catch (Exception) { // Other error has occurred. await DisplayAlert("Unable to dial", "Phone dialing failed.", "OK"); } } }
在 Microsoft.Maui.Application.Community 命名空間中的 PhoneDialer 類別,會針對 Windows、Android、iOS (和 iPadOS),以及 macOS 平台提供抽象的電話撥號功能 (和其他)。 靜態 Open 方法會嘗試使用電話撥號程式來撥打由參數所提供的號碼。
下列步驟說明如何更新 Android 應用程式資訊清單,讓 Android 可使用電話撥號程式。 除非您在資訊清單中根據作業系統指定不同的功能,否則 Windows、iOS 和 MacCatalyst 應用程式都會遵循相同的一般性原則。
在 [方案總管] 視窗中,依序展開 [平台] 資料夾、Android] 資料夾、以滑鼠右鍵按一下 [AndroidManifest.xml 檔案,然後選取 [使用自動編輯器選取器開啟 (XML)]>。 選取 [確定]。
將下列的 XML 程式碼片段新增至 manifest 節點內現有內容之後。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> ... <queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel"/> </intent> </queries> </manifest>
儲存檔案。
在 Visual Studio 工具列中,選取 Android Emulators/Pixel 3a - API 30 (或類似項目) 設定檔,然後開始進行偵錯。
當應用程式出現在模擬器時 (這可能需要幾分鐘),請輸入電話號碼 (或接受預設) 選取 [轉譯],然後選取 [撥號]。
在 [撥打號碼] 警示中,選取 [是]。 確認 Android 電話撥號程式是否顯示了您在應用程式中所提供的號碼。
返回 Visual Studio,並停止偵錯。
摘要
在本練習中,您已使用頁面和檢視將自訂 UI 新增至應用程式。 您也使用 Android 中所提供的平台專用 API 來新增撥打電話的支援。