Ejercicio: Creación de una aplicación de traductor de números de teléfono
En este ejercicio, construirá la interfaz de usuario de la aplicación de marcador telefónico e implementará la lógica detrás de esta interfaz de usuario.
Creará una interfaz de usuario que aproveche las capacidades de la interfaz de usuario de .NET MAUI (interfaz de usuario de aplicación multiplataforma) y el paquete .NET MAUI Essentials para marcar el teléfono.
La aplicación permite al usuario escribir texto en un campo de entrada y traduce ese texto a dígitos numéricos. Usa las letras que se muestran en el teclado de un teléfono como base para la traducción. Por ejemplo, las letras cab se traducen como 222 porque el dígito 2 tiene las tres letras a, b y c.
Continúe con la solución Phoneword que ha creado en el ejercicio anterior.
Adición de un nuevo archivo de origen de C# a la aplicación
Abra la solución Phoneword en Visual Studio si todavía no lo ha hecho.
En la ventana Explorador de soluciones, haga clic con el botón derecho en el proyecto Phoneword, seleccione Agregar y seleccione Clase.
En el cuadro de diálogo Agregar nuevo elemento, asigne un nombre al archivo de clase PhonewordTranslator.cs y seleccione Agregar.
Adición de la lógica de traducción
Reemplace el contenido del archivo de clase por el código siguiente y guarde el archivo. El método estático ToNumber
de la clase PhonewordTranslator
traduce el número de texto alfanumérico a un número de teléfono convencional.
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;
}
}
Creación de la interfaz de usuario
Abre el archivo MainPage.xaml en el proyecto Phoneword.
Quite el control
ScrollView
y su contenido, y deje solo el controlContentPage
:<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Phoneword.MainPage"> </ContentPage>
Agregue un control
VerticalStackLayout
con orientación vertical y un espaciado de 15 unidades y relleno de 20 unidades a ContentPage:<ContentPage ... > <VerticalStackLayout Spacing="15" Padding="20"> </VerticalStackLayout> </ContentPage>
Agregue un control
Label
a StackLayout:<ContentPage ... > <VerticalStackLayout ...> <Label Text = "Enter a Phoneword" FontSize ="20"/> </VerticalStackLayout> </ContentPage>
Agregue un control
Entry
a StackLayout, debajo de la etiqueta. Un controlEntry
proporciona un cuadro de texto en el que el usuario puede escribir datos. En este código, la propiedadx:Name
asigna un nombre al control. Más adelante hará referencia a este control en el código de la aplicación:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry x:Name = "PhoneNumberText" Text = "1-555-NETMAUI" /> </VerticalStackLayout> </ContentPage>
Agregue dos controles
Button
a VerticalStackLayout, después del control Entry. Actualmente, ninguno de los dos botones hace nada y el segundo se deshabilita inicialmente. Agregará el código para controlar el eventoClicked
de estos dos botones en la siguiente tarea:<ContentPage ... > <VerticalStackLayout ...> <Label .../> <Entry ... /> <Button x:Name = "TranslateButton" Text = "Translate" Clicked = "OnTranslate"/> <Button x:Name = "CallButton" Text = "Call" IsEnabled = "False" Clicked = "OnCall"/> </VerticalStackLayout> </ContentPage>
Respuesta a la pulsación del botón TranslateButton
En la ventana Explorador de soluciones, expanda la entrada MainPage.xaml y abra el archivo de código subyacente MainPage.xaml.cs.
En la clase
MainPage
, quite la variablecount
y el métodoOnCounterClicked
. La clase debería tener el siguiente aspecto:namespace Phoneword; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } }
Agregue la variable de cadena
translatedNumber
y el métodoOnTranslate
siguiente a la claseMainPage
, después del constructor. El métodoOnTranslate
recupera el número de teléfono de la propiedadText
del controlEntry
y lo pasa al método estáticoToNumber
de la clasePhonewordTranslator
que creó anteriormente.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: } } }
Nota:
En el paso siguiente, rellenará los bits TODO que faltan de este código.
En el método
OnTranslate
, agregue código para cambiar la propiedadText
del botón Llamada para anexar el número de teléfono traducido correctamente. Puede usar el valor almacenado en el campo TranslatedNumber. Además, se habilitará y deshabilitará el botón en función de la traducción correcta. Por ejemplo, siTranslateNumber
devuelve null, deshabilite el botón, pero si lo ha hecho correctamente, habilítelo.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"; } }
Creación del método de evento para el botón CallButton
Agregue el método de control de eventos
OnCall
al final de la claseMainPage
. Este método usa operaciones asincrónicas, así que márquelo comoasync
:public partial class MainPage : ContentPage { ... async void OnCall(object sender, System.EventArgs e) { } }
En el método
OnCall
, pida al usuario, mediante el método Page.DisplayAlert, que pregunte si quiere marcar el número.Los parámetros de
DisplayAlert
son un título, un mensaje y dos cadenas que se usan para el texto de los botones Accept y Cancel. Devuelve un valor booleano que indica si se ha presionado el botón Accept para cerrar el cuadro de diálogo.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 } }
Prueba de la aplicación
En la barra de herramientas de Visual Studio, seleccione el perfil Máquina Windows y comience la depuración.
Pulse el botón Translate para convertir el texto predeterminado en un número de teléfono válido. El subtítulo del botón Call debe cambiar a Call 1-555-6386284:
Pulse el botón Call. Compruebe que aparece un mensaje en el que se le pide que confirme la operación. así que seleccione No.
Vuelva a Visual Studio y detenga la depuración.
Marcación del número de teléfono
En el archivo de código subyacente MainPage.xaml.cs, edite el método OnCall y reemplace el comentario TODO por los bloques
try/catch
siguientes: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"); } } }
La clase PhoneDialer del espacio de nombres Microsoft.Maui.ApplicationModel.Communication proporciona una abstracción de la funcionalidad de marcación del teléfono (entre otras) para las plataformas Windows, Android, iOS (y iPadOS) y macOS. El método estático Open intenta utilizar el marcador telefónico para llamar al número proporcionado como parámetro.
En los pasos siguientes se muestra cómo actualizar el manifiesto de la aplicación Android para permitir que Android use el marcador telefónico. Las aplicaciones de Windows, iOS y MacCatalyst siguen el mismo principio general, excepto que se especifica una funcionalidad diferente en el manifiesto en función del sistema operativo.
En la ventana Explorador de soluciones, expanda la carpeta Plataformas, expanda la carpeta Android, haga clic con el botón derecho en el archivo AndroidManifest.xml y seleccione Abrir con>Selector de editor automático (XML). Seleccione Aceptar.
Agregue el siguiente fragmento XML dentro del nodo de manifiesto después del contenido existente para este nodo.
<?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>
Guarde el archivo.
En la barra de herramientas de Visual Studio, seleccione el perfil Android Emulators/Pixel 3a - API 30 (o similar) e inicie la depuración.
Cuando la aplicación aparezca en el emulador (esto puede tardar unos minutos), escriba un número de teléfono (o acepte el valor predeterminado), seleccione Traducir y, a continuación, seleccione Llamar.
En la alerta Dial a Number, seleccione Yes. Compruebe que el marcador telefónico de Android aparece con el número que ha proporcionado en la aplicación.
Vuelva a Visual Studio y detenga la depuración.
Resumen
En este ejercicio, ha agregado una interfaz de usuario personalizada a la aplicación mediante páginas y vistas. También ha agregado compatibilidad para realizar una llamada mediante las API específicas de la plataforma disponibles en Android.