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

Android 日期時間選擇器:僅顯示月日時的自定義實現

     編輯:程式設計疑難解答

需求

單一控件同時選擇日期(月、日)和時間(24制時),不顯示年份、分、秒。

方案一:NumberPicker 組合(輕量、無依賴)


public class MonthDayHourPicker extends LinearLayout {
    private NumberPicker npMonth, npDay, npHour;
    private Calendar calendar = Calendar.getInstance();
    
    public MonthDayHourPicker(Context context) {
        super(context);
        init(context);
    }
    
    private void init(Context context) {
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        
        npMonth = createPicker(1, 12, calendar.get(Calendar.MONTH) + 1, "%02d月");
        npDay = createPicker(1, 31, calendar.get(Calendar.DAY_OF_MONTH), "%02d日");
        npHour = createPicker(0, 23, calendar.get(Calendar.HOUR_OF_DAY), "%02d時");
        
        // 動態調整日數(根據月份)
        npMonth.setOnValueChangedListener((picker, oldVal, newVal) -> updateDayRange(newVal));
        
        addView(npMonth, new LayoutParams(0, WRAP_CONTENT, 1));
        addView(npDay, new LayoutParams(0, WRAP_CONTENT, 1));
        addView(npHour, new LayoutParams(0, WRAP_CONTENT, 1));
    }
    
    private NumberPicker createPicker(int min, int max, int current, String format) {
        NumberPicker np = new NumberPicker(getContext());
        np.setMinValue(min);
        np.setMaxValue(max);
        np.setValue(current);
        np.setFormatter(v -> String.format(format, v));
        return np;
    }
    
    private void updateDayRange(int month) {
        int maxDay = getMaxDayOfMonth(month);
        npDay.setMaxValue(maxDay);
        if (npDay.getValue() > maxDay) npDay.setValue(maxDay);
    }
    
    private int getMaxDayOfMonth(int month) {
        switch (month) {
            case 2: return 28; // 簡化,不考慮閏年
            case 4: case 6: case 9: case 11: return 30;
            default: return 31;
        }
    }
    
    public Calendar getSelectedDateTime() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, npMonth.getValue() - 1);
        cal.set(Calendar.DAY_OF_MONTH, npDay.getValue());
        cal.set(Calendar.HOUR_OF_DAY, npHour.getValue());
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }
}

方案二:隱藏 DatePicker/TimePicker 年份與分秒(原生組件)


// DatePicker 隱藏年份
int yearPickerId = Resources.getSystem().getIdentifier("year", "id", "android");
View yearPicker = datePicker.findViewById(yearPickerId);
if (yearPicker != null) yearPicker.setVisibility(View.GONE);

// TimePicker 隱藏分秒(API 24+)
timePicker.setIs24HourView(true);
// 隱藏分鐘選擇器(需反射或自定義布局)
// 參考:https://www.iteye.com/topic/1131942

方案三:第三方庫(MaterialDateTimePicker / SingleDateAndTimePicker)


// build.gradle
implementation 'com.github.florent37:singledateandtimepicker:2.2.0'

// 使用
new SingleDateAndTimePicker.Builder(context)
    .displayHours(true)
    .displayMinutes(false)
    .displayDays(true)
    .displayMonths(true)
    .displayYears(false)
    .title("選擇月日時")
    .build()
    .show();

對比選型

方案優點缺點推薦場景
NumberPicker 組合輕量、完全可控、無反射風險需自行處理閏年、日數聯動簡單表單、不想引入庫
原生組件隱藏系統風格一致、無依賴反射脆弱、API 變動風險、定制受限需系統原生外觀
第三方庫功能豐富、Material 風格、維護活躍增大包體積、版本兼容性複雜交互、項目已用相關庫

推薦 NumberPicker 組合:代碼可控、邏輯清晰、輕量無依賴,滿足「月日時」精確定制需求。

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