AnalogClock与DigitalClock的原理
范例说明
Android中的AnalogClock Widget是一个时钟对象,本范例将配置一个小时钟,并在其下放置一个TextView,为了做对照,上面放置的是模拟时钟,下面的TextView则模拟电子时钟,将AnalogClock的时间以数字钟形式显示。
本范例的重点,在Android.os.Handler、java.lang.Thread以及Android.os.Message三对象的整合应用。通过产生Thread对象,在进程内同步调用System.currentTimeMillis()取得系统时间,并且通过Message对象来通知Handler对象,Handler则扮演联系Activity与Thread之间的桥梁,在收到Message对象后,将时间变量的值,显示于TextView当中,产生数字时钟的外观与功能。 |
首先看看布局设计
<AnalogClock android:id="@+id/myAnalogClock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" > </AnalogClock>
//模拟时钟 <TextView android:id="@+id/myTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textSize="20sp" android:textColor="@drawable/white" android:layout_gravity="center_horizontal" > </TextView>
数字时钟
然后我们设计主程序:
主程序需要另外加载Java的Calendar与Thread对象,在onCreate()中构造Handler与Thread两对象,并实现handelMessage()与run()两个方法,如下所述:
public class ex4_14 extends Activity {
/*声明一常数作为判别信息用*/ protected static final int GUINOTIFIER = 0x1234;
/*声明两个widget对象变量*/ private TextView mTextView; public AnalogClock mAnalogClock; /*声明与时间相关的变量*/ public Calendar mCalendar; public int mMinutes; public int mHour; /*声明关键Handler与Thread变量*/ public Handler mHandler; private Thread mClockThread;
/** Called when the activity is first created. */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /*通过findViewById取得两个widget对象*/ mTextView=(TextView)findViewById(R.id.myTextView); mAnalogClock=(AnalogClock)findViewById(R.id.myAnalogClock); /*通过Handler来接收进程所传递的信息并更新TextView*/ mHandler = new Handler() { public void handleMessage(Message msg) { /*处理信息的方法*/ switch (msg.what) { case ex4_14.GUINOTIFIER: /* 在这处理要TextView对象Show时间的事件 */ mTextView.setText(mHour+" : "+mMinutes); break; } super.handleMessage(msg); } }; /*通过进程来持续取得系统时间*/
mClockThread=new LooperThread(); mClockThread.start(); } /*改写一个Thread Class用来持续取得系统时间*/ class LooperThread extends Thread { public void run() { super.run(); try { do { /*取得系统时间*/
long time = System.currentTimeMillis(); /*通过Calendar对象来取得小时与分钟*/
final Calendar mCalendar = Calendar.getInstance(); mCalendar.setTimeInMillis(time); mHour = mCalendar.get(Calendar.HOUR); mMinutes = mCalendar.get(Calendar.MINUTE); /*让进程休息一秒*/
Thread.sleep(1000); /*重要关键程序:取得时间后发出信息给Handler*/
Message m = new Message(); m.what = ex4_14.GUINOTIFIER; ex4_14.this.mHandler.sendMessage(m); }while(ex4_14.LooperThread.interrupted()==false); /*当系统发出中断信息时停止本循环*/
} catch(Exception e) { e.printStackTrace(); } } } }
扩展学习
其实要达到本范例效果的代码应该只有两行,也就是将笔者对于TextView与进程Thread的处理,改为使用widget.DigitalClock的方式,写法如下:
import android.widget.AnalogClock
mDigitalClock =(DigitalClock)findViewById(R.id.myDigitalClock);
而本程序使用TextView来模拟DigitalClock的做法,实际上,也是参考AnalogClock与DigitalClock这两个widget的代码所做的练习,对于将来实现Timer相关的小对象,会有所帮助。
Android提供了System.currentTimeMillis()、uptimeMillis()和elapsedRealtime()这三种不同特性的System Clock给开发者使用。本范例使用System.currentTimeMillis()就是标准的Clock用法,需要搭配真实的日期与时间使用,另外两者则是适用于interval与elapse time来控制程序与UI之用,读者可以自己练习。
|
| | | 4.15 动态输入日期与时间 | |
DatePicker与TimePicker应用
范例说明
许多的网络服务、网络订房、网络订旅游行程或在注册会员输入基本数据时,都会需要用户输入日期与时间格式的数据,有些网站会提供贴心的小功能:直接在万年历上来选择日期与时间,选择完毕,就会自动将日期与时间带入需要填写的字段中。
Android有没有提供类似的组件可以实现这样的功能呢?答案是肯定的!在这个范例中,将示范以Android API中提供的DatePicker与TimePicker两种对象来实现动态输入日期与时间的功能。
范例中使用了DatePicker、TimePicker与TextView三种对象,以TextView来显示日期与时间,默认带入目前系统的日期与时间,DatePicker与TimePicker可让用户动态调整日期与时间,当用户调整了DatePicker的日期或TimePicker时间时,则TextView中所显示的日期与时间也会跟着改变。
范例程序
src/irdc.ex04_15/EX04_15.java
程序中以updateDisplay()这个方法来设置TextView中所显示的日期时间,以java.util.Calendar对象来取得目前的系统时间,并预先带入TextView中。
当用户更改了DatePicker里的年、月、日时,将触发DatePicker的onDateChange()事件,运行updateDisplay()来重新设置TextView中显示的日期;同样的原理,当用户更改了TimePicker里的时间,会触发TimePicker的onTimeChange()事件,运行updateDisplay()来重新设置TextView中显示的时间。
首先设计界面
<?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout android:id="@+id/layout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/white" xmlns:android="http://schemas.android.com/apk/res/android" > <DatePicker android:id="@+id/dPicker" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="20px" android:layout_y="20px" > </DatePicker> <TimePicker android:id="@+id/tPicker" android:layout_width="220px" android:layout_height="wrap_content" android:layout_x="20px" android:layout_y="180px" > </TimePicker> <TextView android:id="@+id/showTime" android:layout_width="wrap_content" android:layout_height="34px" android:textSize="24sp" android:layout_x="30px" android:layout_y="330px" android:textColor="@drawable/black" > </TextView> </AbsoluteLayout>
/* import程序略 */
import android.widget.DatePicker;
import android.widget.TimePicker;
public class EX04_15 extends Activity
{
/*声明日期及时间变量*/
private int mYear;
private int mMonth;
private int mDay;
private int mHour;
private int mMinute;
/*声明对象变量*/
TextView tv;
TimePicker tp;
DatePicker dp;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
/*取得目前日期与时间*/
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);
super.onCreate(savedInstanceState);
/*加载main.xml Layout */
setContentView(R.layout.main);
/*取得TextView对象,并调用updateDisplay()
来设置显示的初始日期时间*/
tv= (TextView) findViewById(R.id.showTime);
updateDisplay();
/*取得DatePicker对象,以init()
设置初始值与onDateChangeListener() */
dp=(DatePicker)findViewById(R.id.dPicker);
dp.init(mYear,mMonth,mDay,new DatePicker.OnDateChangedListener()
{
@Override
public void onDateChanged(DatePicker view,int year,
int monthOfYear,int dayOfMonth)
{
mYear=year;
mMonth= monthOfYear;
mDay=dayOfMonth;
/*调用updateDisplay()来改变显示日期*/
updateDisplay();
}
});
/*取得TimePicker对象,并设置为24小时制显示*/
tp=(TimePicker)findViewById(R.id.tPicker);
tp.setIs24HourView(true);
/*setOnTimeChangedListener,并重写onTimeChanged event*/
tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener()
{
@Override
public void onTimeChanged(TimePicker view,
int hourOfDay,
int minute)
{
mHour=hourOfDay;
mMinute=minute;
/*调用updateDisplay()来改变显示时间*/
updateDisplay();
}
});
}
/*设置显示日期时间的方法*/
private void updateDisplay()
{
tv.setText(
new StringBuilder().append(mYear).append("/")
.append(format(mMonth + 1)).append("/")
.append(format(mDay)).append(" ")
.append(format(mHour)).append(":")
.append(format(mMinute))
);
}
/*日期时间显示两位数的方法*/
private String format(int x)
{
String s=""+x;
if(s.length()==1) s="0"+s;
return s;
}
}
|
|
|
扩展学习
本范例的重点在于学习如何使用DatePicker与TimePicker对象来达成动态调整日期与时间的功能,读者应该可以发现,在范例中,DatePicker实现OnDateChangedListener()的方法与TimePicker实现OnTimeChangedListener()的方法是不太相同的。DatePicker对象以init()这个方法来指定DatePicker初始的年、月、日及OnDateChangedListener()的事件;而TimePicker对象则是直接以setOnTimeChangedListener()事件来处理时间改变时程序要做的操作。
在旧版的Android SDK(1.0r2版以前的SDK版本)中,DatePicker对象有提供setOnDate ChangedListener()这个方法,但是在新版的SDK(1.0r2),这个方法被删除了,所以要实现OnDate ChangedListener()时,必须以init()方式来重写OnDateChangedListener();而TimePicker则直接以 setOnTimeChangedListener()来实现即可。
Android API另外提供了其他的对象来实现动态修改日期时间的功能:DatePickerDialog与TimePickerDialog。这两种类型的对象最大的差别在于DatePicker与TimePicker是直接显示在屏幕画面上,而DatePickerDialog与TimePickerDialog对象则是以弹出Dialog的方式来显示,如图4-16所示。
而DatePickerDialog与TimePickerDialog的实现方式又如何呢?以下提供简单的范例供各位参考:
/* 取得更改日期的Button,添加onClickListener */
Button dButton=(Button)findViewById(R.id.dPicker);
dButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
/* onClick时跳出DatePickerDialog */
new DatePickerDialog(EX04_15_1.this,
new DatePickerDialog.OnDateSetListener()
{
public void onDateSet(DatePicker view,int year,
int monthOfYear,int dayOfMonth)
{
/* 这里放更新日期的方法 */
}
},mYear,mMonth,mDay).show();
}
});
/* 取得更改时间的Button,添加onClickListener */
Button tButton=(Button)findViewById(R.id.tPicker);
tButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
/* onClick时跳出TimePickerDialog */
new TimePickerDialog(EX04_15_1.this,
new TimePickerDialog.OnTimeSetListener()
{
public void onTimeSet(TimePicker view,int hourOfDay,
int minute)
{
/* 这里放更新时间的方法 */
}
},mHour,mMinute,true).show();
}
});
<!--[if !vml]-->
DatePicker、TimePicker或DatePickerDialog、TimePickerDialog,都可以实现动态更改日期时间的功能,读者可根据自己应用程序的需要来选择用哪种方式实现。
|
文章评论(0条评论)
登录后参与讨论