前言
开发的本意是想看到可视化的时间,让我们心存敬畏,珍惜时间,毕竟时间一去不复返!
最近灵感突突然袭来,想着做一个时间精度条:今天度过了多少,这周度过了多少,这个月度过了多少,今年度过了多少(以及这一辈子度过了多少),刚开始真的只是自己想做,不知道小爱同学有了【对小爱同学说人生进度条你就看到了】,后来有使用者提醒到了小爱,自己发现小爱同学的界面做的还行,于是就仿照着界面做了这个app,目前来说还没有什么重大的bug(毕竟作为一个极小的应用再有bug的话简直没谁了。。)先看一下界面吧(目前是第四个版本,支持两个桌面插件)
下载地址:时间进度:https://www.coolapk.com/apk/com.imfondof.progress
(如果对源码感兴趣,可加入星球,查看源码地址)
## 自定义进度条 先来说一下自定义进度条的事 刚开始看到小爱同学的人生进度条,感觉很好看,比我第一个版本的好看多了(这里就不贴了,太丑了,但是如果你想看的话可以在应用市场里在其他用户的评论里看到),于是想着这个是怎么实现的呢?难道是某个大神在github里造的轮子?于是寻寻觅觅,最后也没有发现这种效果,网上却通过多个博客帮助实现了这种效果,在这里谢过! > 过程是这样的,使用系统提供的进度条,设置为水平,然后再给他来个drawable特效:progress_month就好了 > drawable特效里设置默认的背景颜色,以及进度条的属性,还是使用drawable特效:round_month > 在round_month,咱们给他设置圆角,设置进度条的颜色,(你还可以设置渐变色哦,代码里注释掉了)<!-- 在activity_main.xml里-->
<ProgressBar
android: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="http://schemas.android.com/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">
<scale
android:drawable="@drawable/round_month"
android:scaleWidth="100%" />
</item>
</layer-list>
<!-- 在drawable里新建round_month-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/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" />-->
<gradient
android: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使用了service
private 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);
}
@Override
public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (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;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
timer = new Timer();
//参数:1.事件2.延时事件3.执行间隔事件
timer.schedule(new TimerTask() {
public void run() {
updateView();
}
}, 0, 1000);
}
@Override
public 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就可以了
最终,大功告成。
未来还有很多要写,对技术心存敬畏之心
时间一去不复返,对时间也心存敬畏之心!珍惜时间!