Android UI组件之DatePicker,TimePicker

  一直都是在博客园和csdn上看各种大牛的技术博客,终于忍不住要开始自己写博客,希望一起成长,我会把自己的学习的过程放到博客里,但同时我更愿意贴出的是我碰到的错误。也欢迎网友来指导与纠正,大家一起进步,更希望的是自己能够坚持写博客。

  废话不多说,直接进入正题,最近在学习android开发,对于这些界面的开发,最重要的就是一堆控件的使用了。今天登场的就是DatePicker和TimePicker。既然要学习,那就需要有学习的资料。碰到一个新的东西最自然的想法就是去搜一下。网上相关的文章也是一大堆。再有了资料之后就可以入手设计了,对于日期和时间选择控件,最常用的大概就是获得选择结果。所以一个demo的功能就出来了:

  1.程序启动进入主界面,看到一个最简单的布局,提示用户选择开始时间和结束时间。

  2.用户触摸EditText时,触发onTouch事件。弹出datepicker dialog。

  3.用户选择日期和时间并确定。

  4.结果返回到EditText。

  有了程序的流程,接下来就来设计界面。首先是主界面activity_main.xml的布局文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

 2     xmlns:tools="http://schemas.android.com/tools"

 3     android:layout_width="fill_parent"

 4     android:layout_height="fill_parent"

 5     android:orientation="vertical"

 6     android:padding="10dip"

 7     tools:context=".MainActivity" >

 8     <RelativeLayout 

 9         android:layout_width="fill_parent"

10         android:layout_height="wrap_content">

11         <TextView

12           android:id="@+id/startTextView"

13             android:layout_width="wrap_content"

14             android:layout_height="wrap_content"

15             android:gravity="center_vertical"

16             android:text="@string/start" />

17         <EditText

18               android:id="@+id/startEditText"  

19             android:layout_width="fill_parent"

20             android:layout_height="wrap_content"

21             android:singleLine="true"

22             android:layout_toRightOf="@id/startTextView"/>

23     </RelativeLayout>

24     <RelativeLayout 

25         android:layout_width="fill_parent"

26         android:layout_height="wrap_content">

27         <TextView

28           android:id="@+id/endTextView"

29             android:layout_width="wrap_content"

30             android:layout_height="wrap_content"

31             android:gravity="center_vertical"

32             android:text="@string/end" />

33         <EditText

34               android:id="@+id/endEditText"  

35             android:layout_width="fill_parent"

36             android:layout_height="wrap_content"

37             android:singleLine="true"

38             android:layout_toRightOf="@id/endTextView"/>

39     </RelativeLayout>

40 </LinearLayout>

   界面效果如下:

 

Android UI组件之DatePicker,TimePicker

  接下来是datepicker dialog的view布局datepicker.xml:

 1 <?xml version="1.0" encoding="utf-8"?>

 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

 3     android:layout_width="fill_parent"

 4     android:layout_height="fill_parent"

 5     android:orientation="vertical" 

 6     android:scrollbars="vertical">

 7     <TextView 

 8         android:layout_width="wrap_content"

 9         android:layout_height="wrap_content"

10         android:textSize="16sp"

11         android:text="@string/datepicker"/>

12     <DatePicker 

13         android:id="@+id/myDatePicker"

14         android:layout_width="fill_parent"

15         android:layout_height="wrap_content"

16         android:layout_marginTop="5dip"/>

17      <TextView 

18         android:layout_width="wrap_content"

19         android:layout_height="wrap_content"

20         android:textSize="16sp"

21         android:text="@string/timepicker"/>

22      <TimePicker 

23         android:id="@+id/myTimePicker" 

24         android:layout_width="fill_parent" 

25         android:layout_height="wrap_content" 

26         android:layout_marginTop="5dip" /> 

27 

28 </LinearLayout>

  界面效果如下:

Android UI组件之DatePicker,TimePicker

  这效果,吓我一跳。怎么这样子。算了先不管了。等运行再看看。现在布局文件都有了那么就要开始程序的功能部分了。

  1 package com.example.datepickertest;

  2 

  3 import java.util.Calendar;

  4 

  5 import android.app.Activity;

  6 import android.app.AlertDialog;

  7 import android.content.DialogInterface;

  8 import android.os.Bundle;

  9 import android.text.InputType;

 10 import android.view.Menu;

 11 import android.view.MotionEvent;

 12 import android.view.View;

 13 import android.widget.DatePicker;

 14 import android.widget.EditText;

 15 import android.widget.TimePicker;

 16 

 17 public class MainActivity extends Activity {

 18     //定义控件变量

 19     private EditText startEdit,endEdit;

 20     @Override

 21     protected void onCreate(Bundle savedInstanceState) {

 22         super.onCreate(savedInstanceState);

 23         setContentView(R.layout.activity_main);

 24         startEdit = (EditText) findViewById(R.id.startEditText);

 25         endEdit = (EditText) findViewById(R.id.endEditText);

 26         startEdit.setOnTouchListener(new MyTouchListener());

 27         endEdit.setOnTouchListener(new MyTouchListener());

 28     }

 29     class MyTouchListener implements View.OnTouchListener{

 30         @Override

 31         public boolean onTouch(View v, MotionEvent event) {

 32             // TODO Auto-generated method stub

 33             if(event.getAction() == MotionEvent.ACTION_DOWN){

 34                 AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

 35                 View view = View.inflate(MainActivity.this,R.layout.datepicker,null);

 36                 //获取datepicker和timepicker,在这里要注意.

 37                 //如果是直接通过datepicker = (DatePicker) findViewById(R.id.myDatePicker);或者

 38                 //datepicker = (DatePicker) this.findViewById(R.id.myDatePicker);来获取控件

 39                 //会出现空指针异常,因为当前的this指的是MyTouchListener的实例。所以在这里通过view来取得控件

 40                 final DatePicker datepicker = (DatePicker) view.findViewById(R.id.myDatePicker);

 41                 final TimePicker timepicker = (TimePicker) view.findViewById(R.id.myTimePicker);

 42                 //设置对话框的布局文件

 43                 builder.setView(view);

 44                 //获取Calendar实例来初始化datepicker和设置timepicker的初始值

 45                 Calendar cal = Calendar.getInstance();

 46                 cal.setTimeInMillis(System.currentTimeMillis());

 47                 datepicker.init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),

 48                         cal.get(Calendar.DAY_OF_MONTH), null);

 49                 timepicker.setIs24HourView(true);

 50                 timepicker.setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));

 51                 timepicker.setCurrentMinute(cal.get(Calendar.MINUTE));

 52                 //判断事件的对象

 53                 if(v.getId() == R.id.startEditText){

 54                     final int inType = startEdit.getInputType(); 

 55                     startEdit.setInputType(InputType.TYPE_NULL); 

 56                     startEdit.onTouchEvent(event); 

 57                     startEdit.setInputType(inType);

 58                     //设置对话框属性

 59                     builder.setTitle(R.string.starttitle);

 60                     builder.setPositiveButton("确 定", new DialogInterface.OnClickListener() 

 61                     {

 62                         

 63                         @Override

 64                         public void onClick(DialogInterface dialog, int which) {

 65                             // TODO Auto-generated method stub

 66                             StringBuffer sb = new StringBuffer();

 67                             sb.append(String.format("%d-%02d-%02d",

 68                                     datepicker.getYear(),

 69                                     datepicker.getMonth()+1,

 70                                     datepicker.getDayOfMonth()));

 71                             sb.append("  ");

 72                             sb.append(timepicker.getCurrentHour())

 73                             .append(":")

 74                             .append(timepicker.getCurrentMinute());

 75                             startEdit.setText(sb);

 76                             dialog.cancel();

 77                         }

 78                     }

 79                     );

 80                 }

 81                 if(v.getId() == R.id.endEditText){

 82                     final int inType = endEdit.getInputType(); 

 83                     endEdit.setInputType(InputType.TYPE_NULL); 

 84                     endEdit.onTouchEvent(event); 

 85                     endEdit.setInputType(inType);

 86                     //设置对话框属性

 87                     builder.setTitle(R.string.endtitle);

 88                     builder.setPositiveButton("确 定", new DialogInterface.OnClickListener() 

 89                     {

 90                         

 91                         @Override

 92                         public void onClick(DialogInterface dialog, int which) {

 93                             // TODO Auto-generated method stub

 94                             StringBuffer sb = new StringBuffer(); 

 95                             sb.append(String.format("%d-%02d-%02d",  

 96                                     datepicker.getYear(),  

 97                                     datepicker.getMonth() + 1,  

 98                                     datepicker.getDayOfMonth())); 

 99                             sb.append("  "); 

100                             sb.append(timepicker.getCurrentHour()) 

101                             .append(":").append(timepicker.getCurrentMinute()); 

102                             endEdit.setText(sb); 

103                             dialog.cancel(); 

104                         }

105                     }

106                     );

107                 }

108                 //创建对话框,并显示

109                 AlertDialog dialog = builder.create();

110                 dialog.show();

111             }

112             return true;

113         }

114         

115     }

116     @Override

117     public boolean onCreateOptionsMenu(Menu menu) {

118         // Inflate the menu; this adds items to the action bar if it is present.

119         getMenuInflater().inflate(R.menu.main, menu);

120         return true;

121     }

122 

123 }

接下来运行程序:发现界面丑的简直不能忍啊。

Android UI组件之DatePicker,TimePicker

  连时间都看不到,让我怎么选。上面那个日历也是大的可以。既然涉及到外观那么说不定在XML文件里能找到些许的影子。抱着试一试的想法去XML文件中找,但是看了那茫茫多的属性就在想这么找何时才能找到。想到android通常在XML中出现的属性,就会有相似的set和get方法。于是乎,直接看SDK文档,找到set开头的那些函数。果然很快就定位在setCalendarViewShown上。看了一下的介绍感觉八九不离十,实验才是检验真理的标准。于是乎在程序中添加一行代码

1 //获取Calendar实例来初始化datepicker和设置timepicker的初始值

2                 Calendar cal = Calendar.getInstance();

3                 cal.setTimeInMillis(System.currentTimeMillis());

4                 datepicker.setCalendarViewShown(false);

5                 datepicker.init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),

6                         cal.get(Calendar.DAY_OF_MONTH), null);

  运行一下程序,果然。界面瞬间不一样。

Android UI组件之DatePicker,TimePicker

  然后试验一下发现程序和我们想的一样正常工作。但是到这里就完了吗?反过来想想既然有set方法去设置,那么会不会有这个属性呢,我们再一次来到XML文件,这一次有了目标。属性可能是带CalendarViewShown这类字样的,很快我们发现确实有这个属性。立马尝试了一下,将它设为false,并删掉之前的那一句代码。程序依然正常运行。所以这个属性是正确的。好像到这里就该去睡觉了,但是细心的人已经发现在上面的代码中有一个地方有点怪,我们看到这个getMonth()在返回后还加了1,那么我们把这个加1去掉呢,再次运行程序发现,显示的月份总比选择的月份小1,天天和程序打交道的话就会立即反应一下:"难道月份也是从0计数的?",还是老套路,碰到怪问题就去问SDK,但是发现getmonth这个函数的解释只有一句话,返回选择的月,于是我们望上看,突然发现了Calendar的常量字段。发现果然是从0开始:

public static final int JANUARY

Added in API level 1
Value of the MONTH field indicating the first month of the year.

Constant Value: 0 (0x00000000)。那么既然是这样,反过来我们去设置月份的时候也一样,当我们通过函数这是对应参数为8的时候其实是9.所以要注意程序在参数的处理。今天就写到这儿吧,该睡觉了。

  

1 sb.append(String.format("%d-%02d-%02d",

2                                     datepicker.getYear(),

3                                     datepicker.getMonth()+1,

4                                     datepicker.getDayOfMonth()));

 

你可能感兴趣的:(android ui)