原创 Android第十章 众多豪华控件 模拟时钟

2011-1-27 21:57 7281 6 6 分类: 智能手机

目录

4.14 数字及模拟小时钟设计

AnalogClock与DigitalClock的原理

4.15 动态输入日期与时间

DatePicker与TimePicker应用

 

4.14 数字及模拟小时钟设计

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,都可以实现动态更改日期时间的功能,读者可根据自己应用程序的需要来选择用哪种方式实现。

 

 

 

 

 

 

 

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条