Android筆記(16):UI元件 DatePicker & TimePicker 日期時間選擇器

Photo by Markus Winkler on Unsplash


DatePicker 和 TimePicker 在 Android 元件中,常被用來協助使用者選擇日期和時間,本篇要來看一下如何使用這兩個元件。這兩個元件會佔用較大版面,我們試著使用 onClick() 呼叫日期/時間輔助對話框來協助使用者選擇。

[DatePicker]

DatePicker 日期選擇元件會在畫面上出現一個日期的選擇框,目的是協助使用者使用日曆的方式來選擇日期。通常如果只是在佈局 Layout 中使用 DatePicker 元件時,會發現選擇的日期需要透過 java/kotlin 程式傳給其他元件,或進行顯示。缺點是佔用太多畫面來顯示日期選擇框,因此有些設計者會使用 onClick()方法,呼叫 DatePickerDialog 來呈現日期選擇框,選擇完成後,將結果傳給文字框或編輯框。如要使用 DatePicker ,可在 Layout 佈局檔 XML 中使用 <DatePicker> 標記來設定,語法格式如下:
<DatePicker
   android:屬性 = "值"> 
</DatePicker>

DatePicker 沒有提供專門的方法來獲得它的值,如果要取得使用者按下的值,只能通過 Calendar.getInstance().get() 方法獲取年月日值。DatePicker 繼承自 android.widget.FrameLayout,除了 FrameLayout 可用的屬性外,還有以下幾種:
XML屬性說明
calendarTextColor日曆清單的文字顏色。
calendarViewShown是否顯示日曆視圖。
datePickerMode設定 datePicker 的外觀,有calendar(預設)和 spinner兩種。
dayOfWeekBackground星期列的背景顏色。
dayOfWeekTextAppearance星期列的文字顏色。
startYear設置可選擇的第一年。
endYear設定可選之結束年。
firstDayOfWeek設定日曆列表以星期幾開始。
headerBackground整個表頭的背景顏色。
headerDayOfMonthTextAppearance表頭日期字體的顏色。
headerMonthTextAppearance表頭月份的字體顏色。
headerYearTextAppearance表頭年份的字體顏色。
maxDate最大日期,以 mm/dd/yyyy 格式顯示在日曆上。
minDate最小日期,以 mm/dd/yyyy 格式顯示在日曆上。
spinnersShown是否顯示 spinner 外觀。
yearListItemTextAppearance清單的文本出現在清單中。
yearListSelectorColor年列表選擇的顏色

datePickerMode 設定 DatePicker 的樣式有 calendar(下圖左上)和 spinner(下圖左下)兩種。timePickerMode 設定 TimePicker 的外觀,主要有 clock(預設)(下圖右上) 和 spinner (下圖右下)兩種。

DatePickerDialog 是一個彈出對話方塊用於選擇日期,如果要使用 java/kotlin 呼叫日期選擇對話框,可以使用 DatePickerDialog() 這個方法:
DatePickerDialog(Context context, DatePickerDialog.OnDateSetListener listener,
         int year, int monthOfYear, int dayOfMonth)         
DatePickerDialog()參數說明如下:
  • context:當前上下文
  • listener:日期改變監聽器
  • year:年
  • monthOfYear:月
  • dayOfMonth:日

DatePickerDialog()繼承自 android.app.AlertDialog,因此具有 AlertDialog 相關屬性可以使用。如要使用 DatePickerDialog() ,只要 new 一個 DatePickerDialog 物件,然後調用 .show() 方法就可以將時間選擇對話框顯示出來。DatePickerDialog 有相對應的事件監聽器,用於獲取當前所設置的事件。

其他常用的方法還有:
  • int getDayOfMonth():取得選取的日期
  • int getMonth():取得選取的月份,從0開始,0表示1月
  • int getYear():取得選取的年份
  • void updateDate(int year, int month, int dayOfMonth):更改選取日期

[TimePicker]

TimePicker 時間選擇元件會在畫面上出現一個時間的選擇框,目的是協助使用者使用時鐘的方式來選擇時間,可以是 24 小時制或 AM/PM 12 小時制。通常如果只是在佈局 Layout 中使用 TimePicker 元件時,會發現選擇的時間需要透過 java/kotlin 程式傳給其他元件,或進行顯示。缺點是佔用太多畫面來顯示時間選擇框,因此有些設計者會使用 onClick()方法,呼叫 TimePickerDialog 來呈現時間選擇框,選擇完成後,將結果傳給文字框或編輯框。如要使用 TimePicker,可在 Layout 佈局檔 XML 中使用 <TimePicker> 標記來設定,語法格式如下:
<TimePicker
   android:屬性 = "值"> 
</TimePicker>
TimePicker 沒有提供專門的方法來獲得它的值,如果要取得使用者按下的值,只能通過 Calendar.getInstance().get() 方法獲取時、分值。TimePicker 繼承自 android.widget.FrameLayout,除了 FrameLayout 可用的屬性外,還有以下幾種:
XML屬性說明
timePickerMode設定 TimePicker 的外觀,參考上方右圖,有 clock(預設)(下圖右上) 和 spinner(下圖右下) 兩種。
TimePickerDialog 是一個彈出的對話框用於選擇時間,如果要使用 java/kotlin 呼叫時間選擇對話框,可以使用 TimePickerDialog() 這個方法:
TimePickerDialog(Context context, TimePickerDialog.OnTimeSetListener listener, 
				int hourOfDay, int minute, boolean is24HourView)
參數說明如下:
  • context:當前上下文。
  • listener:時間改變監聽器。
  • hourOfDay:初始化 小時。
  • minute:初始化 分鐘。
  • is24HourView:是否以 24 小時顯示時間,true 為 24 小時制。
預設是 12 小時制的,可以透過 setIs24HourView(true) 方法改成 24 小時制。

TimePickerDialog()繼承自 android.app.AlertDialog,因此具有 AlertDialog 相關屬性可以使用。如要使用 TimePickerDialog() ,只要 new 一個 TimePickerDialog 物件,然後調用 .show() 方法就可以將時間選擇對話框顯示出來。TimePickerDialog 有相對應的事件監聽器,用於獲取當前所設置的事件。


[程式範例]

(1)新建一個模組 Module,進入 res/layout 目錄下點選佈局檔 activity_main.xml。將預設的內容刪除,建立 2 個 EditText 文字編輯框,並設定 onClick() 呼叫的程序名稱,以下是整個 XML 的內容。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerVertical="true"
    android:orientation="vertical">

    <EditText
        android:id="@+id/applydate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50sp"
        android:layout_marginTop="30sp"
        android:layout_marginRight="30sp"
        android:inputType="date"
        android:text=" 日期: YYYY-MM-DD "
        android:onClick="datePicker"
        android:textSize="26sp" />

    <EditText
        android:id="@+id/applytime"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50sp"
        android:layout_marginTop="30sp"
        android:layout_marginRight="30sp"
        android:inputType="time"
        android:text=" 時間: HH:MM "
        android:onClick="timePicker"
        android:textSize="26sp" />

</LinearLayout>

(2)在 MainActivity.java 在 onCreate() 方法內,先建立與佈局檔的物件,用 findValueById 連結元件,建立 datePicker 和 timePicker 兩個子程序,在程序內呼叫 datePickerDialog 和 timePickerDialog,然後改寫(Override)兩個方法:onDateSet 和 onTimeSet,將取得的值指定給日期和時間編輯框。程式碼如下:
package com.example.mydatetime;

import androidx.appcompat.app.AppCompatActivity;

import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TimePicker;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

public class dt_MainActivity extends AppCompatActivity {

    private EditText applydate = null;
    private EditText applytime = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dt_main);

        // 視窗最大化
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        applydate = findViewById(R.id.applydate);
        applytime = findViewById(R.id.applytime);
    }

    public void datePicker(View v) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);      //取得現在的日期年月日
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        
        new DatePickerDialog(v.getContext(), new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int month, int day) {
                String datetime = String.valueOf(year) + "-" + String.valueOf(month) + "-" + String.valueOf(day);
                applydate.setText(datetime);   //取得選定的日期指定給日期編輯框
            }
        }, year, month, day).show();
    }

    public void timePicker(View v) {
        Calendar calendar = Calendar.getInstance();
        int hourOfDay = calendar.get(Calendar.HOUR);
        int minute = calendar.get(Calendar.MINUTE);

        new TimePickerDialog(v.getContext(), new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                String datetime = String.valueOf(hourOfDay) + ":" + String.valueOf(minute);
                applytime.setText(datetime);  //取得選定的時間指定給時間編輯框
            }
        }, hourOfDay, minute,true).show();

    }
}

執行的結果如下:

[參考資料]


1 留言

張貼留言

較新的 較舊