记录《时间进度》(人生进度条)(包含自定义进度、小插件)的开发

前言

开发的本意是想看到可视化的时间,让我们心存敬畏,珍惜时间,毕竟时间一去不复返!

最近灵感突突然袭来,想着做一个时间精度条:今天度过了多少,这周度过了多少,这个月度过了多少,今年度过了多少(以及这一辈子度过了多少),刚开始真的只是自己想做,不知道小爱同学有了【对小爱同学说人生进度条你就看到了】,后来有使用者提醒到了小爱,自己发现小爱同学的界面做的还行,于是就仿照着界面做了这个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" /> &lt;!&ndash; 渐变 &ndash;&gt;-->
    <!--<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就可以了

最终,大功告成。
未来还有很多要写,对技术心存敬畏之心
时间一去不复返,对时间也心存敬畏之心!珍惜时间!

发布了52 篇原创文章 · 获赞 36 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/easy_purple/article/details/90384782