当前位置:首页 > 谈天说地

Android开发实战闹钟项目

34资源网2022-09-13304

本文实例为大家分享了android实战闹钟项目的具体代码,供大家参考,具体内容如下

一、闹钟功能的介绍以及界面的展示

该闹钟是根据我们手机闹钟设计的一个简单的闹钟app,其中包含时钟、闹钟、秒表和计时器功能。用户可以对闹钟添加和删除,可以对秒表计时、暂停和重置,对计时器可以暂停、计时、继续和重置等功能。

二、介绍系统的设计界面

闹钟的布局文件代码如下
由于该闹钟系统包含时钟、闹钟、计时器、秒表四个功能,所以只要在xml文件插入tabhost控件就能实现在手机上更加简洁地展示四个功能。后面只需要在tabhost中插入四个tab用来切换展示的界面,具体的代码实现如下:

public class mainactivity extends appcompatactivity {

    private tabhost mtabhost;
    private stopwatchview mstopwatchview;

    @override
    public sharedpreferences getpreferences(int mode) {
        return super.getpreferences(mode);
    }

    @requiresapi(api = build.version_codes.p)
    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);
        mtabhost = (tabhost) findviewbyid(r.id.tabhost);
        mtabhost.setup();

        mtabhost.addtab(mtabhost.newtabspec("tabtime").setindicator("时钟").setcontent(r.id.tabtime));
        mtabhost.addtab(mtabhost.newtabspec("tabalarm").setindicator("闹钟").setcontent(r.id.tabalarm));
        mtabhost.addtab(mtabhost.newtabspec("tabtimer").setindicator("计时器").setcontent(r.id.tabtimer));
        mtabhost.addtab(mtabhost.newtabspec("tabstopwatch").setindicator("秒表").setcontent(r.id.tabstopwatch));

        mstopwatchview = (stopwatchview) findviewbyid(r.id.tabstopwatch);

    }

    @override
    protected void ondestroy() {
        super.ondestroy();
        mstopwatchview.ondestory();
    }
}

一、时钟功能

因为时钟功能中,只要显示当前的日期和时钟就可以了,所以只需要插入一个textview用来显示日期时间就可以了。

xml文件中的代码(new 一个时钟类timeview,把时钟一块的linearlayout换成com.example.tsclock.timeview)

 // 时钟
<com.example.tsclock.timeview
     android:id="@+id/tabtime"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">

<textview
       android:id="@+id/tvtime"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:textappearance="?android:attr/textappearancelarge"
       android:gravity="center"/>
</com.example.tsclock.timeview>

timeview.java
要将时间显示到tabhost中,就必须先要获取其中的id,然后通过calendar获取当前系统的时间,最后再每过1秒钟刷新一次,这样就能够再textview中出现时间在不停的变化。

public class timeview extends linearlayout {

    private textview tvtime;

    public timeview(context context) {
        super(context);
    }

    public timeview(context context, @nullable attributeset attrs) {
        super(context, attrs);
    }

    public timeview(context context, @nullable attributeset attrs, int defstyleattr) {
        super(context, attrs, defstyleattr);
    }

    // 在初始化之后进行的操作
    @override
    protected void onfinishinflate() {
        super.onfinishinflate();

        tvtime = (textview) findviewbyid(r.id.tvtime);

        // handler每秒执行一次
        timerhandler.sendemptymessage(0);

    }

    // 可见属性发生变化之后
    @override
    protected void onvisibilitychanged(@nonnull view changedview, int visibility) {
        super.onvisibilitychanged(changedview, visibility);
        if (visibility == view.visible){ // 如果可见 则发送一个消息
            timerhandler.sendemptymessage(0);
        }else{                           //  如果不可见 移除所有的消息
            timerhandler.removemessages(0);
        }
    }

    // 重新刷新时间
    private void refreshtime(){
        // 呈现一个时间对象
        calendar c = calendar.getinstance();
        // 获取时分秒
        tvtime.settext(string.format("%d:%d:%d",c.get(calendar.hour_of_day),c.get(calendar.minute),c.get(calendar.second)));

    }

    private handler timerhandler = new handler() {

        public void handlemessage(android.os.message msg){
            // 呈现出来
            refreshtime();

            // 如果可见 则刷新
            if (getvisibility() == view.visible){
                // 1000毫秒之后再制学校handlermessage()方法
                timerhandler.sendemptymessagedelayed(0,1000);
            }
        }
    };

}

二、闹钟功能

闹钟功能就相对时钟功能就复杂很多了,因为这里需要对闹钟进行增加,删除等操作,而且可能需要展示多个闹钟的时间。所以这里需要用到有一个button控件用来增加闹钟和一个listview控件用来展示闹钟的时间。

xml代码

// 闹钟
<com.example.tsclock.alarmview
        android:id="@+id/tabalarm"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

 <listview
       android:id="@+id/lvalarmlist"
       android:layout_width="match_parent"
       android:layout_weight="1"
       android:layout_height="0dp">
</listview>

<button
      android:id="@+id/btnaddalarm"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/add_alarm"
      android:textcolor="#ffffff"
      android:background="@color/colorblue" />

</com.example.tsclock.alarmview>

闹钟类,alarmview.java
需要判断时间到了需要触发事件,需要播放音乐和震动。所以播放音乐和震动放在另一个活动中(playalarmaty.java )

public class alarmview extends linearlayout {

    private button btnaddalarm;

    private listview lvalarmlist;

    private arrayadapter<alarmdata> madapter;

    private static final string key_alarm_list = "alarmlist";

    // 使用系统的闹钟服务
    private alarmmanager malarmmanager;

    public alarmview(context context) {
        super(context);
        init();
    }

    public alarmview(context context, @nullable attributeset attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        // 使用闹钟服务设定闹钟
        malarmmanager = (alarmmanager) getcontext().getsystemservice(context.alarm_service);

    }

    // 在初始化之后进行的操作
    @override
    protected void onfinishinflate() {
        super.onfinishinflate();

        btnaddalarm  = (button)findviewbyid(r.id.btnaddalarm);
        lvalarmlist = (listview) findviewbyid(r.id.lvalarmlist);
                                                                     // 系统的简单资源
        madapter = new arrayadapter<alarmview.alarmdata>(getcontext(),android.r.layout.simple_list_item_1);
        // 设置adapter
        lvalarmlist.setadapter(madapter);
        // 读取已经存储在sharedpreferences中的数据
        readsavedalarmlist();

        btnaddalarm.setonclicklistener(new view.onclicklistener() {// 添加闹钟的点击事件
            @override
            public void onclick(view v) {
                addalarm();
            }
        });

        // 删除闹钟
        lvalarmlist.setonitemlongclicklistener(new adapterview.onitemlongclicklistener() {
            @override
            public boolean onitemlongclick(adapterview<?> parent, view view,final int position, long id) {
                new alertdialog.builder(getcontext()).settitle("操作选项").setitems(new charsequence[]{"删除"}, new dialoginterface.onclicklistener() {
                    @override
                    public void onclick(dialoginterface dialog, int which) {
                        switch (which){
                            case 0:
                                deletealarm(position);
                                break;
                            default:
                                break;
                        }
                    }
                }).setnegativebutton("取消",null).show();

                return true;
            }
        });

    }

    // 删除闹钟
    private void deletealarm(int position){
        alarmdata ad = madapter.getitem(position);
        // 把闹钟从闹钟列表移除
        madapter.remove(ad);
        savealarmlist();
        // 移除闹钟
        malarmmanager.cancel(pendingintent.getbroadcast(getcontext(),ad.getid(),new intent(getcontext(),alarmreceiver.class),0));
    }

    // 添加闹钟
    private void addalarm(){
        // 获取当前时间
        calendar c = calendar.getinstance();

        // 弹出一个时间的选择框
        new timepickerdialog(getcontext(), new timepickerdialog.ontimesetlistener() {
            // 设置时间
            @override
            public void ontimeset(timepicker view, int hourofday, int minute) {
                // 获取当前时间
                calendar calendar = calendar.getinstance();
                calendar.set(calendar.hour_of_day,hourofday); // 设置时
                calendar.set(calendar.minute,minute);   // 设置分钟
                calendar.set(calendar.second,0);  // 秒清零
                calendar.set(calendar.millisecond,0); // 毫秒值清零

                // 如果设置闹钟时间小于当前时间,则往后推一天
                calendar currenttime = calendar.getinstance();
                if (calendar.gettimeinmillis() <= currenttime.gettimeinmillis()){
                    calendar.settimeinmillis(calendar.gettimeinmillis()+24*60*60*1000);
                }

                alarmdata ad = new alarmdata(calendar.gettimeinmillis());
                madapter.add(ad);

                //需要根据api版本来判断调用,从android4.4(api19)开始,为了节能省电(减少系统唤醒和电池使用)
                if (build.version.sdk_int >= build.version_codes.kitkat) {
                    malarmmanager.setwindow(alarmmanager.rtc_wakeup,
                            ad.gettime(),
                            100, // 时间误差范围 100毫秒
                            pendingintent.getbroadcast(getcontext(), ad.getid(),
                                    new intent(getcontext(), alarmreceiver.class), 0));

                } else {
                    malarmmanager.setrepeating(alarmmanager.rtc_wakeup,
                            ad.gettime(),
                            5*60*1000,
                            pendingintent.getbroadcast(getcontext(), ad.getid(),
                                    new intent(getcontext(), alarmreceiver.class), 0));
                }

                savealarmlist();
            }
        },c.get(calendar.hour_of_day),c.get(calendar.minute),true).show();
    }

    // 存储数据(存到sharedpreferences中)
    private void savealarmlist(){
        sharedpreferences.editor editor = getcontext().getsharedpreferences(alarmview.class.getname(),context.mode_private).edit();

        // 存储数据(for循环遍历adapter)
        stringbuffer sb = new stringbuffer();
        //getcount表示这个adapter里面有多少item,就是有多少闹钟
        for (int i = 0 ; i < madapter.getcount(); i++){
            sb.append(madapter.getitem(i).gettime()).append(",");
        }

        // 所有的值传进去之后 去掉最后的逗
        if (sb.length() > 1){
            string content = sb.tostring().substring(0,sb.length()-1);
            editor.putstring(key_alarm_list,content);

            system.out.println(content);// 输出存储的闹钟数据
        }else {
            editor.putstring(key_alarm_list,null);
        }

        editor.commit();
    }

    // 读取已存的数据
    private void readsavedalarmlist(){
        // 获取到sharedpreferences(数据内容)
        sharedpreferences sp = getcontext().getsharedpreferences(alarmview.class.getname(),context.mode_private);
        string content = sp.getstring(key_alarm_list,null);

        // 这里需要判断,不然没闹钟数据的时候会有空指针异常
        if (content != null){
            //这里取得每一个闹钟的time添加到数组里
            string[] timestrings = content.split(",");
            // 遍历数组,把数据添加到madapter
            for (string string : timestrings){
                madapter.add(new alarmdata(long.parselong(string)));
            }
        }
    }

    //闹钟的数据,用一个类要保存,这是常用的做法
    private static class alarmdata{

        private long time = 0;
        private string timelabel = ""; // 在外界获取时间的标签的字符串
        private calendar date;

        // 闹钟响起的时间
        public alarmdata(long time){
            this.time = time;

            date = calendar.getinstance();
            date.settimeinmillis(time);

            timelabel = string.format("%d月%d日 %d:%d",
                    date.get(calendar.month)+1,
                    date.get(calendar.day_of_month),
                    date.get(calendar.hour_of_day),
                    date.get(calendar.minute));

        }
        public alarmdata(string ad){
            this.timelabel = ad;
        }
        public void settime(long time){
            this.time = time;
        }

        public long gettime(){
            return time;
        }

        public void settimelable(string timelable){
            this.timelabel = timelable;
        }

        @override
        public string tostring() {
            return gettimelabel();
        }

        public string gettimelabel() {
            return timelabel;
        }

        //为了给每一个闹钟设定一个标识,方便取消闹钟的使用能知道是哪一个闹钟
        public int getid(){
            return (int) (gettime()/1000/60);
        }
    }
}

当触发事件发生时,我们就要播放我们之前准备的音乐了,但是怎么播放呢,这里我们就要用到mediaplayer媒体播放器这个函数了,这个函数主要就是用来播放音乐或者动画等。当开始播放时,我们也需要弹出警告框,提醒用户去关闭闹钟,所以这里我们需要另外编写一个类,用来执行这些功能。

playalarmaty类中有播放音乐,开启震动,弹出关闭闹钟的dialog。

public class playalarmaty extends activity {

    // 音乐播放器
    private mediaplayer mmediaplayer;
    private vibrator vibrator;
    private powermanager.wakelock mwakelock;

    @override
    protected void oncreate(@nullable bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        requestwindowfeature(window.feature_no_title); // hide title
        window win = getwindow();
        windowmanager.layoutparams winparams = win.getattributes();
        winparams.flags |= (windowmanager.layoutparams.flag_dismiss_keyguard
                | windowmanager.layoutparams.flag_show_when_locked
                | windowmanager.layoutparams.flag_allow_lock_while_screen_on | windowmanager.layoutparams.flag_turn_screen_on);

        // 播放闹钟铃声
        mmediaplayer = mediaplayer.create(this,r.raw.music); //使用create方式,创建mediaplayer对象
        mmediaplayer.setlooping(true); // 设置是否对播放的音乐进行循环播放
        mmediaplayer.start();

        startvibrator();
        createdialog();
    }

    @override
    protected void onpause() {
        super.onpause();
        finish();
        // 释放锁屏
        releasewakelock();
    }

    @override
    protected void onresume() {
        super.onresume();
        // 唤醒屏幕
        acquirewakelock();
    }

    @override
    protected void ondestroy() {
        super.ondestroy();
        mmediaplayer.stop();
        mmediaplayer.release(); // 释放掉
    }

    // 唤醒屏幕
    private void acquirewakelock() {

        if (mwakelock == null) {
            powermanager pm = (powermanager) getsystemservice(context.power_service);
            mwakelock = pm.newwakelock(powermanager.acquire_causes_wakeup
                    | powermanager.screen_dim_wake_lock, this.getclass()
                    .getcanonicalname());
            mwakelock.acquire();
        }
    }

    // 释放锁屏
    private void releasewakelock() {
        if (mwakelock != null && mwakelock.isheld()) {
            mwakelock.release();
            mwakelock = null;
        }
    }
    // 震动
    private void startvibrator() {
        // 想设置震动大小可以通过改变pattern来设定,如果开启时间太短,震动效果可能感觉不到
        vibrator = (vibrator) getsystemservice(context.vibrator_service);
        long[] pattern = { 500, 1000, 500, 1000 }; // 停止 开启 停止 开启
        vibrator.vibrate(pattern, 0);
    }

    private void createdialog() {
        new alertdialog.builder(this)
                .seticon(r.drawable.ic_clock)
                .settitle("闹钟")
                .setmessage("闹钟时间到了!!!")
                .setpositivebutton("推迟10分钟", new dialoginterface.onclicklistener() {
                    public void onclick(dialoginterface dialog, int whichbutton) {
                        tenmremind();
                        mmediaplayer.stop();
                        vibrator.cancel();
                        finish();
                    }
                })
                .setnegativebutton("关闭", new dialoginterface.onclicklistener() {
                    public void onclick(dialoginterface dialog, int whichbutton) {
                        mmediaplayer.stop();
                        vibrator.cancel();
                        finish();
                    }
                }).create().show();
    }

    // 推迟10分钟提醒
    private void tenmremind(){
        //设置时间
        calendar calendar_now = calendar.getinstance();

        calendar_now.settimeinmillis(system.currenttimemillis());
        calendar_now.set(calendar.hour_of_day, calendar_now.get(calendar.hour_of_day));
        calendar_now.set(calendar.minute, calendar_now.get(calendar.minute)+10);
        calendar_now.set(calendar.second, 0);
        calendar_now.set(calendar.millisecond, 0);

        //时间选择好了
        intent intent = new intent(this, alarmreceiver.class);
        //注册闹钟广播
        pendingintent sender = pendingintent.getbroadcast(
                this, 0, intent, pendingintent.flag_update_current);

        alarmmanager am;
        am = (alarmmanager) this.getsystemservice(this.alarm_service);
        am.set(alarmmanager.rtc_wakeup, calendar_now.gettimeinmillis(), sender);
    }

}

但是要当时间到了启动这个活动,就需要一个接收器,接受这个事件,所以有需要另一个类alarmreceiver。

public class alarmreceiver extends broadcastreceiver {


    @override
    public void onreceive(context context, intent intent) {
        system.out.println("闹钟执行了");

        // 闹钟执行一次就取消当前所执行的闹钟
        alarmmanager am = (alarmmanager) context.getsystemservice(context.alarm_service);
        // 取消闹钟
        am.cancel(pendingintent.getbroadcast(context,getresultcode(),new intent(context,alarmreceiver.class),0));

        intent i = new intent(context,playalarmaty.class); // 要启动的类
        i.addflags(intent.flag_activity_new_task); // 设置启动的模式
        context.startactivity(i);
    }
}

三、秒表功能

秒表功能包含四个功能键,分别为开始,暂停、继续和重置。所以需要四个button,然后需要三个edittext分别用来给用户输入时分秒。具体的xml代码如下:

// 秒表
<com.example.tsclock.stopwatchview
      android:id="@+id/tabstopwatch"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">

<linearlayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal">
<textview
       android:id="@+id/timehour"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:textappearance="?android:attr/textappearancelarge"/>
<textview
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text=":"
       android:textappearance="?android:attr/textappearancelarge"/>
<textview
       android:id="@+id/timemin"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:textappearance="?android:attr/textappearancelarge"/>
<textview
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text=":"
       android:textappearance="?android:attr/textappearancelarge"/>
<textview
       android:id="@+id/timesec"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:textappearance="?android:attr/textappearancelarge"/>
<textview
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="."
      android:textappearance="?android:attr/textappearancelarge"/>
<textview
       android:id="@+id/timemsec"
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:textappearance="?android:attr/textappearancelarge"/>
 </linearlayout>

<listview
       android:id="@+id/lvwatchtime"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1"/>

<linearlayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal">

<button
        android:id="@+id/btnswstart"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/start"
        android:textcolor="#ffffff"
        android:background="@color/colorblue"/>

<button
        android:id="@+id/btnswpause"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/pause"
        android:textcolor="#ffffff"
        android:background="@color/colorblue"/>

<button
         android:id="@+id/btnswresume"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:text="@string/resume"
         android:textcolor="#ffffff"
         android:background="@color/colorblue"/>

<button
         android:id="@+id/btnswlap"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:text="@string/lap"
        android:textcolor="#ffffff"
        android:background="@color/colorblue"/>

<button
          android:id="@+id/btnswreset"
          android:layout_width="0dp"
          android:layout_height="wrap_content"
          android:layout_weight="1"
          android:text="@string/reset"
          android:textcolor="#ffffff"
         android:background="@color/colorblue"/>
    </linearlayout>
</com.example.tsclock.stopwatchview>

在秒表功能中,含有四个button,但是有时候只要显示一个或者是两个其余的就需要隐藏,所以这里就需要用到button中的属性setvisibility(view.gone)或者是setvisibility(view.visible),这是用来隐藏和显示button。

有时候我们需要考虑系统的健壮性,比如当我们输入大于59的数或者是小于0的数,这时候我们需要系统检测出来,并进行修正。

需要注意的就是,当我们修改计时的时间的时候,当我们不小心将数目清空的时候,这时候就会将空指针上传,导致系统的崩溃,所以我们需要判断是不是空指针,防止越界报错。

该秒表功能有五个button,所以需要对每个button添加触发事件,其实starttime()函数的功能为开始计时,stoptime()函数的功能为暂停计时。所以这里需要弄清楚的就是什么时候该让那些按钮隐藏,什么时候该让那些按钮显示。

public class stopwatchview extends linearlayout {

    private textview tvhour,tvmin,tvsec,tvmsec;

    private button btnswstart,btnswresume,btnswreset,btnswlap,btnswpause;

    private listview lvtimelist;

    private arrayadapter<string> adapter;

    private timer mtimer = new timer();
    private timertask mtimertask = null;
    private int tenmsec = 0;
    private timertask showtimertask = null;

    private static final int msg_what_show_time = 1;

    public stopwatchview(context context, @nullable attributeset attrs) {
        super(context, attrs);
    }


    @override
    protected void onfinishinflate() {
        super.onfinishinflate();

        tvhour = (textview) findviewbyid(r.id.timehour);
        tvhour.settext("0");
        tvmin = (textview) findviewbyid(r.id.timemin);
        tvmin.settext("0");
        tvsec = (textview) findviewbyid(r.id.timesec);
        tvsec.settext("0");
        tvmsec = (textview) findviewbyid(r.id.timemsec);
        tvmsec.settext("0");

        // 计时
        btnswlap = (button) findviewbyid(r.id.btnswlap);
        btnswlap.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                                                                   // 时         分               秒            毫秒
                adapter.insert(string.format("%d:%d:%d.%d",tenmsec/100/60/60,tenmsec/100/60%60,tenmsec/100%60,tenmsec%100),0);

            }
        });

        // 开始
        btnswstart = (button) findviewbyid(r.id.btnswstart);
        btnswstart.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                starttimer();

                btnswstart.setvisibility(view.gone);
                btnswpause.setvisibility(view.visible);
                btnswlap.setvisibility(view.visible);
            }
        });

        // 暂停
        btnswpause = (button) findviewbyid(r.id.btnswpause);
        btnswpause.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                stoptimer();

                btnswpause.setvisibility(view.gone);
                btnswresume.setvisibility(view.visible);
                btnswlap.setvisibility(view.gone);
                btnswreset.setvisibility(view.visible);
            }
        });

        // 继续
        btnswresume = (button) findviewbyid(r.id.btnswresume);
        btnswresume.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                starttimer();
                btnswresume.setvisibility(view.gone);
                btnswpause.setvisibility(view.visible);
                btnswreset.setvisibility(view.gone);
                btnswlap.setvisibility(view.visible);
            }
        });

        // 重置
        btnswreset = (button) findviewbyid(r.id.btnswreset);
        btnswreset.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                stoptimer();
                tenmsec = 0;
                adapter.clear();// 重置需要清除列表

                btnswlap.setvisibility(view.gone);
                btnswpause.setvisibility(view.gone);
                btnswresume.setvisibility(view.gone);
                btnswreset.setvisibility(view.gone);
                btnswstart.setvisibility(view.visible);

            }
        });


        // 设置除了开始之外 其它四个按钮不可见
        btnswlap.setvisibility(view.gone);
        btnswpause.setvisibility(view.gone);
        btnswresume.setvisibility(view.gone);
        btnswreset.setvisibility(view.gone);

        lvtimelist = (listview) findviewbyid(r.id.lvwatchtime);

        // 初始化话adapter
        adapter = new arrayadapter<string>(getcontext(),android.r.layout.simple_list_item_1);
        lvtimelist.setadapter(adapter);

        // 使用showtimertask不断执行刷新的操作
        showtimertask = new timertask() {
            @override
            public void run() {
                handler.sendemptymessage(msg_what_show_time);
            }
        };
        mtimer.schedule(showtimertask,200,200); // 一秒钟刷新五次

    }

    private void starttimer(){
        if (mtimertask == null){
            mtimertask = new timertask() {// 计时的timertask
                @override
                public void run() {
                    tenmsec++;
                }
            };
            mtimer.schedule(mtimertask,10,10); // 每隔十毫秒执行一次
        }
    }

    private void stoptimer(){
        if (mtimertask != null){
            mtimertask.cancel();
            mtimertask = null;
        }
    }

    // 呈现时间的handler
    private handler handler = new handler(){
        @override
        public void handlemessage(@nonnull message msg) {
            super.handlemessage(msg);
            switch (msg.what){
                case msg_what_show_time:
                    tvhour.settext(tenmsec/100/60/60+""); // 时
                    tvmin.settext(tenmsec/100/60%60+""); // 分
                    tvsec.settext(tenmsec/100%60+""); // 秒
                    tvmsec.settext(tenmsec%100+""); // 毫秒
                    break;
                default:
                    break;
            }
        }
    };

    public void ondestory() {
        mtimer.cancel();
    }
}

四、计时器功能

这个和上面讲了秒表比较类似,不同的是多一个button按钮用来计时,还多一个editview(毫秒值),另外还需要一个listview用来显示计时的时间,详细的xml代码如下:

// 计时器
<com.example.tsclock.timerview
        android:id="@+id/tabtimer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

<linearlayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
<edittext
        android:id="@+id/ethour"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:inputtype="number"
        android:singleline="true"
        android:textappearance="?android:attr/textappearancelarge"/>
<textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=":"
        android:textappearance="?android:attr/textappearancelarge"/>
<edittext
        android:id="@+id/etmin"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:inputtype="number"
        android:singleline="true"
        android:textappearance="?android:attr/textappearancelarge"/>
<textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=":"
        android:textappearance="?android:attr/textappearancelarge"/>
<edittext
        android:id="@+id/etsec"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:inputtype="number"
        android:singleline="true"
        android:textappearance="?android:attr/textappearancelarge"/>
</linearlayout>

<linearlayout
        android:id="@+id/btngroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

<button
        android:id="@+id/btnstart"
        android:layout_width="0dp"
        android:text="@string/start"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textcolor="#ffffff"
        android:background="@color/colorblue"/>
<button
        android:id="@+id/btnpause"
        android:layout_width="0dp"
        android:text="@string/pause"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textcolor="#ffffff"
        android:background="@color/colorblue"/>
<button
         android:id="@+id/btnresume"
         android:layout_width="0dp"
         android:text="@string/resume"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:textcolor="#ffffff"
         android:background="@color/colorblue"/>
<button
         android:id="@+id/btnreset"
         android:layout_width="0dp"
         android:text="@string/reset"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:textcolor="#ffffff"
         android:background="@color/colorblue"/>
   </linearlayout>
</com.example.tsclock.timerview>

计时器功能和秒表功能差不多

public class timerview extends linearlayout {

    private button btnstart,btnpause,btnresume,btnreset;
    private edittext ethour,etmin,etsec;

    private timer mtimer = new timer(); // 计时器
    private timertask mtimertask = null;
    private int alltimercount = 0;

    private static final int msg_what_time_is_up = 1;
    private static final int msg_what_time_is_tick = 2; // 时钟一格一格的往下走

    private listview mlistview;

    public timerview(context context) {
        super(context);
    }

    public timerview(context context, @nullable attributeset attrs) {
        super(context, attrs);
    }

    @override
    protected void onfinishinflate() {
        super.onfinishinflate();

        //开始
        btnstart = (button) findviewbyid(r.id.btnstart);
        btnstart.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                starttimer();

                btnstart.setvisibility(view.gone);
                btnpause.setvisibility(view.visible);
                btnreset.setvisibility(view.visible);
                ethour.setenabled(false);
                etmin.setenabled(false);
                etsec.setenabled(false);

            }
        });

        // 暂停
        btnpause = (button) findviewbyid(r.id.btnpause);
        btnpause.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                stoptimer();

                btnpause.setvisibility(view.gone);
                btnresume.setvisibility(view.visible);
            }
        });

        // 继续
        btnresume = (button) findviewbyid(r.id.btnresume);
        btnresume.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                starttimer();

                btnresume.setvisibility(view.gone);
                btnpause.setvisibility(view.visible);
            }
        });

        // 重置
        btnreset = (button) findviewbyid(r.id.btnreset);
        btnreset.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {
                stoptimer();

                ethour.settext("00");
                etmin.settext("00");
                etsec.settext("00");
                ethour.setenabled(true);
                etmin.setenabled(true);
                etsec.setenabled(true);


                btnstart.setvisibility(view.visible);
                btnpause.setvisibility(view.gone);
                btnresume.setvisibility(view.gone);
                btnreset.setvisibility(view.gone);
            }
        });


        ethour = (edittext) findviewbyid(r.id.ethour);
        etmin = (edittext) findviewbyid(r.id.etmin);
        etsec = (edittext) findviewbyid(r.id.etsec);

        ethour.settext("00");
        // 添加事件监听器
        ethour.addtextchangedlistener(new textwatcher() {

            @override
            public void ontextchanged(charsequence s, int start, int before, int count) {
                if (!textutils.isempty(s)){
                    int value = integer.parseint(s.tostring());
                    if (value > 59){
                        ethour.settext("59");
                    }else if (value < 0){
                        ethour.settext("0");
                    }
                }
                checktoenablebtnstart();
            }
            @override
            public void beforetextchanged(charsequence s, int start, int count, int after) {

            }
            @override
            public void aftertextchanged(editable s) {

            }
        });
        etmin.settext("00");
        etmin.addtextchangedlistener(new textwatcher() {
            @override
            public void ontextchanged(charsequence s, int start, int before, int count) {
                if (!textutils.isempty(s)){
                    int value = integer.parseint(s.tostring());
                    if (value > 59){
                        etmin.settext("59");
                    }else if (value < 0){
                        etmin.settext("0");
                    }
                }
                checktoenablebtnstart();
            }
            @override
            public void beforetextchanged(charsequence s, int start, int count, int after) {

            }
            @override
            public void aftertextchanged(editable s) {

            }
        });
        etsec.settext("00");
        etsec.addtextchangedlistener(new textwatcher() {
            @override
            public void ontextchanged(charsequence s, int start, int before, int count) {
                if (!textutils.isempty(s)){ // 当文字框中不为空
                    int value = integer.parseint(s.tostring());
                    if (value > 59){
                        etsec.settext("59");
                    }else if (value < 0){
                        etsec.settext("0");
                    }
                }
                checktoenablebtnstart();
            }
            @override
            public void beforetextchanged(charsequence s, int start, int count, int after) {

            }

            @override
            public void aftertextchanged(editable s) {

            }
        });

        btnstart.setvisibility(view.visible); // 设置开始可见
        btnstart.setenabled(false); // 不可点击(开始还没有设置时间)
        btnpause.setvisibility(view.gone); // 设置暂停不可见
        btnresume.setvisibility(view.gone);
        btnreset.setvisibility(view.gone);

    }

    private void checktoenablebtnstart(){

        btnstart.setenabled((!textutils.isempty(ethour.gettext()) && integer.parseint(ethour.gettext().tostring()) > 0) ||
                (!textutils.isempty(etmin.gettext()) &&integer.parseint(etmin.gettext().tostring()) > 0) ||
                (!textutils.isempty(etsec.gettext()) &&integer.parseint(etsec.gettext().tostring()) > 0));
    }

    private void starttimer(){
        if (mtimertask == null){
            // 所使用时间的计数
            alltimercount = integer.parseint(ethour.gettext().tostring())*60*60+integer.parseint(etmin.gettext().tostring())*60+integer.parseint(etsec.gettext().tostring());
            mtimertask = new timertask() {
                @override
                public void run() { // run方法会被mtimer执行
                    // 每执行一次 计数减一
                    alltimercount--;

                    // 获取到当
                    mhandler.sendemptymessage(msg_what_time_is_tick);

                    if (alltimercount <= 0){
                        // 访问mhandler
                        mhandler.sendemptymessage(msg_what_time_is_up);
                        stoptimer();
                    }

                }
            };

            mtimer.schedule(mtimertask,1000,1000); // run方法每隔一秒执行一次

        }
    }
    private void stoptimer(){
        if (mtimertask != null){
            mtimertask.cancel();
            mtimertask = null;
        }
    }

    private handler mhandler = new handler(){
        @override
        public void handlemessage(@nonnull message msg) {
            super.handlemessage(msg);
            switch (msg.what){
                case msg_what_time_is_tick:
                    int hour = alltimercount/60/60;
                    int min = (alltimercount/60)%60;
                    int sec = alltimercount%60;

                    ethour.settext(hour+"");
                    etmin.settext(min+"");
                    etsec.settext(sec+"");

                    break;
                case msg_what_time_is_up:
                    // 执行弹出对话框操作
                    // 把时间停止(弹出一个对话框)
                    new alertdialog.builder(getcontext()).settitle("时间到了!!!").setnegativebutton("退出",null).show();

                    btnpause.setvisibility(view.gone);
                    btnresume.setvisibility(view.gone);
                    btnreset.setvisibility(view.gone);
                    btnstart.setvisibility(view.visible);
                    ethour.setenabled(true);
                    etmin.setenabled(true);
                    etsec.setenabled(true);

                    break;
                default:
                    break;
            }
        }
    };
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。

看完文章,还可以扫描下面的二维码下载快手极速版领4元红包

快手极速版二维码

快手极速版新人见面礼

除了扫码领红包之外,大家还可以在快手极速版做签到,看视频,做任务,参与抽奖,邀请好友赚钱)。

邀请两个好友奖最高196元,如下图所示:

快手极速版邀请好友奖励

扫描二维码推送至手机访问。

版权声明:本文由34楼发布,如需转载请注明出处。

本文链接:https://www.34l.com/post/22066.html

分享给朋友:

相关文章

抖音如果让我遇见你而你正当年轻是什么歌曲?

抖音如果让我遇见你而你正当年轻是什么歌曲?

《抖音》短视频平台上有不少老歌经过翻唱火了,可能刚好歌词传递的情感引起了网友们的共鸣,而最近比较火的一首歌歌词大概是如果让我遇见你而你正当年轻,好多网友不知道首是什么歌曲?小编刚开始也不知道,后来经过搜索得知这是一首老歌《怨苍天变了心》,是…

视频号加粉多少会被推荐?视频号制作方法分享

视频号加粉多少会被推荐?视频号制作方法分享

今天下午,视频号突然暂停申请,让原本打算在视频号大干一场的运营者们感到懵圈。不过据业内人士透露,此次暂停并“不会太久”,很快就会再次上线。…

小型电冰箱什么牌子好?现在口碑最好的冰箱推荐

小型电冰箱什么牌子好?现在口碑最好的冰箱推荐

海尔冰箱全球公认的质量很不错的冰箱,海尔冰箱优点是:微霜,制冷效果不错;节能省电,保湿效果不错;海尔冰箱是十大品牌之首,全球销量的第一梯队的佼佼者。海尔冰箱外观十分好看,海尔冰箱款式几乎都很新颖,质量好,制冷情况好,用了一段时间,制冷情况稳…