MaterialDatePicker 获取选定的日期

Posted

技术标签:

【中文标题】MaterialDatePicker 获取选定的日期【英文标题】:MaterialDatePicker get selected dates 【发布时间】:2020-12-06 13:50:26 【问题描述】:

我在 android 中这样调用 MaterialDatePicker:

MaterialDatePicker.Builder<Pair<Long, Long>> builder = MaterialDatePicker.Builder.dateRangePicker();

CalendarConstraints.Builder constraintsBuilder = new CalendarConstraints.Builder();
builder.setCalendarConstraints(constraintsBuilder.build());

int dialogTheme = resolveOrThrow(getContext(), R.attr.materialCalendarTheme);
builder.setTheme(dialogTheme);

MaterialDatePicker<?> picker = builder.build();

picker.show(getFragmentManager(), picker.toString());

图书馆是:

dependencies 
    implementation 'com.google.android.material:material:1.2.0-alpha01'

如何获取此日历的选定日期?我找不到像 onDateSetOnDateSetListener 这样的听众

【问题讨论】:

【参考方案1】:

只需使用在用户确认有效选择时调用的 addOnPositiveButtonClickListener 侦听器:

对于单一日期选择器:

picker.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener<Long>() 
      @Override public void onPositiveButtonClick(Long selection) 
        // Do something...
        //Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        //calendar.setTimeInMillis(selection);   

      
    );

对于范围日期选择器

MaterialDatePicker<Pair<Long, Long>> pickerRange = builderRange.build();
pickerRange.show(....);

pickerRange.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener<Pair<Long, Long>>() 
  @Override public void onPositiveButtonClick(Pair<Long,Long> selection) 
       Long startDate = selection.first;
       Long endDate = selection.second;
       //Do something...
  
);

【讨论】:

您能否通过如何从 Long 转换为 Calendar 或 LocalDate 来增强您的答案?我试过 LocalDate.ofEpochDay 和 LocalDateTime.ofEpochSecond 但它不起作用。谢谢 @LorenzoPetroli 选择器将所有 long 值解释为 UTC 纪元的毫秒数。您可以使用Instant.ofEpochMilli(dateSelected)LocalDateTime.ofInstant(...),否则使用Calendar.setTimeInMillis(dateSelected)。关注LocalDateTime.ofEpochSecond;它适用于秒而不是毫秒。【参考方案2】:

对于那些为此而苦苦挣扎的人以及他们的时间戳是一天的事实,这是我的工作解决方案。我有 API 23 的要求,所以我不能在 java.time.* 中使用任何好的 Epoch 函数。对我来说,关键是意识到我需要做时区偏移数学。

        picker.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener<Long>() 
        @Override
        public void onPositiveButtonClick(Long selectedDate) 
            // user has selected a date
            // format the date and set the text of the input box to be the selected date
            // right now this format is hard-coded, this will change
            ;
            // Get the offset from our timezone and UTC.
            TimeZone timeZoneUTC = TimeZone.getDefault();
            // It will be negative, so that's the -1
            int offsetFromUTC = timeZoneUTC.getOffset(new Date().getTime()) * -1;

            // Create a date format, then a date object with our offset
            SimpleDateFormat simpleFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
            Date date = new Date(selectedDate + offsetFromUTC);

            dataEntry.setText(simpleFormat.format(lDate));
        
    );
    picker.show(myActivity.getSupportFragmentManager(), picker.toString());

【讨论】:

第一次工作,但后来offsetFromUTC 为0。所以,我设置了simpleFormat.setTimeZone(TimeZone.getTimeZone("UTC"));。将进一步测试。【参考方案3】:

GR Envoy的回答不错,但是我想改一下。最好将时区设置为 UTC。

private val outputDateFormat = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()).apply 
    timeZone = TimeZone.getTimeZone("UTC")


...
picker.addOnPositiveButtonClickListener 
    val text = outputDateFormat.format(it)

【讨论】:

【参考方案4】:

我四处搜索,发现许多 Material DatePicker Range get selected dates 解决方案已被弃用。

我在我的项目中使用dateRangePicker,所以下面的代码仅适用于dateRangePicker(),因为我需要同时获取开始日期和结束日期。

在我的 Java 活动代码中:

            materialDatePicker.addOnPositiveButtonClickListener(new MaterialPickerOnPositiveButtonClickListener() 
            @Override
            public void onPositiveButtonClick(Object selection) 
//                Get the selected DATE RANGE
                Pair selectedDates = (Pair) materialDatePicker.getSelection();
//              then obtain the startDate & endDate from the range
                final Pair<Date, Date> rangeDate = new Pair<>(new Date((Long) selectedDates.first), new Date((Long) selectedDates.second));
//              assigned variables
                Date startDate = rangeDate.first;
                Date endDate = rangeDate.second;
//              Format the dates in ur desired display mode
                SimpleDateFormat simpleFormat = new SimpleDateFormat("dd MMM yyyy");
//              Display it by setText
                datedisplay.setText("SELECTED DATE : " +  simpleFormat.format(startDate) + " Second : " + simpleFormat.format(endDate));
            

        );

示例输出:

【讨论】:

哪些解决方案被弃用了?【参考方案5】:

日期选择器代码:(这里我在按钮的点击事件上打开日期选择器)

  datePicker.setOnClickListener(v -> 

        MaterialDatePicker datePicker =
                MaterialDatePicker.Builder.datePicker()
                        .setTitleText("Select date")
                        .build();
        datePicker.show(getSupportFragmentManager(), "date");

        datePicker.addOnPositiveButtonClickListener((MaterialPickerOnPositiveButtonClickListener<Long>) selection -> 
            String dateString = DateFormat.format("dd/MM/yyyy", new Date(selection)).toString();
            Toast.makeText(this, dateString, Toast.LENGTH_SHORT).show();
        );
    );

日期范围选择器代码:(这里我在按钮的点击事件上打开日期范围选择器)

dateRangePicker.setOnClickListener(v -> 
        MaterialDatePicker datePicker =
                MaterialDatePicker.Builder.dateRangePicker()
                        .setSelection(new Pair(MaterialDatePicker.thisMonthInUtcMilliseconds(),
                                MaterialDatePicker.todayInUtcMilliseconds()))
                        .setTitleText("Select dates")
                        .build();
        datePicker.show(getSupportFragmentManager(), "date");

        datePicker.addOnPositiveButtonClickListener((MaterialPickerOnPositiveButtonClickListener<Pair<Long, Long>>) selection -> 
            Long startDate = selection.first;
            Long endDate = selection.second;
            String startDateString = DateFormat.format("dd/MM/yyyy", new Date(startDate)).toString();
            String endDateString = DateFormat.format("dd/MM/yyyy", new Date(endDate)).toString();
            String date = "Start: " + startDateString + " End: " + endDateString;
            Toast.makeText(TextViewActivity.this, date, Toast.LENGTH_SHORT).show();
        );
    );

时间选择器代码:(这里我在按钮的点击事件上打开时间选择器)

  timePicker.setOnClickListener(v -> 
        MaterialTimePicker timePicker = new MaterialTimePicker.Builder()
                .setTimeFormat(TimeFormat.CLOCK_12H)
                .setHour(12)
                .setTitleText("Select Appointment time")
                .setMinute(10)
                .build();
        timePicker.show(getSupportFragmentManager(), "time");

        timePicker.addOnPositiveButtonClickListener(v12 -> 
            int hour = timePicker.getHour();
            int min = timePicker.getMinute();
            Toast.makeText(TextViewActivity.this, "Time is: " + hour + ":" + min, Toast.LENGTH_SHORT).show();
        );

        timePicker.addOnNegativeButtonClickListener(v13 -> Toast.makeText(TextViewActivity.this, "Cancel", Toast.LENGTH_SHORT).show());
    );

【讨论】:

【参考方案6】:

buttonPickDate.setOnClickListener 
    
    // Create the date picker builder and set the title
    val builder = MaterialDatePicker.Builder.datePicker()
        .also 
            title = "Pick Date"
        


    // create the date picker 
    val datePicker = builder.build()
    
    // set listener when date is selected
    datePicker.addOnPositiveButtonClickListener 
        
        // Create calendar object and set the date to be that returned from selection
        val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
        calendar.time = Date(it)
        textView.text = "$calendar.get(Calendar.DAY_OF_MONTH)- " +
                "$calendar.get(Calendar.MONTH) + 1-$calendar.get(Calendar.YEAR)"

    

    datePicker.show(supportFragmentManager, "MyTAG")


https://ngengesenior.medium.com/pick-dates-using-the-new-material-date-picker-android-c13620bafbcb

【讨论】:

以上是关于MaterialDatePicker 获取选定的日期的主要内容,如果未能解决你的问题,请参考以下文章

MaterialDatePicker,选择结束日期后应用程序崩溃

MaterialDatePicker 显示当前日期而不是需要

MaterialDatePicker 选择后返回不正确的日期

如何在 MaterialDatePicker 中禁用过去的日期?

如何在MaterialDatePicker中打开之前选择的日期?

使用 jQuery 和 bootstrap-datetimepicker 获取两个日期,但它们之间的日差错误