安卓调用系统日历控件:DatePicker与DatePickerDialog

本文介绍如何在Android应用中实现自定义的日期选择器界面,包括使用LinearLayout布局、DatePicker组件及MainActivity类的方法,并解决了相关错误提示及OnDateSetListener回调两次的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. <?xml version=“1.0” encoding=“utf-8”?>  
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  3.     xmlns:tools=“http://schemas.android.com/tools”  
  4.     android:layout_width=“match_parent”  
  5.     android:layout_height=“match_parent”  
  6.     android:orientation=“vertical”  
  7.     >  
  8.     <LinearLayout  
  9.         android:background=“@android:color/holo_orange_dark”  
  10.         android:layout_width=“match_parent”  
  11.         android:layout_height=“55dp”>  
  12.         <Button  
  13.             android:onClick=“cancel”  
  14.             android:text=“取消”  
  15.             android:layout_weight=“1”  
  16.             android:layout_width=“0dp”  
  17.             android:layout_height=“match_parent”/>  
  18.           <Button  
  19.               android:onClick=“confirm”  
  20.               android:text=“确认”  
  21.               android:layout_weight=“1”  
  22.               android:layout_width=“0dp”  
  23.               android:layout_height=“match_parent”/>  
  24.     </LinearLayout>  
  25.     <DatePicker  
  26.         android:id=“@+id/datepicker”  
  27.         android:layout_width=“match_parent”  
  28.         android:calendarViewShown=“false”  
  29.         android:layout_height=“wrap_content”/>  
  30.   
  31. </LinearLayout>  
<

  1. public class MainActivity extends AppCompatActivity {  
  2.     private DatePicker datePicker;  
  3.     private int        year;  
  4.     private int        month;//月份是从0开始算的.  
  5.     private int        day;  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏  
  11.         setContentView(R.layout.activity_main);  
  12.         datePicker = (DatePicker) findViewById(R.id.datepicker);  
  13. //  
  14.         initData();  
  15.     }  
  16.     public void initData(){  
  17.         Calendar calendar = Calendar.getInstance();  
  18.         year = calendar.get(Calendar.YEAR);  
  19.         month = calendar.get(Calendar.MONTH);  
  20.         day = calendar.get(Calendar.DAY_OF_MONTH);  
  21.   
  22.         datePicker.init(year, month, day, new DatePicker.OnDateChangedListener() {  
  23.             @Override  
  24.             public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {  
  25.                 Toast.makeText(MainActivity.this, year + ”年” + (monthOfYear+1) + ”月” + dayOfMonth + ”日”, Toast.LENGTH_SHORT).show();  
  26.             }  
  27.         });  
  28.   
  29.     }  
  30.     public void cancel(View v){  
  31.         Toast.makeText(this, ”取消,按照工单给的补抄日期”, Toast.LENGTH_SHORT).show();  
  32.     }  
  33.     public void confirm(View v){  
  34.         Toast.makeText(this, ”确认”, Toast.LENGTH_SHORT).show();  
  35.     }  
  36. }  

备注:

  1.这里必须继承AppCompatActivity,才会出现这个界面,否则你继承的是Activity,出现的界面很丑,黑白的,但是你有时候继承

AppCompatActivity会报错.

  
  1. 报错如下:  
  2. java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test2/com.example.test2.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.  
  3.   
  4. 解决方法:  
  5. 创建的activity是MainActivity extends ActionBarActivity这样的。把后面的ActionBarActivity改成Activity,  
报错如下:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test2/com.example.test2.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

解决方法:
创建的activity是MainActivity extends ActionBarActivity这样的。把后面的ActionBarActivity改成Activity,
  1. 然后导包,把下面报错的地方删掉运行就不报错了。。。  
然后导包,把下面报错的地方删掉运行就不报错了。。。
  1. 导入support:appcompat-v7支持包,我导入的25.1版本的.另外导入的时候也可能报错,需要修改compileSdkVersion版本.  
 导入support:appcompat-v7支持包,我导入的25.1版本的.另外导入的时候也可能报错,需要修改compileSdkVersion版本.
compile 'com.android.support:appcompat-v7:25.1.0'

Android DatePickerDialog和TimePickerDialog显示样式

 

  可以用DatePickerDialog显示选取日期的对话框。可以设置显示的样式

 

1、通过构造方法设置显示样式。

  可以通过DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)这个构造方法的第二个参数来设置显示样式。

  这个theme参数对应的值,可以使用AlertDialog中的theme值。

  AlertDialog.THEME_TRADITIONAL

    

  AlertDialog.THEME_HOLO_DARK

    

  AlertDialog.THEME_HOLO_LIGHT

    

  AlertDialog.THEME_DEVICE_DEFAULT_DARK

    

  AlertDialog.THEME_DEVICE_DEFAULT_LIGHT

    

 

2、通过DatePicker设置显示样式

  首先获取DatePicker,然后使用DatePicker.setCalendarViewShow(boolean)和DatePicker.setSpinnersShow(boolean)来设置。

  CalendarView和Spinners的值分别为true和false

    

  CalendarView和Spinners的值分别为false和true

    

  CalendarView和Spinners的值都是false

    

  CalendarView和Spinners的值都是true

    

 

 

对于TimePickerDialog而言,它的样式设置,只有构造函数一种方式,对应的theme参数和DatePickerDialog相同。它内部定义了一个TimePicker,但是没有提供获取的方式。

 

在构造TimePickerDialog和DatePickerDialog的时候最好使用DialogFragment来进行构造。

帮助文档中例子:

复制代码
public static class TimePickerFragment extends DialogFragment
                            implements TimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current time as the default values for the picker
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        // Create a new instance of TimePickerDialog and return it
        return new TimePickerDialog(getActivity(), this, hour, minute,
                DateFormat.is24HourFormat(getActivity()));
    }

    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        // Do something with the time chosen by the user
    }
}
复制代码
public void showTimePickerDialog(View v) {
    DialogFragment newFragment = new TimePickerFragment();
    newFragment.show(getSupportFragmentManager(), "timePicker");
}

 

对于DialogFragment可以参考文档: Android 官方推荐 : DialogFragment 创建对话框

DatePickerDialog的OnDateSetListener被调用两次的bug解决方案

使用DatePickerDialog.OnDateSetListener的时候发现回调了两次。原因貌似源码的问题。

解决方案:

判断下view是否显示着

final Context context = MainActivity.this;
                Calendar calendar = Calendar.getInstance();
                int y = calendar.get(Calendar.YEAR);
                int m = calendar.get(Calendar.MONTH);
                int d = calendar.get(Calendar.DAY_OF_MONTH);
                DatePickerDialog.OnDateSetListener onDateSetListener = new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        if (view.isShown()) { // 这里判断
                            Toast.makeText(context, String.format(Locale.CHINA, "(y, m, d) = (%d, %d, %d)", year, month, dayOfMonth), Toast.LENGTH_SHORT).show();
                        }
                    }
                };
                DatePickerDialog datePickerDialog = new DatePickerDialog(context, onDateSetListener, y, m, d);
                datePickerDialog.show();
          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

参考文章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值