[android] 解決DatePickerDialog和TimePickerDialog控制項取消按鈕問題
一. 問題提出
在Android程式中,我們通常需要使用DatePicker來設定日期,TimePicker來設定時間。其基本步驟是:
1.先定義DatePicker和TimePicker布局
2.然後通過Calendar類獲得系統時間
3.接著通過init方法將日期傳遞給DatePicker初始化日期控制項
4.在響應點擊事件中可以通過DatePicker的getYear()、getDayOfMonth()、getMonth()函數擷取具體日期
同時可以在OnDateChangedListener事件中監聽日期變化,設定時間函數方法同理。但是使用DatePickerDialog或TimePickerDialog控制項時會遇到的一個問題,它就是android版本4.0後沒有取消(Cancel)按鈕,同時點擊介面任何部分都能擷取日期或時間,據說它是版本存在的BUG。對比圖如下所示:
但是我們期待的效果如所示:
我採取的解決方案是通過自訂XML布局,經過DatePicker和TimePicker控制項實現,同時在AlertDialog中設定取消按鈕和確定按鈕,通過函數setNegativeButton()和setPositiveButton()實現。
二. 簡單實現日期和時間控制項
簡單實現方法非常簡單,不需要設定日期或時間的XML布局,直接通過new DatePickerDialog或TimePickerDialog即可實現。代碼如下:
//點擊日期按鈕布局 設定日期layoutDate.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new DatePickerDialog(MainActivity.this, new DatePickerDialog.OnDateSetListener() {@Overridepublic void onDateSet(DatePicker view, int year, int month, int day) {// TODO Auto-generated method stubmYear = year;mMonth = month;mDay = day;//更新EditText控制項日期 小於10加0dateEdit.setText(new StringBuilder().append(mYear).append(-) .append((mMonth + 1) < 10 ? 0 + (mMonth + 1) : (mMonth + 1)) .append(-) .append((mDay < 10) ? 0 + mDay : mDay) ); }}, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH) ).show();}});
其中mYear、mMonth、mDay是定義變數,同時dateEdit是一個EditText控制項用於顯示具體日期,當數字小於10時前補0,如2015-01-01。下面是設定時間,顯示效果和第三部分的效果相同。
//點擊時間按鈕布局 設定時間layoutTime.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new TimePickerDialog(MainActivity.this,new TimePickerDialog.OnTimeSetListener() {@Overridepublic void onTimeSet(TimePicker view, int hour, int minute) {// TODO Auto-generated method stubmHour = hour;mMinute = minute;//更新EditText控制項時間 小於10加0timeEdit.setText(new StringBuilder().append(mHour < 10 ? 0 + mHour : mHour).append(:).append(mMinute < 10 ? 0 + mMinute : mMinute).append(:00) ); }}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true).show();}});
三. 自訂布局實現
下面是自訂布局實現,而且我自認為該介面布局非常好看,這也是我“隨手拍”項目自己最後總結出來的一個比較欣賞的介面吧!希望你也喜歡,效果如下:
,介面中日期、時間EditText不可編輯,需要通過點擊底部布局來設定。同時備忘資訊的EditText通過自訂背景實現,設定日期、時間中有取消按鈕。
原始碼:
1.項目結構如所示
2.activity_main.xml布局檔案
3.date_dialog.xml檔案:日期控制項布局
4.time_dialog.xml檔案:時間控制項布局
5.drawable-hdpi中editview_shape.xml檔案 實現自訂EditText控制項格式
6.MainActivity.java源碼
public class MainActivity extends Activity {//自訂變數private EditText titleEdit;private EditText dateEdit;private EditText timeEdit;private EditText contentEdit;//底部四個布局按鈕private LinearLayout layoutDate; private LinearLayout layoutTime; private LinearLayout layoutCancel; private LinearLayout layoutSave;//定義顯示時間控制項private Calendar calendar; //通過Calendar擷取系統時間private int mYear;private int mMonth;private int mDay;private int mHour;private int mMinute; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //鎖定螢幕 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.activity_main); //擷取對象 titleEdit = (EditText) findViewById(R.id.showtitle); dateEdit = (EditText) findViewById(R.id.showdate);timeEdit = (EditText) findViewById(R.id.showtime);contentEdit = (EditText) findViewById(R.id.editText1); layoutDate = (LinearLayout) findViewById(R.id.layout_date);layoutTime = (LinearLayout) findViewById(R.id.layout_time);layoutCancel = (LinearLayout) findViewById(R.id.layout_cancel);layoutSave = (LinearLayout) findViewById(R.id.layout_save);calendar = Calendar.getInstance(); //點擊日期按鈕布局 設定日期layoutDate.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//通過自訂控制項AlertDialog實現AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);View view = (LinearLayout) getLayoutInflater().inflate(R.layout.date_dialog, null);final DatePicker datePicker = (DatePicker) view.findViewById(R.id.date_picker);//設定日期簡略顯示 否則詳細顯示 包括:星期周datePicker.setCalendarViewShown(false);//初始化當前日期calendar.setTimeInMillis(System.currentTimeMillis());datePicker.init(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), null); //設定date布局builder.setView(view);builder.setTitle(設定日期資訊);builder.setPositiveButton(確 定, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //日期格式 StringBuffer sb = new StringBuffer(); sb.append(String.format(%d-%02d-%02d, datePicker.getYear(), datePicker.getMonth() + 1, datePicker.getDayOfMonth())); dateEdit.setText(sb); //賦值後面鬧鐘使用 mYear = datePicker.getYear();mMonth = datePicker.getMonth();mDay = datePicker.getDayOfMonth(); dialog.cancel(); } }); builder.setNegativeButton(取 消, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); }});builder.create().show();}});layoutDate.setOnTouchListener(new OnTouchListener() { //設定布局背景@Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { layoutDate.setBackgroundColor(Color.WHITE); layoutTime.setBackgroundColor(Color.TRANSPARENT); layoutCancel.setBackgroundColor(Color.TRANSPARENT); layoutSave.setBackgroundColor(Color.TRANSPARENT); } return false;}});//點擊時間按鈕布局 設定時間layoutTime.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//自訂控制項AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);View view = (LinearLayout) getLayoutInflater().inflate(R.layout.time_dialog, null);final TimePicker timePicker = (TimePicker) view.findViewById(R.id.time_picker);//初始化時間calendar.setTimeInMillis(System.currentTimeMillis());timePicker.setIs24HourView(true); timePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY)); timePicker.setCurrentMinute(Calendar.MINUTE); //設定time布局builder.setView(view);builder.setTitle(設定時間資訊);builder.setPositiveButton(確 定, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mHour = timePicker.getCurrentHour(); mMinute = timePicker.getCurrentMinute(); //時間小於10的數字 前面補0 如01:12:00 timeEdit.setText(new StringBuilder().append(mHour < 10 ? 0 + mHour : mHour).append(:).append(mMinute < 10 ? 0 + mMinute : mMinute).append(:00) ); dialog.cancel(); } }); builder.setNegativeButton(取 消, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); }});builder.create().show();}});layoutTime.setOnTouchListener(new OnTouchListener() { //設定布局背景@Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { layoutDate.setBackgroundColor(Color.TRANSPARENT); layoutTime.setBackgroundColor(Color.WHITE); layoutCancel.setBackgroundColor(Color.TRANSPARENT); layoutSave.setBackgroundColor(Color.TRANSPARENT); } return false;}});//點擊取消按鈕layoutCancel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {dateEdit.setText();dateEdit.setHint(2015-01-01);timeEdit.setText();timeEdit.setHint(00:00:00);contentEdit.setText();contentEdit.setHint(記錄旅途中的備忘資訊...);}});layoutCancel.setOnTouchListener(new OnTouchListener() { //設定布局背景@Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { layoutDate.setBackgroundColor(Color.TRANSPARENT); layoutTime.setBackgroundColor(Color.TRANSPARENT); layoutCancel.setBackgroundColor(Color.WHITE); layoutSave.setBackgroundColor(Color.TRANSPARENT); } return false;}});//點擊儲存按鈕layoutSave.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//確認儲存按鈕new AlertDialog.Builder(MainActivity.this).setTitle(確認儲存嗎?) .setIcon(android.R.drawable.ic_dialog_info) .setPositiveButton(確 定, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { /** * 資料庫插入操作 */ } }) .setNegativeButton(返 回, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).show(); }});layoutSave.setOnTouchListener(new OnTouchListener() { //設定布局背景@Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { layoutDate.setBackgroundColor(Color.TRANSPARENT); layoutTime.setBackgroundColor(Color.TRANSPARENT); layoutCancel.setBackgroundColor(Color.TRANSPARENT); layoutSave.setBackgroundColor(Color.WHITE); } return false;}});} // End onCreate }
最後希望文章對大家有所協助!如果你知道我這篇文章想要闡述的內容是什嗎?為什麼要寫這篇文章?或許它會對你有所協助,一方面是布局可能對你有啟發;另一方面就是剛好遇到那個問題的同學。
在點擊“儲存”按鈕時,也可把資料存放區至資料庫中調用MySQLiteOpenHelper,這裡就不再介紹。寫著寫著就到了淩晨5點了,程式猿生活還是要改下啊~自己保重自己的身體吧!期待改正自己的作息,難難難~