前言
开发的本意是想看到可视化的时间,让我们心存敬畏,珍惜时间,毕竟时间一去不复返!
最近灵感突突然袭来,想着做一个时间精度条:今天度过了多少,这周度过了多少,这个月度过了多少,今年度过了多少(以及这一辈子度过了多少),刚开始真的只是自己想做,不知道小爱同学有了【对小爱同学说人生进度条你就看到了】,后来有使用者提醒到了小爱,自己发现小爱同学的界面做的还行,于是就仿照着界面做了这个app,目前来说还没有什么重大的bug(毕竟作为一个极小的应用再有bug的话简直没谁了。。)先看一下界面吧(目前是第四个版本,支持两个桌面插件)
下载地址:时间进度:/apk/com.imfondof.progress
(如果对源码感兴趣,可加入星球,查看源码地址)
## 自定义进度条 先来说一下自定义进度条的事 刚开始看到小爱同学的人生进度条,感觉很好看,比我第一个版本的好看多了(这里就不贴了,太丑了,但是如果你想看的话可以在应用市场里在其他用户的评论里看到),于是想着这个是怎么实现的呢?难道是某个大神在github里造的轮子?于是寻寻觅觅,最后也没有发现这种效果,网上却通过多个博客帮助实现了这种效果,在这里谢过! > 过程是这样的,使用系统提供的进度条,设置为水平,然后再给他来个drawable特效:progress_month就好了 > drawable特效里设置默认的背景颜色,以及进度条的属性,还是使用drawable特效:round_month > 在round_month,咱们给他设置圆角,设置进度条的颜色,(你还可以设置渐变色哦,代码里注释掉了)
<!-- 在activity_main.xml里--><ProgressBarandroid:id="@+id/progress_month"style="@style/Widget.AppCompat.ProgressBar.Horizontal"android:layout_width="0dp"android:layout_height="20dp"android:layout_weight="9"android:max="100"android:progress="80"android:progressDrawable="@drawable/progress_month" />
<!-- 在drawable里新建progress_month--><?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="/apk/res/android"><item android:id="@android:id/background"><shape><corners android:radius="50dp" /><solid android:color="#12222222" /></shape></item><item android:id="@android:id/progress"><scaleandroid:drawable="@drawable/round_month"android:scaleWidth="100%" /></item></layer-list>
<!-- 在drawable里新建round_month--><?xml version="1.0" encoding="utf-8"?><shape xmlns:android="/apk/res/android"android:width="2dp"android:color="#dcdcdc"android:shape="rectangle"><corners android:radius="50dp" /><!--<solid android:color="#ff9d77" /> <!– 渐变 –>--><!--<gradient--><!--android:angle="270"--><!--android:endColor="#FFFFFF"--><!--android:startColor="#ff8c00" />--><gradientandroid:angle="0"android:endColor="@color/colorMonth"android:startColor="@color/colorMonth"android:type="linear" /></shape>
好了,经过这三步,那个今天的蓝色进度条就弄好啦
小数点后一位
接下来就是百分比的问题了,系统提供的是int类型,可是我想给他来个小数点,这可怎么搞呢?于是相处了这个办法(使用这种办法,无论想要显示小数点后几位都可以哦 )
思路:百分比是这样计算的:progress*100/max,比方说:8/100,进度是8%,是让8乘以100在除以100最后加上百分号就行了
然后咱么这样计算:8乘以1000除以100,结果是80,这样咱们就保留了精度,让80除以10是我们想要的小数点之前的数字,让80mod10,就是小数点之后的数字,拼接好就是我们想要的效果了
//为进度条设置进度private void set(ProgressBar progressBar, int max, int process, TextView textView) {progressBar.setMax(max);progressBar.setProgress(process);int percent = process * 1000 / max;textView.setText(percent / 10 + "." + percent % 10 + "%");}
计算日期
接下来就用到了一系列的日期计算函数,网上一大堆,这里不多说了
桌面插件
这个是新接触的,从网上摘来学的,可能会有不足之处,但至少效果是实现了
在AndroidStudio里新建Widget:
他就自动为我们继承了AppWidgetProvider,
并在AndroidManifest里为我们添加了配置信息。
并新建了布局文件
但是咱们这个小插件是要实时更新的呀,接下来介绍两种办法
在Widget使用Timer
我们需要在update里通过Timer来写ui就可了,设置每一秒更新一次
public class DayWidget extends AppWidgetProvider {//这里直接在这里进行刷新了,,allwidget使用了serviceprivate Timer timer;static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);//系统生成的appWidgetManager.updateAppWidget(appWidgetId, views);}@Overridepublic void onUpdate(final Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) {// There may be multiple widgets active, so update all of themfor (int appWidgetId : appWidgetIds) {updateAppWidget(context, appWidgetManager, appWidgetId);}timer = new Timer();//参数:1.事件2.延时事件3.执行间隔事件timer.schedule(new TimerTask() {public void run() {ComponentName provider = new ComponentName(context.getApplicationContext(), DayWidget.class);RemoteViews rViews = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);写自己的ui事件// 刷新appWidgetManager.updateAppWidget(provider, rViews);}}, 0, 1000);}}
使用service绑定,在service里使用Timer
新建service,继承Service
在oncreate里使用Timer进行刷新,每秒一次
public class AllWidgetService extends Service {private Timer timer;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();timer = new Timer();//参数:1.事件2.延时事件3.执行间隔事件timer.schedule(new TimerTask() {public void run() {updateView();}}, 0, 1000);}@Overridepublic void onDestroy() {super.onDestroy();timer = null;}private void updateView() {/*** 参数:1.包名2.小组件布局*/RemoteViews rViews = new RemoteViews(getPackageName(), R.layout.all_widget);//自己的ui操作// 刷新AppWidgetManager manager = AppWidgetManager.getInstance(getApplicationContext());ComponentName cName = new ComponentName(getApplicationContext(), AllWidget.class);manager.updateAppWidget(cName, rViews);}private String getPerscent(int max, int progress) {int percent = progress * 1000 / max;return percent / 10 + "." + percent % 10 + "%";}}
ok,这样就好了,一个时间进度条就这样写好了。。其中遇到一个小插曲,【参考indeterminate属性】在插件里显示进度条一直没有显示正确的进度,而是一个细细的进度条来回动,网上查找无果,经过各种调试,终于发现了问题所在:
rViews.setProgressBar(progressBar, max, process, false);
在桌面插件里设置进度条只能使用setProgressBar这个方法,其中最后一个参数要命了,刚开始设置的是true,后来改成了false就好了!
官方的方法是这样的:
/*** Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax},* {@link ProgressBar#setProgress ProgressBar.setProgress}, and* {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate}** If indeterminate is true, then the values for max and progress are ignored.** @param viewId The id of the {@link ProgressBar} to change* @param max The 100% value for the progress bar* @param progress The current value of the progress bar.* @param indeterminate True if the progress bar is indeterminate,*false if not.*/public void setProgressBar(int viewId, int max, int progress,boolean indeterminate) {setBoolean(viewId, "setIndeterminate", indeterminate);if (!indeterminate) {setInt(viewId, "setMax", max);setInt(viewId, "setProgress", progress);}}
在对进度条SeekBar或者ProgressBar设置进度的时候,有些时候我们并不知具体进度值是多少,但是也需要有动态进度的提醒。
但是,咱们是知道进度值是多少的!!所以,这里设置为false就可以了
最终,大功告成。
未来还有很多要写,对技术心存敬畏之心
时间一去不复返,对时间也心存敬畏之心!珍惜时间!