您当前的位置:首页 > 互联网教程

一个简单的Android开源生产力计时器应用程序

发布时间:2025-05-13 21:56:04    发布人:远客网络

一个简单的Android开源生产力计时器应用程序

一、一个简单的Android开源生产力计时器应用程序

保持注意力集中,摆脱分心,安排好工作时间。好的工具可以帮助我们提高生产力。Goodtime(美好时光)是一款面向Android用户,极简主义的pomodoro计时器应用程序。它是免费开源的,具有简单有效的计时技术,帮助用户查看进度,保持专注。用户界面简洁,仅需几个手势即可操作。例如,轻触计时器启动,从通知区域停止。您可调整计时器持续时间,设置理想的工作和休息时间。当计时器结束时,会发出警报通知您休息,可自动重新启动(若已启用)。应用程序会跟踪进度,评估时间管理情况,促进自律。专业订阅解锁额外功能,如首次启动应用的手势教程。下载并安装Goodtime,可在Google Play商店、F-Driod和Github上获取。这款应用程序是否满足了您的需求?或者,您会推荐一个更好的实用程序来提高Android的生产力吗?欢迎在评论中分享您的见解!

二、android 实现同时多个倒计时效果怎么做

1、安卓实现同时多个倒计时效果的步骤:

2、我们首先需要在输入框中输入一个秒数,比如:12,然后获取输入框中的值,显示在一个TextView中;

3、点击“开始倒计时”按钮,每隔一秒钟,秒数减1,然后显示在TextView中;

4、点击“停止倒计时”按钮,计时器停止运行,当再次点击“开始倒计时”按钮,计时器继续运行。

5、平时用的每个商品都应该有两个属性值,这里叫它deadLine和isOverdue吧,表示商品的到期时间和是否到期,那么倒计时可以考虑这么实现:设置一个主计时器,每隔1秒发出消息告诉GridView现在的时间,GridView的Item获得这个时间之后就和deadLine比较,如果已经到deadline了,就把数据源中的这项标记成已到期(修改isOverdue的值为true);没到deadline,就计算还差多少时间,显示到GridView的Item里。

三、Android编程中chronometer在后台怎么才能定时暂停

我看了下Chronometer这个类的源码,他内部就是用一个handler延迟一秒给自己发送一次消息,然后修改时间。按Home键,会触发Chronometer的onWindowVisibilityChanged()方法

上面方法是启动计时器,将mStarted变量设置为true,并执行一次updateRunning()方法,updateRunning()会在下面讲到

stop()方法是停止计时,将mStarted变量设置为false,并执行一次updateRunning()方法

protectedvoidonWindowVisibilityChanged(intvisibility){

super.onWindowVisibilityChanged(visibility);

上面的onWindowVisibilityChanged方法,是View里面的方法,只要View的可见状态发生改变了都会触发这个方法,很显然你说按Home键时间没停止,就是因为这个方法里面的代码,实际上是因为按Home键触发这个方法以后,就不再回调你设置的监听器的回调方法。按Home键后,View变为不可见状态,变量mVisible变成了false

booleanrunning=mVisible&&mStarted;

updateText(SystemClock.elapsedRealtime());

mHandler.sendMessageDelayed(Message.obtain(mHandler,TICK_WHAT),1000);

mHandler.removeMessages(TICK_WHAT);

上面的updateRunning()方法主要是工具mVisible和mStarted这2个boolean变量来控制是否向handler发送消息。

privateHandlermHandler=newHandler(){

publicvoidhandleMessage(Messagem){

updateText(SystemClock.elapsedRealtime());

sendMessageDelayed(Message.obtain(this,TICK_WHAT),1000);

这个Handler主要是执行dispatchChronometerTick()方法再向它自己发送一条延时消息

voiddispatchChronometerTick(){

if(mOnChronometerTickListener!=null){

mOnChronometerTickListener.onChronometerTick(this);

dispatchChronometerTick()方法就是回调你设置的监听器的onChronometerTick方法

根据以上分析,按Home键之后,Chronometer就不会回调你的监听器方法,这个是受Chronometer的onWindowVisibilityChanged()方法控制的,所以你的问题不好解决!!

我能想到的解决方式就是把Chronometer的代码拿过来,自己写一个类,粘贴上Chronometer里面的代码,然后再修改它的onWindowVisibilityChanged()方法,然后就可以用自己的这个计时器了。我测试过了,实现了

最后附上我自己的MyChronometer类代码,你可以复制一下。。在布局文件里直接用这个控件

packagecom.lily.demo_listview;

*Copyright(C)2008TheAndroidOpenSourceProject

*LicensedundertheApacheLicense,Version2.0(the"License");

*youmaynotusethisfileexceptincompliancewiththeLicense.

*YoumayobtainacopyoftheLicenseat

*

*Unlessrequiredbyapplicablelaworagreedtoinwriting,software

*distributedundertheLicenseisdistributedonan"ASIS"BASIS,

*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.

*SeetheLicenseforthespecificlanguagegoverningpermissionsand

importjava.util.IllegalFormatException;

importandroid.annotation.SuppressLint;

importandroid.content.Context;

importandroid.text.format.DateUtils;

importandroid.util.AttributeSet;

importandroid.view.accessibility.AccessibilityEvent;

importandroid.view.accessibility.AccessibilityNodeInfo;

importandroid.widget.RemoteViews.RemoteView;

importandroid.widget.TextView;

*Classthatimplementsasimpletimer.

*Youcangiveitastarttimeinthe{@linkSystemClock#elapsedRealtime}timebase,

*anditcountsupfromthat,orifyoudon'tgiveitabasetime,itwillusethe

*timeatwhichyoucall{@link#start}.Bydefaultitwilldisplaythecurrent

*timervalueintheform"MM:SS"or"H:MM:SS",oryoucanuse{@link#setFormat}

*toformatthetimervalueintoanarbitrarystring.

*@attrrefandroid.R.styleable#Chronometer_format

publicclassMyChronometerextendsTextView{

privatestaticfinalStringTAG="Chronometer";

*Acallbackthatnotifieswhenthechronometerhasincrementedonitsown.

publicinterfaceOnChronometerTickListener{

*Notificationthatthechronometerhaschanged.

voidonChronometerTick(MyChronometerchronometer);

privateLocalemFormatterLocale;

privateObject[]mFormatterArgs=newObject[1];

privateStringBuildermFormatBuilder;

privateOnChronometerTickListenermOnChronometerTickListener;

privateStringBuildermRecycle=newStringBuilder(8);

privatestaticfinalintTICK_WHAT=2;

*InitializethisChronometerobject.

publicMyChronometer(Contextcontext){

*Initializewithstandardviewlayoutinformation.

publicMyChronometer(Contextcontext,AttributeSetattrs){

*Initializewithstandardviewlayoutinformationandstyle.

publicMyChronometer(Contextcontext,AttributeSetattrs,intdefStyle){

super(context,attrs,defStyle);

//TypedArraya=context.obtainStyledAttributes(

//com.android.internal.R.styleable.Chronometer,defStyle,0);

//setFormat(a.getString(com.android.internal.R.styleable.Chronometer_format));

mBase=SystemClock.elapsedRealtime();

*Setthetimethatthecount-uptimerisinreferenceto.

*@parambaseUsethe{@linkSystemClock#elapsedRealtime}timebase.

Log.d("MyChronometer","dispatchChronometerTick333");

updateText(SystemClock.elapsedRealtime());

*Returnthebasetimeassetthrough{@link#setBase}.

*Setstheformatstringusedfordisplay.TheChronometerwilldisplay

*thisstring,withthefirst"%s"replacedbythecurrenttimervaluein

*Iftheformatstringisnull,orifyounevercallsetFormat(),the

*Chronometerwillsimplydisplaythetimervaluein"MM:SS"or"H:MM:SS"

publicvoidsetFormat(Stringformat){

if(format!=null&&mFormatBuilder==null){

mFormatBuilder=newStringBuilder(format.length()*2);

*Returnsthecurrentformatstringassetthrough{@link#setFormat}.

*Setsthelistenertobecalledwhenthechronometerchanges.

publicvoidsetOnChronometerTickListener(OnChronometerTickListenerlistener){

mOnChronometerTickListener=listener;

*@returnThelistener(maybenull)thatislisteningforchronometerchange

publicOnChronometerTickListenergetOnChronometerTickListener(){

returnmOnChronometerTickListener;

*Startcountingup.Thisdoesnotaffectthebaseassetfrom{@link#setBase},just

*Chronometerworksbyregularlyschedulingmessagestothehandler,evenwhenthe

*Widgetisnotvisible.Tomakesureresourceleaksdonotoccur,theusershould

*makesurethateachstart()callhasareciprocalcallto{@link#stop}.

*Stopcountingup.Thisdoesnotaffectthebaseassetfrom{@link#setBase},just

*Thisstopsthemessagestothehandler,effectivelyreleasingresourcesthatwould

*beheldasthechronometerisrunning,via{@link#start}.

*Thesameascalling{@link#start}or{@link#stop}.

*@hidependingAPIcouncilapproval

publicvoidsetStarted(booleanstarted){

protectedvoidonDetachedFromWindow(){

super.onDetachedFromWindow();

Log.d("MyChronmeter","onDetachedFromWindow()"+mVisible);

protectedvoidonWindowVisibilityChanged(intvisibility){

super.onWindowVisibilityChanged(visibility);

privatesynchronizedvoidupdateText(longnow){

Stringtext=DateUtils.formatElapsedTime(mRecycle,seconds);

Localeloc=Locale.getDefault();

if(mFormatter==null||!loc.equals(mFormatterLocale)){

mFormatter=newFormatter(mFormatBuilder,loc);

mFormatter.format(mFormat,mFormatterArgs);

text=mFormatBuilder.toString();

}catch(IllegalFormatExceptionex){

Log.w(TAG,"Illegalformatstring:"+mFormat);

updateText(SystemClock.elapsedRealtime());

Log.d("MyChronometer","dispatchChronometerTick222");

mHandler.sendMessageDelayed(Message.obtain(mHandler,TICK_WHAT),1000);

mHandler.removeMessages(TICK_WHAT);

privateHandlermHandler=newHandler(){

publicvoidhandleMessage(Messagem){

updateText(SystemClock.elapsedRealtime());

Log.d("MyChronometer","dispatchChronometerTick111");

sendMessageDelayed(Message.obtain(this,TICK_WHAT),1000);

voiddispatchChronometerTick(){

if(mOnChronometerTickListener!=null){

mOnChronometerTickListener.onChronometerTick(this);

//Log.d("MyChronometer","回调方法");

@SuppressLint("NewApi")@Override

publicvoidonInitializeAccessibilityEvent(AccessibilityEventevent){

super.onInitializeAccessibilityEvent(event);

event.setClassName(MyChronometer.class.getName());

@SuppressLint("NewApi")@Override

publicvoidonInitializeAccessibilityNodeInfo(AccessibilityNodeInfoinfo){

super.onInitializeAccessibilityNodeInfo(info);

info.setClassName(MyChronometer.class.getName());