Android custom View clock birth record

Source: Internet
Author: User
Tags drawtext

Many of the packages feel that custom view is a symbol of a master, not actually. People think that the custom view is difficult in many cases because the custom view involves too many classes and APIs to make people dizzy, so today we will start with the simplest drawing API, and take you step-by-step into customizing the view world.

Let's take a look at one we're going to implement today:

The whole effect is simple, is to display a clock on the screen, the clock can automatically move around.

OK, let's start the work.

1. Preparatory work

First of all, to implement this clock, I have to inherit from view to draw my own clock, because this effect has no way to inherit the existing controls to improve functionality. And then we'll see what variables we need here? In this blog I do not intend to introduce the custom properties and view measurement, here I just want to introduce the drawing API, so the size of the view and the color of the clock hands, etc. i will give a fixed value for the time being. OK, so the variables we need are mainly the following:

/**     * Draw the dial's brush */    private Paint circlepaint;    /**     * Draw dial number */    private Paint numpaint;    /**     * * Draw the table Heart */    private Paint dotpaint;    /**     * Hour     /    private Paint hourpaint;    /**     * Minute hand * */    private Paint minutepaint;    /**     * seconds * */    private Paint secondpaint;    /**     * View width, default 256DP     */    private int width;    /**     * View height, default 256DP */    private int height;    /**     * Calendar class, used to get the current time     */    private calendar calendar;    /**     * Current hour color */    private int hourcolor;    /**     * Current minute hand color */    private int minutecolor;    /**     * Current Second color */    private int secondcolor;    /**     * Hour width */    private int hourwidth;    /**     * Minute hand width */    private int minutewidth;    /**     * Second hand width */    private int secondwidth;

There are so many variables.

2. About the construction method

As you can see, when I inherit the view, the system asks me to implement its construction method, there are four main construction methods, as follows:

1.

Public Clockview (Context context)

The construction method is called when I am new to a view in the Java code.

2.

Public Clockview (context context, AttributeSet attrs)

The construction method is called when I add a view to the layout file.

3.

Public Clockview (context context, AttributeSet attrs, int defstyleattr)

Many packages see the third parameter after the defstyleattr, mistakenly think that if I write a style in the layout file will call the construction method, in fact, this construction method system does not call itself (everyone is interested to write a style, and then in this method to print the log, See if the method is going to be called or not, it's up to us to make an explicit call (which can be called in the second construction method). So what exactly does the defstyleattr mean here? As the literal meaning of this argument, it is a default style that we specify for a custom view. (We'll talk about this in more detail later in this blog).

In addition, there is a high version of the construction method used, we do not introduce here.

In general, we need to do some initialization in the construction method, such as reading the attributes defined in the XML file, or initializing the brush, and so on, because our controls are either instantiated through Java code or may be added through XML in the layout file. As mentioned earlier, if we initialize the control in Java code, the first constructor is called, and if we add the control to the XML layout file, then the second constructor method is called. Then the question comes, and the method of our initialization control should be written in that constructor method? You can write as follows:

    Public Clockview (Context context) {        super (context);        Initview ();    }    Public Clockview (context context, AttributeSet Attrs) {        super (context,attrs);        Initview ();    }

In the two constructor methods to call the initialization method, this way is not a problem, but it seems that your ideas are not organized, refer to the other controls provided by Android source code, I recommend the initialization of the control in the following way to write:

    Call Public    Clockview (context context) {This        (context, NULL) when creating a control in code);    }    Call public Clockview When creating view in Layout file    (context context, AttributeSet attrs) {This        (context, attrs, 0);    }    Public Clockview (context context, AttributeSet attrs, int defstyleattr) {        Super (context, attrs, defstyleattr);        Initview ();    }

Although the results are the same, but the following is the way you look at the idea is clear.

3. Initializing the control

We define many variables in the preparation, including the color of the clock, the color of the pointer, and so on, and then we need to initialize these variables in the Initview method for next use, OK, let's take a look at the initialization code:

    private void Initview () {//Gets an instance of the current time calendar = Calendar.getinstance (); Clock default width high width = (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Getresources (). getdisplaymetrics        ());        Height = (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, N, Getresources (). Getdisplaymetrics ());        Initializes the color of the needle hourcolor = color.red;        Minutecolor = Color.green;        Secondcolor = Color.Blue;        The width of the initial needle hourwidth = 8;        Minutewidth = 5;        Secondwidth = 2;        Initializes various brushes circlepaint = new paint ();        De-aliased Circlepaint.setantialias (true);        Sets the brush color Circlepaint.setcolor (color.green);        Sets the brush Style to stroke Circlepaint.setstyle (Paint.Style.STROKE);        Sets the width of the stroke circlepaint.setstrokewidth (6);        Dotpaint = new Paint ();        Dotpaint.setantialias (TRUE);        Dotpaint.setcolor (color.red);        Dotpaint.setstyle (Paint.Style.FILL); Numpaint =New Paint ();        Numpaint.setcolor (color.red);        Numpaint.setantialias (TRUE);        Text alignment numpaint.settextalign (Paint.Align.CENTER);        Hourpaint = new Paint ();        Hourpaint.setcolor (Hourcolor);        Hourpaint.setstyle (Paint.Style.FILL);        Hourpaint.setstrokewidth (Hourwidth);        Minutepaint = new Paint ();        Minutepaint.setcolor (Minutecolor);        Minutepaint.setstyle (Paint.Style.FILL);        Minutepaint.setstrokewidth (Minutewidth);        Secondpaint = new Paint ();        Secondpaint.setcolor (Secondcolor);        Secondpaint.setstyle (Paint.Style.FILL);    Secondpaint.setstrokewidth (Secondwidth); }

The first is to get an instance of the current time, because I need to based on the time on the phone to display the clock time, followed by the various properties of the needle and brush initialization, here is very simple, I will no longer one by one in detail, we look at the code comments, I believe you can understand.

4. Draw a Clock

When all of the above work is done, the next step is to draw the clock, to draw the work we put in the OnDraw method, in the custom control, if the control is we inherit from view to implement, then basically this control needs ourselves to draw.

OK, let's take a look at the clock drawing.

Clocks are not complicated, but we also need to step-by-step:

The first is to draw the dial, which is the simplest:

        1. Center x axis coordinates, 2. Center y coordinate, 3. Radius, 4. Brush        int radius = WIDTH/2-ten;        Draw the Dial        canvas.drawcircle (WIDTH/2, HEIGHT/2, radius, circlepaint);

RADIUS represents the radius of the dial, draws a circle through drawcircle, four parameters are the center point coordinates of the ring, the radius of the ring, and the brush that draws the circle.

After the circle has been painted, the next step is to draw the table heart, which is the red center of the dial.

Canvas.drawcircle (WIDTH/2, HEIGHT/2, Dotpaint);

It's simple.

OK, two The simplest of things after painting, then the next is to draw the time scale of the dial, the time scale of the plot in addition to the numbers, there is a green short-term, we have to draw 12 of this kind of thing, then how to draw it? There are many ideas, you can follow the mathematical knowledge of high school, calculate the coordinates of each number and the starting position of each short-term and the coordinates of the end position, and then draw out, no doubt, this way of calculation is too large, then we take a simple way: I am only at 12 points in the position of the drawing, If you need to draw a little, then I rotate the canvas counterclockwise 30 degrees to 12 points, then draw 1 and a short line and then rotate the canvas clockwise 30 degrees, if it is to draw 2 points, then I rotate the canvas counter-clockwise 60 degrees to 12 points, and then draw a 2 and a short line, Once the drawing is finished and the canvas is rotated 60 degrees clockwise, let's look at the code below:

        for (int i = 1; i < i++) {            //Save canvas State before rotation            canvas.save ();            Canvas.rotate (i *, WIDTH/2, HEIGHT/2);            1.2 represents the start coordinate, 3.4 represents the end coordinate, 5. Brush            canvas.drawline (WIDTH/2, HEIGHT/2-radius, WIDTH/2, HEIGHT/2-radius + ten, Circle Paint);            Draw the dial number 1. Text to be drawn, 2. Text x coordinate, 3. Text baseline, 4. Text Brush            canvas.drawtext (i + "", WIDTH/2, HEIGHT/2-radius +, numpaint);            Restore Canvas State            canvas.restore ();        }

I used a loop to draw these 12 ticks, and before each rotation of the canvas, I saved the current state of the canvas with a Canvas.save () method, and then rotated the canvas after the rotation, and it was simple to draw a line after the completion of the drawing. I need to call the canvas's Restore () method, which allows the canvas to revert to the angle before rotation. In general, it is important to note that the Canvas.save () method and the Canvas.restore () method are all paired up.

OK, after all these things have been drawn, the next step is to draw the hands, and the needle is drawn in the same way as above, rotating the dial first, then drawing the needle, and then circling the table back to the previous state. Here I will no longer elaborate, we look at the code:

        Get current hour        int hour = Calendar.get (calendar.hour);        Canvas.save ();        Rotating screen        canvas.rotate (hour *, WIDTH/2, HEIGHT/2);        Draw Hour        Canvas.drawline (WIDTH/2, HEIGHT/2 +, WIDTH/2, HEIGHT/2-All, hourpaint);        Canvas.restore ();        int minute = Calendar.get (Calendar.minute);        Canvas.save ();        Canvas.rotate (minute * 6, WIDTH/2, HEIGHT/2);        Canvas.drawline (WIDTH/2, HEIGHT/2 +, WIDTH/2, HEIGHT/2-A, minutepaint);        Canvas.restore ();        int second = Calendar.get (Calendar.second);        Canvas.save ();        Canvas.rotate (Second * 6, WIDTH/2, HEIGHT/2);        Canvas.drawline (WIDTH/2, HEIGHT/2 + +, WIDTH/2, HEIGHT/2-secondpaint);        Canvas.restore ();

OK, after all the things are done, we can add the following code to the layout file to see how our work Works:

    <org.mobiletrain.clockview.clockview        android:layout_width= "match_parent"        android:layout_height= " Match_parent "/>

After adding the finished, run, no accident, your app should have shown a clock, but the clock is still, then how can we let the clock move? In fact, we just need to retrieve the calendar instance every second, and then redraw the clock, so, at the beginning and end of the OnDraw method, we'll add the following two lines of code, respectively:

1. Add at Start:

Calendar = Calendar.getinstance ();

This line of code is used to get an instance of the latest time

2. Add at end:

postinvalidatedelayed (1000);

This line of code is used to redraw the clock, but the redraw is after 1 seconds.

OK, now that our custom clock is complete, the complete code should look like this:

/** * Created by Wangsong on 2016/3/29.    */public class Clockview extends View {/** * Draw a brush for the dial */private Paint circlepaint;    /** * Draw Dial number */private Paint numpaint;    /** * * Draw the table Heart */private Paint dotpaint;    /** * Hour/private Paint hourpaint;    /** * Minute hand * */private Paint minutepaint;    /** * seconds * */private Paint secondpaint;    /** * View width, default 256DP */private int width;    /** * View height, default 256DP */private int height;    /** * Calendar class, used to get the current time */private calendar calendar;    /** * Current Hour color */private int hourcolor;    /** * Current minute hand color */private int minutecolor;    /** * Current Second color */private int secondcolor;    /** * Hour width */private int hourwidth;    /** * Minute hand width */private int minutewidth;    /** * Second Hand width */private int secondwidth;    Call Public Clockview (context context) {This (context, NULL) when creating a control in code; }//In the layout file, create aCall public Clockview when building the view (context context, AttributeSet Attrs) {This (context, attrs, 0);         } public Clockview (context context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);    Initview ();        private void Initview () {//Gets an instance of the current time calendar = Calendar.getinstance (); Clock default width high width = (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, Getresources (). getdisplaymetrics        ());        Height = (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, N, Getresources (). Getdisplaymetrics ());        Initializes the color of the needle hourcolor = color.red;        Minutecolor = Color.green;        Secondcolor = Color.Blue;        The width of the initial needle hourwidth = 8;        Minutewidth = 5;        Secondwidth = 2;        Initializes various brushes circlepaint = new paint ();        De-aliased Circlepaint.setantialias (true);        Sets the brush color Circlepaint.setcolor (color.green); Set brush style to stroke circlepaint.seTstyle (Paint.Style.STROKE);        Sets the width of the stroke circlepaint.setstrokewidth (6);        Dotpaint = new Paint ();        Dotpaint.setantialias (TRUE);        Dotpaint.setcolor (color.red);        Dotpaint.setstyle (Paint.Style.FILL);        Numpaint = new Paint ();        Numpaint.setcolor (color.red);        Numpaint.setantialias (TRUE);        Text alignment numpaint.settextalign (Paint.Align.CENTER);        Hourpaint = new Paint ();        Hourpaint.setcolor (Hourcolor);        Hourpaint.setstyle (Paint.Style.FILL);        Hourpaint.setstrokewidth (Hourwidth);        Minutepaint = new Paint ();        Minutepaint.setcolor (Minutecolor);        Minutepaint.setstyle (Paint.Style.FILL);        Minutepaint.setstrokewidth (Minutewidth);        Secondpaint = new Paint ();        Secondpaint.setcolor (Secondcolor);        Secondpaint.setstyle (Paint.Style.FILL);    Secondpaint.setstrokewidth (Secondwidth); }//Draw view @Override protected void OnDraw (canvas canvas) {calendar = Calendar. getinstance ();        1. Center x axis coordinates, 2. Center y coordinate, 3. Radius, 4. Brush int radius = WIDTH/2-10;        Draw the Dial canvas.drawcircle (WIDTH/2, HEIGHT/2, radius, circlepaint);        Canvas.drawcircle (WIDTH/2, HEIGHT/2, Dotpaint);            for (int i = 1; i < i++) {//Save canvas State before rotation canvas.save ();            Canvas.rotate (i *, WIDTH/2, HEIGHT/2);  1.2 represents the start coordinate, 3.4 represents the end coordinate, 5. Brush Canvas.drawline (WIDTH/2, HEIGHT/2-radius, WIDTH/2, HEIGHT/2-radius + 10,            Circlepaint);            Draw the dial number 1. Text to be drawn, 2. Text x coordinate, 3. Text baseline, 4. Text Brush Canvas.drawtext (i + "", WIDTH/2, HEIGHT/2-radius +, numpaint);        Restore Canvas State canvas.restore ();        }//get current hour int hour = Calendar.get (Calendar.hour);        Canvas.save ();        Rotating screen canvas.rotate (hour *, WIDTH/2, HEIGHT/2);        Draw Hour Canvas.drawline (WIDTH/2, HEIGHT/2 +, WIDTH/2, HEIGHT/2-All, hourpaint); Canvas.restOre ();        int minute = Calendar.get (Calendar.minute);        Canvas.save ();        Canvas.rotate (minute * 6, WIDTH/2, HEIGHT/2);        Canvas.drawline (WIDTH/2, HEIGHT/2 +, WIDTH/2, HEIGHT/2-A, minutepaint);        Canvas.restore ();        int second = Calendar.get (Calendar.second);        Canvas.save ();        Canvas.rotate (Second * 6, WIDTH/2, HEIGHT/2);        Canvas.drawline (WIDTH/2, HEIGHT/2 + +, WIDTH/2, HEIGHT/2-secondpaint);        Canvas.restore ();    Redraw the view every 1 seconds, redraw calls the OnDraw () method postinvalidatedelayed (1000); }}

Above.

Android custom View clock birth record

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.