精华内容
下载资源
问答
  • 以下图片是我做项目的个订单界面,开始想要做出来15分钟的倒计时的计时器,但是却无从下手,想了差不多两天才想出来。当终于做出来的时候,心情是无比的兴奋。现在给大家分享一下我的做法和想法: 因为我的...

    以下图片是我做项目的一个订单界面,一开始想要做出来15分钟的倒计时的一个计时器,但是却无从下手,想了差不多两天才想出来。当终于做出来的时候,心情是无比的兴奋。现在给大家分享一下我的做法和想法:
    在这里插入图片描述
    因为我的确认订单还没有做出来,所以没有下单时间,因此我想到了用当前的时间。原来的思路就是获取当前的时间,然后把当前的时间加上15分钟,然后再减去当前时间。可问题是当前的时间是在定时器里获取的,当前时间是在不停的跳动,所以在不停的获取。而我需要的是获取当前此时此刻的时间。所以当前时间加上15分钟后的时间和当前时间都是不同的,被减数永远都是15分钟。然后我就进行更改。
    在这里插入图片描述
    所以上面提到的下单时间是要一个定值,所以我选择了用登录时间,登录时间是确定的。控制器返回登录时间给页面,页面接收就可以直接使用了。在window的setInterval () 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。我这里以1000毫秒,也就是1秒来执行一次。
    在这里插入图片描述
    上面的登录时间为(2019-07-26 11:26:25),为什么要把登录时间放进Date()里面呢?把登录时间转换为中国时间的格式,方便在下面运算。其次就是15分钟的一个毫秒值,下面要进行计算。然后就是把登录时间加上15分钟后的时间也就是第二次时间,设置它的毫秒值(900000)相当于登录时间的毫秒值加上900000毫秒。

    时间段=15分钟后的时间获取毫秒值—减去当前时间的毫秒值,得到的就是时间段的一个毫秒值。再计算除了小时还剩余多少毫秒,hou1是剩余多少小时,Math.floor是对一个数进行向下取整计算,它返回的是小于或等于函数参数,并且与之最接近的整数。,其次是剩余多少分钟,除了分钟剩余多少毫秒,剩余多少秒数。
    在这里插入图片描述
    设置一个空字符串,如果剩余分钟>0,就拼接分字,接着拼接秒字,多少分多少秒。否则就直接多少秒。把字符串设置相应位置的ID的文本值。在这里我再设置一下,给一个判断,如果分钟<=0秒数<=0,就停止计时器。

    上面就是具体的操作,希望对你们有用,如果哪里分析不够恰当或者不清晰的地方请海涵,还可以在评论下面进行点评和指正~

    展开全文
  • 倒数计时器就是这样种元素,当用户登陆页面时,它会给用户产生种紧迫感。在我们的日常生活中,会看到各种各样的倒计时设计效果,比如:视频的开头;APP启动页面的右上角;某些电子商务和活动网站的价格区域,...

    视觉效果和动画效果已经成为产品设计中不可或缺的一部分,开发人员使用动画效果可以创建引人入胜的内容,营销人员可以使用这些效果来获得更好的产品覆盖率和良好的转化率。倒数计时器就是这样一种元素,当用户登陆页面时,它会给用户产生一种紧迫感。

    在我们的日常生活中,会看到各种各样的倒计时设计效果,比如:视频的开头;APP启动页面的右上角;某些电子商务和活动网站的价格区域,等等。

    毫无疑问,倒计时是非常有用的。在电子商务网站中,倒数计时器广泛使用在特惠价附近,以使用户感到机不可失。大多情况下,无论用户是否有购买产品的意愿,这种营销技巧对用户都是非常有效的。富有创造力的倒数计时器页面设计可以获得很多潜在客户并提高产品的转化率。那么,如何用简单的方法做出酷炫的倒计时效果呢?在下面列表中,小编给大家收集了十款最佳免费倒数计时器动效,我们一起来学习一下。

    1

    Watch Timer

    af071c7cfdb8482cd77bf365a1c59520.gif

    智能穿戴设备在当今的受众中正在迅猛增长, 进行健身运动时,智能手表上最常用的功能之一就是计时器。在这个倒数计时器设计中,设计师使用了不同的颜色。我们只需拖动顶部的时间滑块即可设置“倒计时”时间。点击“开始”图标后,倒计时开始,环形进度条的进度也随之减小,整体效果非常炫酷。

    2

    Daily UI

    ff459cbe6a45c70ebeb8258bca2b1060.gif

    Daily UI倒数计时器设计非常富有创意,该计时器可以很好的用在产品发布会等大屏场合。视觉效果非常流畅,即使在小型屏幕设备上也不会出现滞后现象。使用白色的数字字体,和背景很好地融合在一起。

    3

    Storm

    687b4959d7faa67b5bc1395d00bba06a.png

    这个倒数计时器效果非常适合于电子商务网站和时尚网站。设计师使用了干净的图像背景,整体文本在背景上看起来也非常简洁、清晰。倒数计时器使用白色框突出显示,与黑色的计时器刻度盘对比明显,很容易引起用户的注意。

    4

    Pomodoro Clock

    ae19e0d1d06eff5af9d2ccf3d1afbced.gif

    整体设计看起来很时髦、现代且诱人。这个倒数计时器不仅可以设置时间,还可以播放一些音乐。默认情况下,此时钟支持五种音轨,用户可以根据自己的喜好更改音轨。背景使用了流行的渐变色,非常具有视觉冲击力。

    5

    数字倒数计时器

    7484247a127219ef7482d853f64820f9.gif

    这是一个非常常规的数字倒数计时器设计。整体设计非常简洁,大方。使用的字体很大,富有现代感,可以让用户清楚地看到时间。另外,旋转动画是非常平滑干净的。尤其是在分钟部分,过渡很顺利。

    6

    倒数计时器

    861aca83c307789ce92c9654508160c9.gif

    在这个倒数计时器中使用了卡片翻转风格的效果,模拟日历卡片的翻页效果,趣味性很强。整体效果看起来非常平滑,整洁,尤其是分钟和秒钟内所有卡片同时翻转时,你都可以体验到效果的平滑度。此外,字体还精心的选择了以配合复古的外观和现代设计。

    7

    倒数计时器设计

    f29c6b56eef8799e050f6cfc9daba312.png

    这个倒数计时器中的图像背景上的白色圆形刻度盘提供了非常清晰的视图。页面使用了分屏设计的布局形式,将页面的内容保留在另侧,而计时器保留在左侧。使用这种设计方式可以很好的向用户告知某些信息。例如:如果网站因这种设计而需要维护,则可以清楚地指出需要花费多长时间。此外,用于文本和计时器的字体非常干净且易于阅读。

    8

    Online store

    a0d009eab2738fd6facc01f2e1df5f59.gif

    随着假期的临近,很多在线商店都在做产品促销活动。上面的倒数计时器效果非常适用于商城网站。此设计中的计时器具有天、小时、分钟和秒的格式,可以帮助站主提醒用户,给用户心理带来紧迫感。当然,也可以在电子邮件中使用此计时器,向客户发送交互式电子邮件。

    9

    倒数计时器设计

    385694469d02f9fd38719b236e941bd1.gif

    倒数计时器使用斜体字体,背景使用轮播图片的形式进行切换,看起来很吸引人。文本和倒数计时器虽使用了不同的字体,但它们彼此之间达到了完美的平衡,并为整体设计带来优雅的外观。

    10

    顶部倒数计时器设计效果

    cd6e0f483faaf1bf90713b1cc26c7c84.gif

    将倒数计时器置于页面的顶部位置,而顶部一般都是显示重要通知的最佳位置。用户进入页面后,计时器非常显眼,不会分心,同时,确保用户至少会看到一次。时钟的每个部分都由细线隔开,动画效果简洁明了。

    dca44657dd7defab719e8874d4a282b6.gif 倒数计时器原型设计

    在进行精美的UI界面设计之前,对界面进行原型设计是必不可缺的一步。还是老规矩,今天小编带着大家使用原型工具Mockplus对倒数计时器效果进行简单的原型设计。

    首先,我们一起来看看效果:

    dc3271bc53f76c8f24e2a76be8593d5d.gif

    设计步骤解析:

    1)拖出圆形组件,对其设置文本、背景色及去掉边框。

    2)复制4个同样的组件,并输入对应数字(最后一个设为空白)。

    3)5个组件分别对自己设置交互,选择触发方式为“载入时”,效果为显示/隐藏。

    4)分别设置好相应延迟时间,最大的一个数字,延迟时间应最短。

    5)将五个组件按数字大小依次叠加在一起,最小的数字组件放在最下面。

    e4c5942120b81a969b1f9509ecd10fa1.png

    总 结

    倒数计时器的使用场景非常多,如果我们使用得当,会给我们带来非常有效的效果。当然,这些前提是我们有一个优秀的倒数计时器设计,对倒数计时器感兴趣的设计师,可以结合上面的实例和想法去设计一个属于自己的倒数计时器。

     c89bbfca749ea7ab4fc8349a7f27e759.gif

    恭喜以下小伙伴每人获得《UI那些事儿》一本!

    Vicky.

    还好

    伍三芹

    请获奖小伙伴在10月25日(本周五)12:00前,将收货地址及收货人信息发送至本公众号后台~

    630b7094d953168eb14d87c1773fea83.png 摹  客

    让设计和协作,更快更简单

    https://www.mockplus.cn/

    20772e1a0f5f68bc2be5c71a3d845860.png

    展开全文
  • 今天分享个基础知识,主要有:1、解决CountDownTimer计时器少一秒的问题;2、实现个简单的自定义view关于计时器,Android已经分装好了CountDownTimer,给我们的开发带来了很大的方便,使用时只要new ...

    今天分享一个基础知识,主要有:

    1、解决CountDownTimer计时器少一秒的问题;

    2、实现一个简单的自定义view


    关于计时器,Android已经分装好了CountDownTimer,给我们的开发带来了很大的方便,使用时只要new CountDownTimer(long millisInFuture, long countDownInterval)就可以了,来看一下API。


    CountDownTimer (long millisInFuture, long countDownInterval)
    参数1,倒计时的总时间(毫秒)
    参数2,每次间隔多少毫秒

     

    CountDownTimer我们使用最常见的场景应该是获取验证码。下面我们来看一个简单的获取验证码案例。


    在页面放一个按钮Button。

       <Button
            android:id="@+id/btnStart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="获取验证码" />


    private Button btnStart; 
        @Override
        public void onCreate(Bundle savedInstanceState) {       
           super.onCreate(savedInstanceState);        initView();    }    
           private void initView(){        btnStart =(Button) findViewById(R.id.btnStart);        btnStart.setOnClickListener(new View.OnClickListener() {      
               @Override            public void onClick(View v) {              
                  //1,请求服务器...               //2,触发定时器刷新UI(验证码发送成功后调用)                timer.start();            }        });    }  
       private CountDownTimer timer = new CountDownTimer(10000, 1000) {          @Override          public void onTick(long millisUntilFinished) {              btnStart.setText((millisUntilFinished / 1000) + "秒后可重发");          }          @Override          public void onFinish() {              btnStart.setEnabled(true);              btnStart.setText("获取验证码");          }      };  

    这样一个简单的CountDownTimer案例就完成了。

    细心地你,相信在测试时能注意到这样一个问题:

    CountDownTimer(10000, 1000)指的是倒计时10S间隔1s,正常的应该是10s 、9s、8s、 ... 、4s、3s、2s、1s。实际却是9s、... 、4s、3s、2s 、1s,有时候会出现跳一秒(10s、8s、7s、6s、5s、4s、3s、2s)而且最后一次计时大于1000毫秒 ,造成的原因是计时时候出现了延迟。

    我们先看一下CountDownTimer源码。


    CountDownTimer:

        private Handler mHandler = new Handler() {        
       @Override        public void handleMessage(Message msg) {            
       synchronized (CountDownTimer.this) {              
        if (mCancelled) {                  
         return;                }        
                 final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();                if (millisLeft <= 0) {                    onFinish();                } else if (millisLeft < mCountdownInterval) {                    sendMessageDelayed(obtainMessage(MSG), millisLeft);                } else {                  
                  long lastTickStart = SystemClock.elapsedRealtime();                    onTick(millisLeft);                  
                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();                    while (delay < 0) delay += mCountdownInterval;                    sendMessageDelayed(obtainMessage(MSG), delay);                }            }        }    };

    通过源码我们注意到了它的判断规则,很清楚,为此针对延时,我们可以尝试这样处理。用线程再次延时处理。

               if (millisUntilFinished > 1000 && millisUntilFinished < 2000) {
                    mHandler.postDelayed(new Runnable() {                   
                       @Override                    public void run() {                        btnStart.setText(1 + "秒后可重发");                    }                }, 1000);            }

    这样就可以避免了出现倒计时少一秒的情况发生。

       private String TAG = getClass().getSimpleName();    
       private Button btnStart;  
        private Handler mHandler = new Handler() {      
            @Override        public void handleMessage(Message msg) {      
               super.handleMessage(msg);        }    };    
        @Override    protected void onCreate(Bundle savedInstanceState) {      
            super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnStart = (Button) findViewById(R.id.btnStart);        btnStart.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                countDownTimer.start();            }        });    }    CountDownTimer countDownTimer = new CountDownTimer(10000, 1000) {        @Override        public void onTick(long millisUntilFinished) {          
             double num = (double) millisUntilFinished / 1000;            Log.d(TAG, "millisUntilFinished : " + (int) Math.ceil((num)));            btnStart.setText((int) Math.ceil((num)) + "秒后可重发");            if (millisUntilFinished > 1000 && millisUntilFinished < 2000) {                mHandler.postDelayed(new Runnable() {                  
             @Override         public void run() {            btnStart.setText(1 + "秒后可重发");             }         }, 1000);      }            btnStart.setEnabled(false);        }      
            @Override        public void onFinish() {            Log.d(TAG, "onFinish 0");            btnStart.setText("获取验证码");            btnStart.setEnabled(true);            countDownTimer.cancel();        }    };  
        @Override    protected void onDestroy() {        
              super.onDestroy();      
                if (null != countDownTimer) {            countDownTimer.cancel();            countDownTimer = null;        }        
                if (null != mHandler) {            mHandler.removeCallbacksAndMessages(null);        }    } }

    要是我们项目中有多处需要用到这样的倒计时时,比如忘记密码处找回密码,登录获取验证码时,注册时获取验证码等,要是我们每次都这样写,会有一定的工作量,为了避免搬砖,我们可以对CountDownTimer进行简单封装,再优雅点,我们把获取验证码按钮自定义成为一个按钮,这样我们需要时在引用就可以了。省去一些复制粘贴一些重复性代码。把时间花在刀刃上。


    下面是我自定义的一个CountDownButton,继承Button。

    public class CountDownButton extends Button {   
       /**     * 总时长     */    private long mMillisInFuture = 100000;    
       /**     * 间隔时长     */    private long countDownInterval = 1000;    
       /**     * 按下背景色     */    private Drawable boxBgFocus = null;    
       /**     * 背景色     */    private Drawable boxBgNormal = null;  
        /**     * 是否结束     */    private boolean isFinish;        private String defaultText= "获取验证码";    
        private CountDownTimer countDownTimer;    
        public CountDownButton(Context context) {      
         this(context, null);     }    
        public CountDownButton(Context context, AttributeSet attrs) {    
             this(context, attrs, 0);     }  
        public CountDownButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CountDownButton);        mMillisInFuture = (long) typedArray.getInt(R.styleable.CountDownButton_millisInFuture, 10000);        countDownInterval = (long) typedArray.getInt(R.styleable.CountDownButton_countDownInterval, 1000);        boxBgFocus = typedArray.getDrawable(R.styleable.CountDownButton_bg_focus);        boxBgNormal = typedArray.getDrawable(R.styleable.CountDownButton_bg_normal);        typedArray.recycle();        isFinish = true;        setGravity(Gravity.CENTER);                setText(defaultText);        setBackground(boxBgNormal);              countDownTimer = new CountDownTimer(mMillisInFuture, countDownInterval) {            @Override            public void onTick(long millisUntilFinished) {                isFinish = false;                setText((Math.round((double) millisUntilFinished / 1000) - 1) + "秒");                setBackground(boxBgFocus);            }            
              @Override            public void onFinish() {                isFinish = true;                setText(defaultText);                setBackground(boxBgNormal);            }        };    }    
        public boolean isFinish() {      
               return isFinish;    }    
        public void cancel() {        countDownTimer.cancel();    }    
        public void start() {        countDownTimer.start();    } }

    属性值 attr

    <?xml version="1.0" encoding="utf-8"?><resources>
        <declare-styleable name="CountDownButton">
            <attr name="millisInFuture" format="integer"/>
            <attr name="countDownInterval" format="integer"/>
            <attr name="bg_focus" format="reference"/>
            <attr name="bg_normal" format="reference"/>
        </declare-styleable></resources>

    使用

    
        <项目包名.CountDownButton
            android:id="@+id/btnCountDown"
            android:layout_margin="30dp"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            code:bg_normal="@drawable/verification_edit_bg_normal"
            code:bg_focus="@drawable/verification_edit_bg_focus"
            android:text="获取验证码"/>
       private String TAG = getClass().getSimpleName();   
       private CountDownButton  countDownButton;  
        @Override    protected void onCreate(Bundle savedInstanceState) {    
           super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        countDownButton = ((CountDownButton) findViewById(R.id.btnCountDown));        countDownButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {              
            //是否倒计时结束,避免在倒计时时多次点击导致重复请求接口                if (countDownButton.isFinish()) {                    
            //发送验证码请求成功后调用                    countDownButton.start();                }            }        });    }

    END】


    点击图片查看更多精彩推荐内容

    ↓↓↓

     

    手把手教你开发自定义控件

    展开全文
  • 模仿小米计时器

    千次阅读 2017-11-15 15:24:24
    模仿小米计时器(第次写博客,有不当之处请见谅,大家如果有什么好的意见,我也会欣然接受的O(∩_∩)O。) 话不多说,我先上个效果图 (界面有点粗糙哈!) 下面咱们直接看代码 `package ...

    模仿小米计时器

    (第一次写博客,有不当之处请见谅,大家如果有什么好的意见,我也会欣然接受的O(∩_∩)O。)
    话不多说,我先上一个效果图
    这里写图片描述
    (界面有点粗糙哈!)

    • 下面咱们直接看代码
    • `package com.example.a14409.cookbook.view;

    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.media.MediaPlayer;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.util.TypedValue;
    import android.view.View;
    import com.example.a14409.cookbook.constent.Constents;
    import com.example.a14409.cookbook.presenter.Interface.ShakeInvoke;
    import com.example.a14409.cookbook.service.Clockservice;
    import com.example.a14409.cookbook.utils.Utils;
    import java.util.Calendar;

    /**
    * 计时器
    */
    public class ClockView extends View {

    private Paint circlePaint;//圆盘画笔
    private Paint centurePaint;//圆心画笔
    private Paint numPaint;//数字画笔
    private Paint hourPaint;//时针画笔
    private Paint minutePaint;//分针画笔
    private Paint secondPaint;//秒针画笔
    private Paint ArcPaint;//外圈刻度画笔
    private Paint changePaint; //渐变画笔
    private float width;//此时钟控件的默认宽度
    private float height;//此时钟控件的默认高度
    private Calendar calendar; //时间对象
    private Path path; //画三角形
    private static float schedules = 0;//进度显示格数
    private static float second = 0;//秒针的旋转速度
    private static int time = 0;//显示的秒数
    private static int minute = 0;//显示的分钟数
    private static int hour = 0;//显示的小时数
    private int seconds;//获取的秒数
    private boolean start_stop = false;//开始
    private boolean startservice;//开始
    private static float ratio = 0;
    private static float sss = 0;
    private static int sum = 0;
    public static float hand = 0;
    private float bl;//屏幕比例
    private boolean origin = true;//原点
    private boolean end;//结束
    private Canvas canvas;
    private MediaPlayer mediaPlayer;
    private static String hours, minutes, times;//时间
    private static float TIMES;
    private ShakeInvoke invoke;
    
    /**
     * 开启线程,是程序退出或者黑屏保存数据不停止
     * */
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    if (start_stop) {//每0.1秒更新一次
                        if (seconds >= 1) {
                            TIMES -= 0.1;
                            timeDate();
                            if (sum < 60 && seconds < 60) {
                                hand -= (float) 36 / 60;
                                schedules = hand/3*5;
                            } else {
                                hand += (float) 36 / 60;
                                schedules = hand/3*5;
                                if (hand >= 360) {
                                    hand = 0;
                                }
                            }
    
                            if (TIMES < 0.1) {
                                //结束播放铃声
                                mediaPlayer.start();
                                if(!Constents.ISSHAKE){
                                    invoke.Shake();
                                }
    
                            }
                        }
                    }
    
                    break;
            }
        }
    };
    
    /**
     * 时间变化
     */
    private void timeDate() {
    
        if (sum <= 60) {
            second = (float) (second + 0.1);
            time = seconds - (int) (second);
            Log.e("TAG", "seconds: "+time );
        } else {
            second = (float) (second + 0.1);
            time = seconds - (int) (second);
        }
    
        if (schedules > 600) {
            schedules = 0;
            origin = !origin;
        }
    
    
        if (hour >= 10) {
            hours = "" + hour;
        } else if (hour >= 1 && hour < 10) {
            hours = "0" + hour;
        } else if (hour < 1) {
            hours = "00";
        }
        if (minute >= 10) {
            minutes = "" + minute;
        } else if (minute >= 1 && minute < 10) {
            minutes = "0" + minute;
        } else if (minute < 1) {
            minutes = "00";
        }
    
    
        if (time >= 10) {
            times = "" + time;
        } else if (time >= 1 && time < 10) {
            times = "0" + time;
        } else if (time < 1) {
            times = "00";
            if (minute < 1 && hour > 1) {
                hour--;
                if (hour >= 10) {
                    hours = "" + hour;
                } else if (hour >= 1 && hour < 10) {
                    hours = "0" + hour;
                } else if (hour < 1) {
                    hours = "00";
                }
                minute = 59;
                minutes = "" + minute;
                time = 60;
                times = "" + time;
    
            } else if (minute >= 1 && hour < 1) {
                minute--;
                if (minute >= 10) {
                    minutes = "" + minute;
                } else if (minute >= 1 && minute < 10) {
                    minutes = "0" + minute;
                } else if (minute < 1) {
                    minutes = "00";
                }
    
                time = 60;
                times = "" + time;
                second = (float) 0.0;
                seconds = 60;
            } else if (minute >= 1 && hour >= 1) {
                minute--;
                if (minute >= 10) {
                    minutes = "" + minute;
                } else if (minute >= 1 && minute < 10) {
                    minutes = "0" + minute;
                } else if (minute < 1) {
                    minutes = "00";
                }
                seconds = 60;
                second = (float) 0.0;
                time = seconds;
                times = "" + seconds;
            } else if (minute < 1 && hour >= 1) {
                hour--;
                if (hour >= 10) {
                    hours = "" + hour;
                } else if (hour >= 1 && hour < 10) {
                    hours = "0" + hour;
                } else if (hour < 1) {
                    hours = "00";
                }
                minute = 59;
                minutes = "" + 59;
                seconds = 60;
                second = (float) 0.0;
                time = seconds;
                times = "" + seconds;
            }
        }
    

    // Log.e(“TAG”, hours + “:” + minutes + “:” + times);
    }

    public void MyMediaPlayer(MediaPlayer mediaPlayer) {
        this.mediaPlayer = mediaPlayer;
    }
    
    public ClockView(Context context) {
        this(context, null);
    }
    
    public ClockView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
        bl = Utils.Screen(context);
    }
    
    /**
     * 回调
     * */
    public void ShakeInvoke(ShakeInvoke invoke){
        this.invoke = invoke;
    }
    //此方法用作初始化变量
    private void initView() {
    
        //初始化各种画笔
        circlePaint = new Paint();
        centurePaint = new Paint();
        ArcPaint = new Paint();
        numPaint = new Paint();
        hourPaint = new Paint();
        minutePaint = new Paint();
        secondPaint = new Paint();
        changePaint = new Paint();
    
        path = new Path();
        //自己定义的长度宽度,方法作用是把参数2的276转换成dp单位,即276dp
        width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 276, getResources().getDisplayMetrics());
        height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 276, getResources().getDisplayMetrics());
        //圆盘画笔设置
        circlePaint.setAntiAlias(true);//消除锯齿
        circlePaint.setColor(Color.WHITE);//设置圆盘画笔的颜色为红色
        circlePaint.setStyle(Paint.Style.STROKE);//设置画笔的类型为描边
        circlePaint.setStrokeWidth(1);//设置描边宽度
        circlePaint.setAlpha(100);//设置画笔透明度,最高值为255
        //外圈画笔设置
        ArcPaint.setAntiAlias(true);
        ArcPaint.setColor(Color.WHITE);
        ArcPaint.setStyle(Paint.Style.STROKE);
        ArcPaint.setStrokeWidth(1);
        //圆心画笔设置
        centurePaint.setStyle(Paint.Style.STROKE);//设置画笔的类型为铺满
        centurePaint.setColor(Color.WHITE);//设置画笔的颜色为红色
        centurePaint.setAntiAlias(true);//设置圆心画笔为无锯齿
        centurePaint.setStrokeWidth(5);
        //数字画笔设置
        numPaint.setAntiAlias(true);
        numPaint.setColor(Color.WHITE);
        numPaint.setStrokeWidth(1);
        numPaint.setTextSize(20);
        //时钟画笔设置
        hourPaint.setColor(Color.WHITE);
        hourPaint.setAntiAlias(true);
        hourPaint.setStrokeWidth(6);
        hourPaint.setAlpha(100);
        //分钟画笔设置
        minutePaint.setColor(Color.WHITE);
        minutePaint.setAntiAlias(true);
        minutePaint.setStrokeWidth(3);
        //秒钟画笔设置
        secondPaint.setColor(Color.WHITE);
        secondPaint.setAntiAlias(true);
        //渐变画笔设置
        changePaint.setColor(Color.WHITE);
        secondPaint.setAntiAlias(true);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        this.canvas = canvas;
        super.onDraw(canvas);
        ratio = (float) seconds / 36;
        //首先获取当前时间
        calendar = Calendar.getInstance();
        //开始画圆盘
        float radius = width / 2 - 20;//圆盘的半径
    
        //小于一分钟的话用另外一种展示的格式
        if (sum < 60 && seconds < 60) {
            sss = sss - ((float) (seconds * 6) / (seconds * 10));
    
            for (float i = 0; i < hand; i = i + ((float) (seconds * 6) / (seconds * 10))) {
    
                circlePaint.setAlpha(255);//设置画笔透明度,最高值为255
    
                //画刻度之前,先把画布的状态保存下来
                canvas.save();
                //让画布旋转3/5度,参数一是需要旋转的度数,参数2,3是旋转的圆心
                canvas.rotate(i, getWidth() / 2, getHeight() / 2);
                //旋转后再圆上画上一长10dp的刻度线
                canvas.drawLine(width / 2 - 30 / bl, height / 2 + 20 / bl - radius, width / 2 - 30 / bl, height / 2 + 45 / bl - radius, circlePaint);
                //恢复画布
                canvas.restore();
            }
    
        } else {
           //启动之后进度随着时间变化
            for (float i = 0; i < 600; i++) {
    
                if (i < schedules) {
    
                    if (origin) {
                        circlePaint.setAlpha(255);//设置画笔透明度,最高值为255
                    } else {
                        circlePaint.setAlpha(0);//设置画笔透明度,最高值为255
                    }
                } else {
                    if (origin) {
                        circlePaint.setAlpha(0);//设置画笔透明度,最高值为255
                    } else {
                        circlePaint.setAlpha(255);//设置画笔透明度,最高值为255
                    }
                }
    
                //画刻度之前,先把画布的状态保存下来
                canvas.save();
                //让画布旋转3/5度,参数一是需要旋转的度数,参数2,3是旋转的圆心
                canvas.rotate(i * 36 / 60, getWidth() / 2, getHeight() / 2);
                //旋转后再圆上画上一长10dp的刻度线
                canvas.drawLine(width / 2 - 30 / bl, height / 2 + 20 / bl - radius, width / 2 - 30 / bl, height / 2 + 45 / bl - radius, circlePaint);
                //恢复画布
    
                canvas.restore();
            }
        }
        //原生透明圈
        for (int i = 0; i < 360; i++) {
            circlePaint.setAlpha(100);//设置画笔透明度,最高值为255
            //画刻度之前,先把画布的状态保存下来
            canvas.save();
            //让画布旋转3/5度,参数一是需要旋转的度数,参数2,3是旋转的圆心
            canvas.rotate(i, getWidth() / 2, getHeight() / 2);
            //旋转后再圆上画上一长10dp的刻度线
            canvas.drawLine(width / 2 - 30 / bl, height / 2 + 20 / bl - radius, width / 2 - 30 / bl, height / 2 + 45 / bl - radius, circlePaint);
            //恢复画布
            canvas.restore();
        }
        //画外围四分圈
        //画圆弧对象,参数1234分别代表,起始x值,起始y值,终点x值,终点y值
        RectF oval = new RectF(5 / bl, 5 / bl, getWidth() - 5 / bl, getHeight() - 5 / bl);
        //利用画布进行画弧,参数1是RectF对象,参数2是起始点,参数3是要画的度数(多大),4画笔对象
        canvas.drawArc(oval, -88, 90, false, ArcPaint);
        canvas.drawArc(oval, 2, 90, false, ArcPaint);
        canvas.drawArc(oval, 92, 90, false, ArcPaint);
        canvas.drawArc(oval, 182, 90, false, ArcPaint);
    
        Paint paint = new Paint();
        paint.setTextSize((float) 90 / bl);//设置字体大小
        paint.setColor(Color.WHITE);
    
        String hour_minute_time = hours + ":" + minutes + ":" + times;
    
        canvas.drawText(hour_minute_time, getWidth() / 29 * 8, getHeight() / 2 + 35 / bl, paint);//使用画笔paint
    
        Log.e("TAG", "onDraw: hand"+schedules );
        canvas.save();
        canvas.rotate((schedules * 36 / 60)+2, getWidth() / 2, getHeight() / 2);
        //Path是画自定义图形的对象,在构造方法中实例化
        path.moveTo(getWidth() / 2, getHeight() / 2 + 95 / bl - radius);//三角形的顶点
        path.lineTo(getWidth() / 2 - 10 / bl, getHeight() / 2 + 110 / bl - radius);//底边左端点
        path.lineTo(getWidth() / 2 + 10 / bl, getHeight() / 2 + 110 / bl - radius);//底边右端点
        path.close();//让三个点形成封闭的图形
        canvas.drawPath(path, secondPaint);//把形成的图形化在画布上
    
    
        if (time < 1 && minute < 1 && hour < 1) {
            start_stop = false;
        }
    
        canvas.restore();
        if (start_stop) {
            if (seconds >= 1) {
                postInvalidateDelayed(100);//每0.1秒更新一次
            }
        }
    
    }
    //初始化
    public void setImport(int seconds) {
        this.seconds = seconds;
        this.sum = seconds;
        this.TIMES = (float)seconds;
        //计算时间
        sss = seconds * 6;
        if (seconds > 3600) {
            hour = seconds / 3600;
            minute = seconds % 3600 / 60;
            this.seconds = seconds % 3600 % 60;
            time = seconds % 3600 % 60;
        } else if (seconds >= 60) {
            hand = 0;
            hour = 0;
            minute = seconds / 60;
            this.seconds = seconds % 60;
    
        } else if (seconds < 60) {
            hand = (float) 6 * sum;
            schedules = hand/3*5;
            hour = 0;
            minute = 0;
            second = 0;
            this.seconds = seconds;
    
        }
        timeDate();
    }
    
    //启动
    public void Start(boolean start, Context content) {
        this.start_stop = start;
        postInvalidateDelayed(0);//每0.1秒更新一次
        if (!startservice) {
            //启动服务
            Clockservice clockservice = new Clockservice(content, handler);
            Intent startIntent = new Intent(content, Clockservice.class);
            content.startService(startIntent);
            startservice = true;
        }
    
    }
    //暂停
    public void Stop(boolean stop) {
        this.start_stop = stop;
        postInvalidateDelayed(0);//每0.1秒更新一次
    }
    
    public void End(boolean end) {
        this.end = end;
    }
    

    }`

    (—–这个是计时器的核心布局view,具体的代码功能麻烦看一下注释,这边就不详细讲解了—–)

    • 布局代码
    • `

    - * 为了让计时器时刻工作,我们就需要给它开启一个服务,代码如下:*

    package com.example.a14409.cookbook.service;

    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;

    /**
    * 计时器service
    */

    public class Clockservice extends Service {

    private Context context;
    private Handler handler;
    public Clockservice(){
    }
    public Clockservice(Context context, final Handler handler){
        this.context = context;
        this.handler = handler;
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i<1000000;i++){
    
                    try {
                        Thread.sleep(100);
                        handler.sendEmptyMessage(0);
    
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }).start();
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
    
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("TAG", "onStartCommand() executed");
    
        return super.onStartCommand(intent, flags, startId);
    
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TAG", "onDestroy() executed");
    }
    

    }

    - 音乐播放和屏幕常亮的方法如下:

    /**
    * 播放音乐
    * */
    public static MediaPlayer isPlayOrPause(Context context,String musicpath) {
    MediaPlayer mediaPlayer = null;
    // final ImageButton imageButton = (ImageButton) view;
    if (mediaPlayer == null) {
    //播放内存卡中音频文件
    mediaPlayer = new MediaPlayer();
    //设置类型
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    //设置音源
    try {
    // mediaPlayer.setDataSource(context, Uri.parse(musicpath));
    File file = new File(musicpath);
    FileInputStream fis = new FileInputStream(file);
    mediaPlayer.setDataSource(fis.getFD());
    //准备一下(内存卡)
    mediaPlayer.prepare();
    } catch (IOException e) {
    e.printStackTrace();
    }
    // mediaPlayer.start();
    //把图标修改为暂停的图标
    // imageButton.setImageResource(android.R.drawable.ic_media_pause);
    //获取音乐的总时长
    int duration = mediaPlayer.getDuration();
    //设置进度条的最大值为音乐的总时长
    // seekBar.setMax(duration);
    // new MyThread().start();
    } else if (mediaPlayer.isPlaying()) {
    // mediaPlayer.pause();
    //把图标修改为播放的图标
    // imageButton.setImageResource(android.R.drawable.ic_media_play);

        } else {
    

    // mediaPlayer.start();
    //把图标修改为暂停的图标
    // imageButton.setImageResource(android.R.drawable.ic_media_pause);

        }
        return mediaPlayer;
    }
    
    /**
     * 屏幕常亮
     * */
    public static PowerManager.WakeLock ScreenBrigth(Context context){
        PowerManager powerManager = (PowerManager) context
                .getSystemService(Context.POWER_SERVICE);
        return powerManager.newWakeLock(
                PowerManager.FULL_WAKE_LOCK, "My Lock");
    }
    
    • -

    - 查找手机歌单代码如下:

    // 查找sdcard卡上的所有歌曲信息
    public static List getMultiData(Context context) {
    String musicPath = null;
    String musicName = null;
    String musicAlbum = null;
    String musicArtist = null;
    String musicAlbumKey = null;
    String musicAlbumArtPath = null;
    ArrayList
    musicList = new ArrayList();
    // 加入封装音乐信息的代码
    // 查询所有歌曲
    ContentResolver musicResolver = context.getContentResolver();
    Cursor musicCursor = musicResolver.query(
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
    null);
    int musicColumnIndex;
    if (null != musicCursor && musicCursor.getCount() > 0) {
    for (musicCursor.moveToFirst(); !musicCursor.isAfterLast(); musicCursor
    .moveToNext()) {
    Map musicDataMap = new HashMap();
    Random random = new Random();
    int musicRating = Math.abs(random.nextInt()) % 10;
    musicDataMap.put(“musicRating”, musicRating);
    // 取得音乐播放路径
    musicColumnIndex = musicCursor
    .getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
    musicPath = musicCursor.getString(musicColumnIndex);
    musicDataMap.put(“musicPath”, musicPath);

                // 取得音乐的名字
                musicColumnIndex = musicCursor
                        .getColumnIndex(MediaStore.Audio.AudioColumns.TITLE);
                musicName = musicCursor.getString(musicColumnIndex);
                musicDataMap.put("musicName", musicName);
    
                // 取得音乐的专辑名称
                musicColumnIndex = musicCursor
                        .getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM);
                musicAlbum = musicCursor.getString(musicColumnIndex);
                musicDataMap.put("musicAlbum", musicAlbum);
                // 取得音乐的演唱者
                musicColumnIndex = musicCursor
                        .getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST);
                musicArtist = musicCursor.getString(musicColumnIndex);
                musicDataMap.put("musicArtist", musicArtist);
                // 取得歌曲对应的专辑对应的Key
                musicColumnIndex = musicCursor
                        .getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM_KEY);
                musicAlbumKey = musicCursor.getString(musicColumnIndex);
                String[] argArr = {musicAlbumKey};
                ContentResolver albumResolver = context.getContentResolver();
                Cursor albumCursor = albumResolver.query(
                        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null,
                        MediaStore.Audio.AudioColumns.ALBUM_KEY + " = ?",
                        argArr, null);
                if (null != albumCursor && albumCursor.getCount() > 0) {
                    albumCursor.moveToFirst();
                    int albumArtIndex = albumCursor
                            .getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM_ART);
                    musicAlbumArtPath = albumCursor.getString(albumArtIndex);
                    if (null != musicAlbumArtPath
                            && !"".equals(musicAlbumArtPath)) {
                        musicDataMap.put("musicAlbumImage", musicAlbumArtPath);
                    } else {
                        musicDataMap.put("musicAlbumImage",
                                "file:///mnt/sdcard/alb.jpg");
                    }
                } else {
    

    // 没有专辑定义,给默认图片
    musicDataMap.put(“musicAlbumImage”,
    “file:///mnt/sdcard/alb.jpg”);
    }
    musicList.add(musicDataMap);
    }
    }
    return musicList;
    }

    (到这里计时器的功能就差不多了,只需要细细修改界面就好了,如有bug,希望大家指出!)


    展开全文
  • 使用stm32f103c8实现个简单的运动会计时器

    千次阅读 多人点赞 2018-04-28 09:55:32
    没事做突然想写博客,然后发现没有刷什么有价值的题,就...屏幕图片源水印淘宝店( ̄▽ ̄)” ok开始第步,配置管脚图 oled管脚*7,个3v3,个GND,还有五个GPIO输出。 这边用的是串行通信的方法,各个管...
  • 倒数计时器就是这样种元素,当用户登陆页面时,它会给用户产生种紧迫感。在我们的日常生活中,会看到各种各样的倒计时设计效果,比如:视频的开头;APP启动页面的右上角;某些电子商务和活动网站的价格区域,...
  • 简介:计时器小程序——秒表计时器,程序界面简洁,只有个时间显示区域和两个图片按钮,个按钮是开始/暂停,另个按钮是停止。 1.功能: (1)根据用户设置.按0.1秒或1秒为最小单位计时,满60秒进为分钟,最大...
  • 运行环境 Win7,Win8,Win10 win64 Reworld版本 体验版 针对零基础读者的补充 ... 时间戳实现思路分为三个部分:首先,获取当前时间和要计时为止的时间,然后转化为时间戳;其次,在当前时间与到达时间做差...
  • 1,setInterval()计时器 clearInterval()清除计时器 (1)在运行过程中,是不可以重新给setInterval赋值计时时间的。 (2)setInterval参数问题 ​ 第个参数function,必填的,回调函数,可以是个函数,也可以...
  • 安卓开发,实现双方比赛计时器: 效果图:           TimerMainActivity.java package com.example.fujianping.httprequest01.mytimer; import android.app.Activity; import android.app....
  • ❤️使用 HTML、CSS 和 JS 的简单倒数计时器 ❤️

    万次阅读 多人点赞 2021-09-09 16:07:44
    在本文中,我使用简单的 JavaScript 代码创建了个倒数计时器和你分享。 您可以观看它的现场演示以了解它是如何工作的。如果您知道如何创建数字时钟,那么创建这样的项目就会容易得多。您可以在此处提前安排特定...
  • ppt倒计时器制作方法

    千次阅读 2015-08-18 16:44:20
    第二:自己在PPT中应用文本框做一分钟PPT倒计时器:   一.PPT中插入一文本框,在文本框内输入“60~0”这61个数,一个数一行(敲回车) 小提示:可利用EXCEL表格从60向下填充,复制后无格式
  • JavaScript计时器延时执行

    千次阅读 2019-01-17 11:07:01
    在js(Javascript)中有个很关键的函数代码叫做计时器, 定时器有两种: 1.setInterval() ,2.setTimeout()。 setInterval():按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 ...
  • 计时软件 需求 最近工作/学习时总是感觉时间过的飞快,...最长倒计时支持到:59小时59分钟59秒 可灵活配置倒计时策略 运行环境 只适合在window7以上window系列64操作系统上运行。 启动软件 双击“CountDownExe_x64
  • 你说巧不巧,早上刚看到关于带薪拉屎的文章,今天下午就看到了这条消息:没错,今天有网友爆料某互联网公司在厕所安装了坑位计时器,以控制员工上厕所的时间。当然了,经过网友爆料和进一步探查某互联网公司就是快手...
  • Android实现秒表计时器的程序设计

    万次阅读 2010-08-08 18:21:00
    主要功能是实现秒表计时,功能简介如下:简介:计时器小程序——秒表计时器,程序界面简洁,只有个时间显示区域和两个图片按钮,个按钮是开始/暂停,另个按钮是停止。1.功能:(1)根据用户设置.按0.1秒或1秒为...
  • 最近学习JavaScript的计时器功能,做了个小案例,在此记录一下,需要的童鞋可以看一下,代码的缺点是小时数部分计时样式没有做出来完整的显示,望海涵。 实现的效果图片如图: ![在这里插入图片描述]...
  • Html+Css+js实现计时器

    千次阅读 2019-05-08 12:05:13
    Html+Css+js实现计时器 人狠话不多,先上图 实现原理: 1.通过js控制图片的路径,动态替换图片 2.通过js控制图片的显示或隐藏,动态替换图片 版的实现代码: game.html <body> <div class="game-...
  • 利用python wx库实现计时器
  • 最近在做项目的时候,需要对界面进行不断的刷新操作,在一定的时间内连续触发某个函数,按照之前Python里的思路,第反应是用time函数,但实际的效果并不好,经常会卡住,后来尝试用pyqt5里自带的计时器,这个问题...
  • 进阶_计时器(Handler+Thread实现)_150503

    千次阅读 2015-05-03 13:12:21
    有三种实现计时器的方式: 1:最基本的Handler+Thread的方式,因为最近准备着手了解线程和消息机制,所以这个会比较详细。 2:handler.postDelayed()方法,这个实现起来是最简单的,但是个人不太喜欢,因为递归...
  • JS倒计时效果+数字图片

    千次阅读 2017-07-14 21:30:07
    这里用JS结合组数字图片,写了个简单的倒计时效果。数字图片大家自己找啦,这里需要注意的就是图片命名——要和图片中的数字保持一致哟。 如果有什么不完善的地方,还请各路大神指点。 代码呈上:<!DOCTYPE ...
  • unity带指针的计时器

    2021-10-14 17:13:08
    } } 代码随便给任一物体,需要创建两个Image(表盘背景图片和指针图片),表盘背景的Image Type设置为Filled,选择360,只需要把时间(分钟或者秒)传进来,设置指针的角度(中心点Pivot要设置好,一般是设置在...
  • 48.计时器
  • 微信小程序使用 setInterval 制作计时器后台延迟问题 之前参加2020年微信小程序应用开发大赛的时候写了个用于校园足球的微信小程序——踢在浙大。 在小程序的设计过程中出现了个裁判工具的功能,简单地说就是...
  • 首先写计时器的头文件GameTimer.h: #ifndef _GAME_TIMER_H_ #define _GAME_TIMER_H_ #include "cocos2d.h" class GameTimer : public cocos2d::Node { public: GameTimer(); virtual ~GameTimer(); static...
  • (同济大学2021MBA提前面试流程)(西安交大2021MBA提前面试流程)正好今天下午3点刚参与了场西安交通大学MBA的提前面试模拟,小编现在就和大家分享一些技巧和注意事项。01制作PPT的注意事项首先,和大家分享一下制作...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,266
精华内容 2,506
关键字:

一分钟计时器图片