Accustomed to the default Android countdown font, the use of canvas drawing to achieve the countdown clock effect, first look at the static effect
It is not difficult to find that each number is a small circle, can also be changed to a small square, and so on, these are achievable.
The circle is used here.
A careful look at the numbers finds that it consists of a two-dimensional array, similar to the following: 0 can be drawn according to the following array, the effect
{0,0,1,1,1,0,0}, {0,1,1,0,1,1,0}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, { 1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {0,1,1,0,1,1,0}, {0,0,1,1,1,0,0}
How to do this, you can define a constant class, which can also be used in JSON format, and then read.
/** * Constants.java * Copyright (C) * Creator:cuiran 2014-12-19 PM 2:28:34 */package com.cayden.countdown;/** * TODO * @author Cuiran * @version 1.0.0 */public interface Constants {int[][] data0={{0,0,1,1,1,0,0}, {0,1,1,0,1,1,0}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1 }, {1,1,0,0,0,1,1}, {0,1,1,0,1,1,0}, {0,0,1,1,1,0,0}};int[][] data1={{0,0,0,1,1,0,0}, {0,1,1,1,1,0,0}, {0,0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {0, 0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {1,1,1,1,1,1, 1}};int[][] data2={{0,1,1,1,1,1,0}, {1,1,0,0,0,1,1}, {0,0,0,0,0,1,1}, {0,0,0,0,1,1,0} , {0,0,0,1,1,0,0}, {0,0,1,1,0,0,0}, {0,1,1,0,0,0,0}, {1,1,0,0,0,0,0}, {1,1,0,0,0,1,1}, {1,1,1,1,1,1,1}}; Int[][] data3={{1,1,1,1,1,1,1}, {0,0,0,0,0,1,1}, {0,0,0,0,1,1,0}, {0,0,0,1,1,0,0}, {0,0,1,1,1,0,0}, {0,0,0,0,1,1,0}, {0,0,0,0,0,1,1}, {0,0,0,0,0,1,1}, { 1,1,0,0,0,1,1}, {0,1,1,1,1,1,0}};int[][] data4={{0,0,0,0,1,1,0}, {0,0,0,1,1,1,0}, {0,0,1 , 1,1,1,0}, {0,1,1,0,1,1,0}, {1,1,0,0,1,1,0}, {1,1,1,1,1,1,1}, {0,0,0,0,1,1,0}, {0,0,0,0,1,1,0}, {0,0,0,0,1,1,0}, {0,0,0,1,1,1,1}};int[][] data5={{1,1,1,1,1,1,1}, {1,1,0,0,0,0,0}, {1,1,0,0,0,0,0}, {1,1,1,1,1,1,0}, {0,0,0,0,0,1,1}, {0,0 , 0,0,0,1,1}, {0,0,0,0,0,1,1}, {0,0,0,0,0,1,1}, {1,1,0,0,0,1,1}, {0,1,1,1,1,1,0 }};int[][] data6={{0,0,0,0,1,1,0}, {0,0,1,1,0,0,0}, {0,1,1,0,0,0,0}, {1,1,0,0,0,0,0}, {1,1,0,1,1,1,0}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1 , 1,0,0,0,1,1}, {0,1,1,1,1,1,0}};int[][] data7={{1,1,1,1,1,1,1}, {1,1,0,0,0,1,1}, {0,0,0,0 , 1,1,0}, {0,0,0,0,1,1,0}, {0,0,0,1,1,0,0}, {0,0,0,1,1,0,0}, {0,0,1,1,0,0,0}, {0,0,1,1,0,0,0}, {0,0,1,1,0,0,0}, {0,0,1,1,0,0,0}};int[][] data8={{0,1,1,1,1,1,0}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {0,1,1,1,1,1,0}, { , 0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {0,1,1,1,1,1,0 }};int[][] data9={{0,1,1,1,1,1,0}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {1,1,0,0,0,1,1}, {0,1,1,1,0,1,1}, {0,0,0,0,0,1,1}, {0,0,0,0,0,1,1}, {0,0,0,0,1,1,0}, {0,0,0,1,1,0,0}, {0,1,1,0,0,0,0}}; Int[][] data10={{0,0,0,0}, {0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0}, {0,1,1,0}, {0,1,1,0}, {0,0,0,0}, {0,0,0,0}};
Then customize a Countdownview inheritance Surfaceview, implement Runnable, callback,constants these three interfaces, the implementation of the thread interface is for the subsequent dynamic changes when used.
The specific code is as follows:
/** * Countdownview.java * Copyright (C) * Creator:cuiran 2014-12-19 pm 2:18:59 */package Com.cayden.countdown.view;im Port Java.util.arraylist;import Com.cayden.countdown.constants;import Android.content.context;import Android.graphics.canvas;import Android.graphics.color;import Android.graphics.paint;import Android.util.Log; Import Android.view.surfaceholder;import android.view.surfaceholder.callback;import android.view.SurfaceView;/** * Countdown View * @author Cuiran * @version 1.0.0 */public class Countdownview extends Surfaceview implements Runnable, Callback, Constants {private static final String tag= "Countdownview";p rivate surfaceholder Mholder; Used to control surfaceviewprivate Canvas Mcanvas; Declaration Canvas private Paint Mpaint; Declaration Brush private Thread Mthread; Declares a thread private static final int radius=10;//declares a sphere radius private static final int margin_top = 60; private static final int margin_left = 30; Private arraylist<int[][]> list=new arraylist<int[][]> (); PuBlic Countdownview (Context context) {super (context); Mholder = This.getholder (); Get Surfaceholder Object Mholder.addcallback (this); Add state listener Mpaint = new Paint (); Create a Brush object Mpaint.setcolor (Color.Blue); Sets the color of the Brush List.add (DATA0); List.add (DATA1); List.add (DATA2); List.add (DATA3); List.add (DATA4); List.add (DATA5); List.add (DATA6); List.add (DATA7); List.add (DATA8); List.add (DATA9); List.add (DATA10);} @Overridepublic void surfacechanged (Surfaceholder arg0, int arg1, int arg2, int arg3) {} @Overridepublic void Surfacecreate D (Surfaceholder arg0) {mthread = new Thread (this); Create thread Object Mthread.start ();} @Overridepublic void surfacedestroyed (Surfaceholder arg0) {} @Overridepublic void Run () {Try{mdraw ();} catch (Exception e) {log.e (TAG, "Run Error", E);}} /** * Custom Drawing method * 2014-12-19 pm 2:22:45 * */public void Mdraw () {Mcanvas = Mholder.lockcanvas (); Get the Canvas object and start painting the canvas mcanvas.drawcolor (color.black); Set the canvas color to black CANVAs (Mcanvas); Mholder.unlockcanvasandpost (Mcanvas); Display the canvas on the screen}public void canvas (canvas mcanvas) {//Draw circle, (x axis, Y axis, radius, brush) int hours=12; int minutes=36; int seconds=24; Canvasdigit (Margin_left, Margin_top, HOURS/10, Mcanvas); Canvasdigit (Margin_left + 15* (radius+1), Margin_top, hours%10, Mcanvas); Canvasdigit (Margin_left + 30* (RADIUS + 1), margin_top, Mcanvas); Canvasdigit (Margin_left + 39* (radius+1), Margin_top, MINUTES/10, Mcanvas); Canvasdigit (Margin_left + 54* (radius+1), Margin_top, minutes%10, Mcanvas); Canvasdigit (Margin_left + 69* (radius+1), Margin_top, Mcanvas); Canvasdigit (Margin_left + 78* (radius+1), Margin_top, SECONDS/10, Mcanvas); Canvasdigit (Margin_left + 93* (radius+1), Margin_top, seconds%10, Mcanvas);} public void canvasdigit (int x,int y,int Num,canvas mcanvas) {Int. [] data=list.get (num); for (int i=0;i<data.length;i+ +) {for (int J=0;j<data[i].length;j++) {if (data[i][j]==1) {mcanvas.drawcircle (x + j*2* (radius+1) + (radius+1), Y + i*2* (radius+1) + (radius+1), RADIUS, Mpaint); }}}}}
The key code is a formula for the intermediate interval between the time the circle is drawn
Mcanvas.drawcircle (x + j*2* (radius+1) + (radius+1), Y + i*2* (radius+1) + (radius+1), RADIUS, mpaint);
a picture is quoted here:
The picture is where the next circle is calculated.
And we're writing an activity to show the view we just wrote.
package Com.cayden.countdown;import Android.app.activity;import Android.os.bundle;import Android.view.Menu;import Android.view.window;import Android.view.windowmanager;import Com.cayden.countdown.view.countdownview;public Class Mainactivity extends Activity {@Overrideprotected void onCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Hides the status bar This.getwindow (). SetFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WINDOWMANAGER.LAYOUTP Arams. Flag_fullscreen); Remove Requestwindowfeature (Window.feature_no_title) from the title of the activity; Set the layout Setcontentview (new Countdownview (This));} @Overridepublic boolean Oncreateoptionsmenu (Menu menu) {//Inflate the menu; This adds items to the action bar if it is PR Esent.getmenuinflater (). Inflate (R.menu.main, menu); return true;}}
The last run effect is shown as the first picture.
Android countdown Electronic Clock Implementation (previous)