首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android開發實戰:點擊區域彈出日期選擇器完整實現指南

     編輯:程式設計疑難解答

需求場景

點擊文本框、按鈕或任意 View 區域,彈出系統風格的日期選擇對話框,用戶選擇後回顯到控件上。適用於生日選擇、預約日期等場景。

核心組件:DatePickerDialog

Android 提供 `DatePickerDialog` 封裝了日曆選擇邏輯,配合 `OnDateSetListener` 即可快速實現。

完整代碼實現

1. 佈局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="點擊選擇日期"
        android:textSize="18sp"
        android:padding="12dp"
        android:background="@android:drawable/edit_text"
        android:drawableEnd="@android:drawable/ic_menu_my_calendar"
        android:clickable="true"
        android:focusable="true" />
</LinearLayout>

2. Activity/Java 代碼

public class DatePickerActivity extends AppCompatActivity {

    private TextView tvDate;
    private int mYear, mMonth, mDay;

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

        tvDate = findViewById(R.id.tv_date);
        
        // 初始化為今天
        Calendar calendar = Calendar.getInstance();
        mYear = calendar.get(Calendar.YEAR);
        mMonth = calendar.get(Calendar.MONTH);
        mDay = calendar.get(Calendar.DAY_OF_MONTH);
        updateDateText();

        tvDate.setOnClickListener(v -> showDatePicker());
    }

    private void showDatePicker() {
        DatePickerDialog dialog = new DatePickerDialog(
            this,
            (view, year, month, dayOfMonth) -> {
                mYear = year;
                mMonth = month;
                mDay = dayOfMonth;
                updateDateText();
            },
            mYear, mMonth, mDay
        );
        dialog.show();
    }

    private void updateDateText() {
        String monthStr = (mMonth + 1) < 10 ? "0" + (mMonth + 1) : String.valueOf(mMonth + 1);
        String dayStr = mDay < 10 ? "0" + mDay : String.valueOf(mDay);
        tvDate.setText(mYear + "-" + monthStr + "-" + dayStr);
    }
}

進階優化技巧

1. 限制日期範圍(如:不可選過去日期)

dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000); // 今天之後
// 或
dialog.getDatePicker().setMaxDate(System.currentTimeMillis()); // 今天之前

2. 自定義主題樣式

<!-- styles.xml -->
<style name="CustomDatePicker" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">#FF5722</item> <!-- 選中顏色 -->
    <item name="android:windowBackground">@android:color/white</item>
</style>

// 使用
new DatePickerDialog(this, R.style.CustomDatePicker, listener, year, month, day);

3. 使用 DialogFragment 管理生命周期(推薦)

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        return new DatePickerDialog(requireActivity(), 
            (DatePickerDialog.OnDateSetListener) getTargetFragment(),
            c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
    }
}

// 調用
DatePickerFragment fragment = new DatePickerFragment();
fragment.setTargetFragment(this, REQUEST_CODE);
fragment.show(getSupportFragmentManager(), "datePicker");

常見坑點提醒

  • ⚠️ `month` 參數是 0-11,顯示/存儲時需 +1。
  • ⚠️ Activity 重建(旋轉屏幕)會導致 Dialog 丟失,使用 `DialogFragment` 可自動恢復。
  • ⚠️ Android 7.0+ `DatePickerDialog` 默認顯示年份滾動器,若需日曆視圖需自定義或用第三方庫(如 MaterialDatePicker)。

總結

`DatePickerDialog` + `OnDateSetListener` 是最輕量的原生方案。生產項目建議封裝為工具類或 `DialogFragment`,統一處理主題、範圍限制、生命周期,提升復用性與穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved