共用方式為


Android 時間選擇器

若要讓使用者選取時間,您可以使用 TimePicker。 Android 應用程式通常會與 TimePickerDialog 搭配使用TimePicker,以選取時間值 – 這有助於確保裝置和應用程式之間的一致介面。 TimePicker 可讓用戶選取 24 小時或 12 小時 AM/PM 模式的一天時間。 TimePickerDialog 是將 TimePicker 封裝在對話框中的協助程序類別。

[時間選擇器] 對話框運作的範例螢幕快照

概觀

新式 Android 應用程式會在 DialogFragment顯示 TimePickerDialog 。 這可讓應用程式將 顯示為 TimePicker 快顯對話框,或將其內嵌在活動中。 此外,會 DialogFragment 管理對話框的生命週期和顯示,以減少必須實作的程式代碼數量。

本指南示範如何使用 TimePickerDialog包裝在 中的 DialogFragment。 當使用者按兩下活動上的按鈕時,範例應用程式會顯示 TimePickerDialog 為強制回應對話框。 當使用者設定時間時,對話框會結束,而處理程式會在 [活動] 畫面上更新 ,並顯示 TextView 已選取的時間。

需求

本指南的範例應用程式是以Android 4.1 (API 層級16) 或更高版本為目標,但可以搭配Android 3.0使用(API層級11或更高版本)。 透過將 Android 支援連結庫 v4 新增至專案和某些程式代碼變更,就可以支援舊版 Android。

使用 TimePicker

此範例會 DialogFragment擴充 ;的子類別實作 DialogFragment (如下稱為 TimePickerFragment )主機,並顯示 TimePickerDialog。 第一次啟動範例應用程式時,它會在 上方TextView顯示 [挑選時間] 按鈕,用來顯示選取的時間:

初始範例應用程式畫面

當您按鍵按鍵 ,範例應用程式會 TimePickerDialog 啟動 ,如下列螢幕快照所示:

應用程式顯示的預設時間選擇器對話框螢幕快照

在 中 TimePickerDialog,選取時間並按兩下 [確定 ] 按鈕,會導致 TimePickerDialog 叫用方法 IOnTimeSetListener.OnTimeSet。 這個介面是由裝載 DialogFragment 實作的(TimePickerFragment如下所述)。 按兩下 [ 取消] 按鈕會使片段和對話框關閉。

DialogFragment 以下列三種方式之一,將選取的時間傳回主控活動:

  1. 叫用方法或設定屬性 – 活動可以提供特別用來設定此值的屬性或方法。

  2. 引發事件DialogFragment 可以定義叫用時 OnTimeSet 將引發的事件。

  3. Action 使用 – DialogFragment 可以叫Action<DateTime>用 來顯示活動中的時間。 活動會在具現化 DialogFragment時提供 Action<DateTime

此範例會使用第三種技術,這需要 Activity 將處理程式DialogFragment提供給 Action<DateTime>

啟動應用程式專案

啟動名為 TimePickerDemo 的新 Android 專案(如果您不熟悉建立 Xamarin.Android 專案,請參閱 Hello,Android 以瞭解如何建立新專案)。

編輯 Resources/layout/Main.axml ,並將其內容取代為下列 XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"
    android:padding="16dp">
    <Button
        android:id="@+id/select_button"
        android:paddingLeft="24dp"
        android:paddingRight="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="PICK TIME"
        android:textSize="20dp" />
    <TextView
        android:id="@+id/time_display"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:paddingTop="22dp"
        android:text="Picked time will be displayed here"
        android:textSize="24dp" />
</LinearLayout>

這是具有 TextView 的基本 LinearLayout,可顯示時間和開啟的 TimePickerDialogButton。 請注意,此版面配置會使用硬式編碼的字串和維度,讓應用程式更簡單且更容易瞭解 – 生產應用程式通常會使用這些值的資源(如 DatePicker 程式代碼範例所示)。

編輯 MainActivity.cs ,並以下列程式代碼取代其內容:

using Android.App;
using Android.Widget;
using Android.OS;
using System;
using Android.Util;
using Android.Text.Format;

namespace TimePickerDemo
{
    [Activity(Label = "TimePickerDemo", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        TextView timeDisplay;
        Button timeSelectButton;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            timeDisplay = FindViewById<TextView>(Resource.Id.time_display);
            timeSelectButton = FindViewById<Button>(Resource.Id.select_button);
        }
    }
}

當您建置並執行此範例時,您應該會看到類似下列螢幕快照的初始畫面:

初始應用程式畫面

按下 [挑選時間] 按鈕不會執行任何動作,因為 DialogFragment 尚未實作 以顯示 TimePicker。 下一個步驟是建立這個 DialogFragment

擴充 DialogFragment

若要擴充 DialogFragment 以搭配 TimePicker使用,您必須建立衍生自 DialogFragment 並實作 的 TimePickerDialog.IOnTimeSetListener子類別。 將下列類別新增至 MainActivity.cs

public class TimePickerFragment : DialogFragment, TimePickerDialog.IOnTimeSetListener
{
    public static readonly string TAG = "MyTimePickerFragment";
    Action<DateTime> timeSelectedHandler = delegate { };

    public static TimePickerFragment NewInstance(Action<DateTime> onTimeSelected)
    {
        TimePickerFragment frag = new TimePickerFragment();
        frag.timeSelectedHandler = onTimeSelected;
        return frag;
    }

    public override Dialog OnCreateDialog (Bundle savedInstanceState)
    {
        DateTime currentTime = DateTime.Now;
        bool is24HourFormat = DateFormat.Is24HourFormat(Activity);
        TimePickerDialog dialog = new TimePickerDialog
            (Activity, this, currentTime.Hour, currentTime.Minute, is24HourFormat);
        return dialog;
    }

    public void OnTimeSet(TimePicker view, int hourOfDay, int minute)
    {
        DateTime currentTime = DateTime.Now;
        DateTime selectedTime = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day, hourOfDay, minute, 0);
        Log.Debug(TAG, selectedTime.ToLongTimeString());
        timeSelectedHandler (selectedTime);
    }
}

這個 TimePickerFragment 類別會細分為較小的片段,並在下一節中說明。

DialogFragment 實作

TimePickerFragment 會實作數種方法:Factory 方法、Dialog 具現化方法,以及 OnTimeSet 所需的 TimePickerDialog.IOnTimeSetListener處理程式方法。

  • TimePickerFragmentDialogFragment 的子類別。 它也會實作 TimePickerDialog.IOnTimeSetListener 介面(亦即,它提供必要的 OnTimeSet 方法):

    public class TimePickerFragment : DialogFragment, TimePickerDialog.IOnTimeSetListener
    
  • TAG 會針對記錄目的初始化 (MyTimePickerFragment 可以變更為您想要使用的任何字串)。 動作 timeSelectedHandler 會初始化為空委派,以防止 Null 參考例外狀況:

    public static readonly string TAG = "MyTimePickerFragment";
    Action<DateTime> timeSelectedHandler = delegate { };
    
  • 呼叫 NewInstance Factory 方法以具現化新的 TimePickerFragment。 此方法會採用 Action<DateTime> 當使用者按下 中的 [確定 ] 按鈕時叫用的 TimePickerDialog處理程式:

    public static TimePickerFragment NewInstance(Action<DateTime> onTimeSelected)
    {
        TimePickerFragment frag = new TimePickerFragment();
        frag.timeSelectedHandler = onTimeSelected;
        return frag;
    }
    
  • 顯示片段時,Android 會呼叫 DialogFragment OnCreateDialog 方法。 這個方法會建立新的 TimePickerDialog 物件,並使用 Activity、回呼物件(也就是 的目前實例 TimePickerFragment)和目前時間初始化它:

    public override Dialog OnCreateDialog (Bundle savedInstanceState)
    {
        DateTime currentTime = DateTime.Now;
        bool is24HourFormat = DateFormat.Is24HourFormat(Activity);
        TimePickerDialog dialog = new TimePickerDialog
            (Activity, this, currentTime.Hour, currentTime.Minute, is24HourFormat);
        return dialog;
    }
    
  • 當使用者變更對話框中的時間設定 TimePicker 時, OnTimeSet 會叫用 方法。 OnTimeSetDateTime使用目前日期建立 物件,並在使用者選取的時間(小時和分鐘)中合併:

    public void OnTimeSet(TimePicker view, int hourOfDay, int minute)
    {
        DateTime currentTime = DateTime.Now;
        DateTime selectedTime = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day, hourOfDay, minute, 0);
    
  • 這個 DateTime 物件會傳遞至 timeSelectedHandler 在建立時向 物件註冊的 TimePickerFragmentOnTimeSet 會叫用此處理程式,將活動的時間顯示更新為選取的時間(此處理程式會在下一節中實作):

    timeSelectedHandler (selectedTime);
    

顯示 TimePickerFragment

DialogFragment現在已實作 ,現在是時候使用 Factory 方法具現化 DialogFragment ,並叫NewInstance DialogFragment.Show 來顯示它:

將下列方法新增至 MainActivity

void TimeSelectOnClick (object sender, EventArgs eventArgs)
{
    TimePickerFragment frag = TimePickerFragment.NewInstance (
        delegate (DateTime time)
        {
            timeDisplay.Text = time.ToShortTimeString();
        });

    frag.Show(FragmentManager, TimePickerFragment.TAG);
}

具現化 TimePickerFragment之後TimeSelectOnClick,它會建立並傳入匿名方法的委派,以傳遞時間值來更新活動的時間顯示。 最後,它會啟動 TimePicker 對話片段 (透過 DialogFragment.Show) 向使用者顯示 TimePicker

在 方法的 OnCreate 結尾,新增下列這一行,將事件處理程式附加至啟動對話方塊的 PICK TIME 按鈕:

timeSelectButton.Click += TimeSelectOnClick;

按兩下 [挑選時間] 按鈕時,TimeSelectOnClick將會叫用以顯示TimePicker對話框片段給使用者。

請嘗試

建置並執行應用程式。 當您按下 [挑選時間 ] 按鈕時, TimePickerDialog 會以活動的默認時間格式顯示 (在此案例中為上午 12 小時/PM 模式):

時間對話框會以AM/PM模式顯示

當您在對話框中按下 [確定] 時,處理程式會使用所選的時間更新活動的 TextView ,然後TimePicker結束:

活動文字檢視中會顯示 A/M 時間

接下來,將下列程式代碼行新增至 OnCreateDialog 宣告和初始化之後 is24HourFormat 的緊接:

is24HourFormat = true;

這項變更會強制傳遞至建構函true式的TimePickerDialog旗標,以便使用 24 小時模式,而不是裝載活動的時間格式。 當您再次建置並執行應用程式時,按兩下 [挑選時間 ] 按鈕, TimePicker 對話框現在會顯示為 24 小時格式:

24 小時格式的 TimePicker 對話框

因為處理程式會呼叫 DateTime.ToShortTimeString 來列印活動的時間 TextView,因此時間仍會以預設的 12 小時 AM/PM 格式列印。

摘要

本文說明如何從 Android 活動將小工具顯示為 TimePicker 快顯模式對話方塊。 它提供了範例 DialogFragment 實作,並已 IOnTimeSetListener 討論 介面。 此範例也會示範 如何 DialogFragment 與主機活動互動,以顯示選取的時間。