如何在安卓系统中创建日期和时间选择器?

147

是否有任何Android小部件可以同时选择日期和时间?我已经使用基本的时间选择器日期选择器

但它们并不太美观和用户友好(我发现)。你知道是否存在一个包括日期和时间的小部件吗?

非常感谢, Luc


1
有一个适用于日期和时间选择器的 Github 库:AndroidDateTimePicker - user12949439
15个回答

90

在布局XML中同时放置DatePickerTimePicker

date_time_picker.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:padding="8dp"
    android:layout_height="match_parent">

    <DatePicker
        android:id="@+id/date_picker"
        android:layout_width="match_parent"
        android:calendarViewShown="true"
        android:spinnersShown="false"
        android:layout_weight="4"
        android:layout_height="0dp" />

    <TimePicker
        android:id="@+id/time_picker"
        android:layout_weight="4"
        android:layout_width="match_parent"
        android:layout_height="0dp" />

    <Button
        android:id="@+id/date_time_set"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:text="Set"
        android:layout_height="0dp" />

</LinearLayout>

代码:

final View dialogView = View.inflate(activity, R.layout.date_time_picker, null);
final AlertDialog alertDialog = new AlertDialog.Builder(activity).create();

dialogView.findViewById(R.id.date_time_set).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

         DatePicker datePicker = (DatePicker) dialogView.findViewById(R.id.date_picker);
         TimePicker timePicker = (TimePicker) dialogView.findViewById(R.id.time_picker);

         Calendar calendar = new GregorianCalendar(datePicker.getYear(),
                            datePicker.getMonth(),
                            datePicker.getDayOfMonth(),
                            timePicker.getCurrentHour(),
                            timePicker.getCurrentMinute());

         time = calendar.getTimeInMillis();
         alertDialog.dismiss();
    }});
alertDialog.setView(dialogView);
alertDialog.show();

2
非常棒的例子,感谢。有一点要注意...你可能想在onClick实现的末尾加上alertDialog.dismiss();。 - Jonathan
这个例子中无法选择年份。 - lostintranslation
@Awadesh,针对横屏,您需要创建另一个XML文件,类似于:https://dev59.com/oW445IYBdhLWcg3wcJ6O#4858052 - Oded Breiner
它可以工作,但当我从横屏模式切换到竖屏模式或反之亦然时,它不会自动更改。 - Awadesh
1
Android 6.0+这个布局看起来很丑;(https://static.pychat.org/photo/f1qRFo31_Screenshot_20170214-123713.png) - deathangel908
显示剩余3条评论

81
使用此函数,您可以逐个选择日期和时间,然后将其设置为全局变量date。无需库或XML。
Calendar date;
public void showDateTimePicker() {
   final Calendar currentDate = Calendar.getInstance();
   date = Calendar.getInstance();
   new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
       @Override
       public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            date.set(year, monthOfYear, dayOfMonth);
            new TimePickerDialog(context, new TimePickerDialog.OnTimeSetListener() {
                @Override
                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                    date.set(Calendar.HOUR_OF_DAY, hourOfDay);
                    date.set(Calendar.MINUTE, minute);
                    Log.v(TAG, "The choosen one " + date.getTime());
                }
            }, currentDate.get(Calendar.HOUR_OF_DAY), currentDate.get(Calendar.MINUTE), false).show();
       }
   }, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
}

最简单的方法之一 - Vicky Thakor
4
调用需要 API 级别 24。 - Ravi R Priyadarshi
我该如何获取datePicker对象?我想禁用过去的日期。 - Arpit Patel

54

Android内部没有提供此功能。

编辑:现在,Android提供了内置选取器。请查看@Oded answer


2
我知道这个回复已经超过一年了,但我认为这个回复应该更新。Rabi在下面提到的DateSlider库似乎非常适合这个问题。 - Stephan Branczyk
我同意这个答案应该更新,因为那是一个很棒的小部件。然而,Rabi指出的代码已经有点过时了,并且包含一些已弃用的方法,例如showDialog。也许很快会出现更现代的解决方案。 - Eugene van der Merwe
14
实际答案是正确的,不应该更新。即使存在 AndroidDateSlider,Android 中也没有内置任何提供该功能的内容。 - Cristian
4
我是唯一一个对谷歌甚至不支持任何商业应用程序中最广泛使用的控件感到困惑的人吗? - TtT23

29

在Android中的DialogFragment中结合DatePicker和TimePicker

我创建了一个来实现这个。它还有可定制的颜色!

使用起来非常简单。

首先你需要创建一个监听器:

private SlideDateTimeListener listener = new SlideDateTimeListener() {

    @Override
    public void onDateTimeSet(Date date)
    {
        // Do something with the date. This Date object contains
        // the date and time that the user has selected.
    }

    @Override
    public void onDateTimeCancel()
    {
        // Overriding onDateTimeCancel() is optional.
    }
};

然后您创建并显示对话框:

new SlideDateTimePicker.Builder(getSupportFragmentManager())
    .setListener(listener)
    .setInitialDate(new Date())
    .build()
    .show();

我希望你觉得这很有用。


真的很好!节省了我的时间!谢谢!不过,我不得不克隆代码,因为我认为Gradle依赖字符串无效? - kuldeep
@JDJ 抱歉,我无法将你的库添加到我的项目中,你能否解释一下如何操作? - Sebastian Delgado
3
步骤1 点击“Clone or download”,然后点击“Download ZIP”下载整个项目。 步骤2 解压缩ZIP内容,或者只解压缩ZIP\SlideDateTimePicker-master\slideDateTimePicker文件夹,然后将该文件夹复制到您现有项目的根目录容器中,即您想要添加插件的位置。 步骤3 通过Gradle添加依赖项,使用"compile project(':slideDateTimePicker')" OR 在Android Studio中:File > New > Import Project,选择提取的文件夹并按照常规方式配置项目导入,接受并继续下一步,完成安装。 - Ninja Coding
2
@JDJ,我们发现一个问题,在Lollipop或Marshmallow上,原生的DatePicker和TimePicker没有显示出来,而是显示了早期版本的组件。 - Ninja Coding
请注意,我认为这个库已经不再可用,并且已被放弃。https://github.com/jjobes/SlideDateTimePicker/issues/59 - Joshua
显示剩余7条评论

21

DatePicker 的更新时间方法中调用时间选择器对话框。它不会在同一时间被调用,而是当你按下 DatePicker 的设置按钮时才会调用。时间选择器对话框将会打开。

以下是该方法的代码:

package com.android.date;

import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

public class datepicker extends Activity {

    private TextView mDateDisplay;
    private Button mPickDate;
    private int mYear;
    private int mMonth;
    private int mDay;
    private TextView mTimeDisplay;
    private Button mPickTime;

    private int mhour;
    private int mminute;

    static final int TIME_DIALOG_ID = 1;

    static final int DATE_DIALOG_ID = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mDateDisplay =(TextView)findViewById(R.id.date);
        mPickDate =(Button)findViewById(R.id.datepicker);
        mTimeDisplay = (TextView) findViewById(R.id.time);
        mPickTime = (Button) findViewById(R.id.timepicker);

        //Pick time's click event listener
        mPickTime.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                showDialog(TIME_DIALOG_ID);
            }
        });

        //PickDate's click event listener 
        mPickDate.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(DATE_DIALOG_ID);
            }
        });

        final Calendar c = Calendar.getInstance();
        mYear = c.get(Calendar.YEAR);
        mMonth = c.get(Calendar.MONTH);
        mDay = c.get(Calendar.DAY_OF_MONTH);
        mhour = c.get(Calendar.HOUR_OF_DAY);
        mminute = c.get(Calendar.MINUTE);
    }

    //-------------------------------------------update date---//    
    private void updateDate() {
        mDateDisplay.setText(
            new StringBuilder()
                    // Month is 0 based so add 1
                    .append(mDay).append("/")
                    .append(mMonth + 1).append("/")
                    .append(mYear).append(" "));
        showDialog(TIME_DIALOG_ID);
    }

      //-------------------------------------------update time---//    
    public void updatetime() {
        mTimeDisplay.setText(
                new StringBuilder()
                        .append(pad(mhour)).append(":")
                        .append(pad(mminute))); 
    }

    private static String pad(int c) {
        if (c >= 10)
            return String.valueOf(c);
        else
            return "0" + String.valueOf(c);


    //Datepicker dialog generation  

    private DatePickerDialog.OnDateSetListener mDateSetListener =
        new DatePickerDialog.OnDateSetListener() {

            public void onDateSet(DatePicker view, int year, 
                                  int monthOfYear, int dayOfMonth) {
                mYear = year;
                mMonth = monthOfYear;
                mDay = dayOfMonth;
                updateDate();
            }
        };


     // Timepicker dialog generation
        private TimePickerDialog.OnTimeSetListener mTimeSetListener =
            new TimePickerDialog.OnTimeSetListener() {
                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                    mhour = hourOfDay;
                    mminute = minute;
                    updatetime();
                }
            };

        @Override
        protected Dialog onCreateDialog(int id) {
            switch (id) {
            case DATE_DIALOG_ID:
                return new DatePickerDialog(this,
                            mDateSetListener,
                            mYear, mMonth, mDay);

            case TIME_DIALOG_ID:
                return new TimePickerDialog(this,
                        mTimeSetListener, mhour, mminute, false);

            }
            return null;
        }
}

下面是给出的main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello"/>

    <TextView android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <Button
        android:id="@+id/timepicker"
        android:text="Change Time" 
        android:layout_height="wrap_content" 
        android:layout_width="wrap_content"/>

    <TextView 
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <Button android:id="@+id/datepicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="200dp"
        android:text="Change the date"/>

</LinearLayout>

15

非常好的优雅解决方案。工作得很好。我遇到了一些小问题.. 1)AM/PM标签被截断了,因此我不得不在样式中设置较小的字体大小<item name="android:textSize">11sp</item>并移除加粗设置。2)看起来必须调用setDefaultDateTime(..)或者你会得到运行时异常..所以我使用Calendar.getInstance().getTime()作为参数调用它。迄今为止我见过的最好的日期选择器Github项目-感谢您分享它。 - Gene Bo

13

你提供的链接演示如何弹出带有时间选择器和日期选择器对话框。但是你需要注意,你可以直接在自己的布局中使用这些UI小部件。你可以构建自己的对话框,在同一个视图中包括TimePicker和DatePicker,以此完成我认为你正在寻找的目标。

换句话说,不要使用TimePickerDialog和DatePickerDialog,而是直接在自己的对话框或活动中使用UI小部件TimePickerDatePicker


1
我同意@Jaydeep Khamar的解决方案并不是所要求的,那些是打开两个单独的对话框。最好看到已经结合了这个功能的基本示例代码。 - Eugene van der Merwe

9

在我的一个项目中,我遇到了同样的问题,并决定制作一个自定义小部件,在一个用户友好的对话框中同时拥有日期和时间选择器。您可以在http://code.google.com/p/datetimepicker/获取源代码和示例。该代码使用Apache 2.0许可证。


6

2
你有使用这个的示例吗? - Roger Keays

5

您可以使用一个DatePicker库,例如wdullaer/MaterialDateTimePicker

  • First show DatePicker.

    private void showDatePicker() {
    Calendar now = Calendar.getInstance();
    DatePickerDialog dpd = DatePickerDialog.newInstance(
            HomeActivity.this,
            now.get(Calendar.YEAR),
            now.get(Calendar.MONTH),
            now.get(Calendar.DAY_OF_MONTH)
    );
    dpd.show(getFragmentManager(), "Choose Date:");
    }
    
  • Then onDateSet callback store date & show TimePicker

    @Override
    public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
    Calendar cal = Calendar.getInstance();
    cal.set(year, monthOfYear, dayOfMonth);
    filter.setDate(cal.getTime());
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            showTimePicker();
        }
    },500);
    }
    
  • On onTimeSet callback store time

     @Override
     public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) {
    Calendar cal = Calendar.getInstance();
    if(filter.getDate()!=null)
        cal.setTime(filter.getDate());
    cal.set(Calendar.HOUR_OF_DAY,hourOfDay);
    cal.set(Calendar.MINUTE,minute);
    }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接