Android Custom view4--Chart view

Source: Internet
Author: User

1. Introduction

Weekend in the network, saw a study plan report chart, detailed records of their own week of study, every day is 0 lessons Ah! Just learning the Android custom view, so think of yourself to write a, here first give a picture of the Nets, and their own.

Yissan's blog, without permission is strictly prohibited reprint Http://blog.csdn.net/yissan

2. Realization Analysis

We want to implement such a line chart, the necessary information is mainly the following several

Look at the vertical axis, the vertical axis needs the maximum value of information, but also useful to determine the unit each spacing represents, such as the maximum value is 100, we also have a value divided into several data.

Next look at the horizontal axis, because the horizontal axis of information is generally text, not like the number can be obtained by accumulating, so directly save a string array variable.

Then it's the polyline, and the polyline only needs to determine the y-coordinate of the vertical axis of each axis, and then it's OK to connect it, just to get the specific coordinates of y based on the spacing of the units on the left and the values of each unit.

Then you need to sum up:
1, longitudinal axis maximum value
2, longitudinal axis Division number
3. The value of each small unit in the longitudinal axis is calculated by the maximum/split quantity
4. Arrays for horizontal display
5, horizontal, longitudinal axis spacing
6, specific array (used to draw the polyline)

With the information above you can go to draw, the following to start the specific custom view steps to explain

3. Concrete Realization

In the previous article, I wrote an article that introduced a custom step--Learning Android custom Control 1 together, and we followed this step to explain.

(1) CREATE view

Primarily determines whether the inherited view is a specific view, defines and gets properties, and adds a set property method.

Defining properties

<?xml version= "1.0" encoding= "Utf-8"?><resources>    <declare-styleable name="Statisticsview">        <attr name="MaxValue" format="integer"></attr>        <attr name="Dividercount" format="integer"> </attr>        <attr name="title" format="integer"></attr>        <attr name="LineColor" format="Color"></attr>        <attr name="TextColor" format="Color"></attr>        <attr name="Pathcolor" format="Color"></attr>    </declare-styleable></Resources>

Getting properties in a construction method

 Public  class statisticsview extends View {    //Draw horizontal longitudinal axis    PrivatePaint Mborderpaint;//Draw the center of the coordinate point    PrivatePaint Circlepaint;//Draw a line chart    PrivatePaint Mpathpaint;PrivatePath MPath;//longitudinal axis maximum value    Private intMaxValue = -;//longitudinal axis split quantity    Private intDividercount =Ten;PrivateString title ="7th Learning Situation (Unit section)";//Vertical axis per unit value    Private intPervalue = Maxvalue/dividercount;//Bottom display string    PrivateString[] bottomstr = {};//Specific values    Private float[] values = {};//Bottom horizontal Unit spacing    Private floatBottomgap;//Left longitudinal axis spacing    Private floatLeftgap;PrivateTextpaint Textpaint; Public void setvalues(float[] values) { This. values = values;    Invalidate (); } Public void Setbottomstr(string[] bottomstr) { This. bottomstr = Bottomstr;    Requestlayout (); } Public Statisticsview(Context context) {Super(context); } Public Statisticsview(context context, AttributeSet attrs) { This(Context, Attrs,0); } Public Statisticsview(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr);        TypedArray array = context.obtainstyledattributes (Attrs, R.styleable.statisticsview); MaxValue =array.getint (R.styleable.statisticsview_maxvalue, -); Dividercount = Array.getint (R.styleable.statisticsview_dividercount,Ten); title = Array.getstring (R.styleable.statisticsview_title);intLineColor = Array.getcolor (R.styleable.statisticsview_linecolor,color.black);intTextColor =array.getcolor (R.styleable.statisticsview_textcolor,color.black); Mborderpaint =NewPaint (); Circlepaint =NewPaint (); Mpathpaint =NewPaint (); Mborderpaint.setantialias (true);        Mborderpaint.setcolor (LineColor); Mborderpaint.setstrokewidth (1);        Mborderpaint.setstyle (Paint.Style.STROKE); Mpathpaint.setantialias (true);        Mpathpaint.setstyle (Paint.Style.STROKE); Mpathpaint.setstrokewidth (3); Textpaint =NewTextpaint ();        Textpaint.setcolor (TextColor); Textpaint.settextsize (dip2px (GetContext (), A)); MPath =NewPath ();        Circlepaint.setstyle (Paint.Style.FILL); Circlepaint.setantialias (true);    Array.recycle (); }}

The above code simply gets the properties and initializes some information. At the same time, the method of setting values is provided externally.

(2) handling the layout of the view

The first consideration in handling layouts is to override the Onmeasure method as needed. Here, for the sake of simplicity, direct wrap_content is equal to the direct width and height of the case. Of course you can also have a property representing the width of each pitch, and then calculate the width height under wrap_content.

 @Override    protected void onmeasure(intWidthmeasurespec,intHEIGHTMEASURESPEC) {intWidthmode = Measurespec.getmode (Widthmeasurespec);intWidthsize = Measurespec.getsize (Widthmeasurespec);intHeightmode = Measurespec.getmode (Heightmeasurespec);intHeightsize = Measurespec.getsize (Heightmeasurespec);if(widthmode==measurespec.exactly&&heightmode==measurespec.exactly)        {setmeasureddimension (widthsize,heightsize); }Else if(widthmeasurespec==measurespec.exactly)        {setmeasureddimension (widthsize,widthsize); }Else if(heightmeasurespec==measurespec.exactly)        {setmeasureddimension (heightsize,heightsize); }    }

Since it is necessary to determine the unit spacing of the horizontal axis at draw, we need to get it, generally we get the value can be obtained in the Onsizechange method, but because the gap at the bottom of our base needs to be displayed according to several to determine. But it only started when bottomstr[] has a length of 0, and then the set method for the BOTTOMSTR setting does not call Onsizechange again. Bottomgap will be the first value, so the effect will be problematic, so it is taken in the OnLayout method.

    @Override    protectedvoidonLayout(booleanintintintint bottom) {        bottomGap = getWidth()/(bottomStr.length+1);        leftGap = getHeight()/(dividerCount+2);        super.onLayout(changed, left, top, right, bottom);    }
(3), Draw view (draw)

Next, you can implement OnDraw () to draw the view

@Override    protected void OnDraw(Canvas canvas) {Super. OnDraw (canvas);if(bottomstr==NULL|| bottomstr.length==0){return; }//Draw the left lineCanvas.drawline (Bottomgap,getheight ()-leftgap,bottomgap,leftgap,mborderpaint);floatFontheight = (Textpaint.getfontmetrics (). Descent-textpaint.getfontmetrics (). Ascent);//Draw down the edgeCanvas.drawline (Bottomgap,getheight ()-leftgap,getwidth ()-bottomgap,getheight ()-leftgap,mborderpaint); for(inti =1; i<=bottomstr.length;i++) {canvas.drawcircle (I*bottomgap,getheight ()-leftgap,6, Circlepaint); Canvas.drawtext (bottomstr[i-1],i*bottomgap-(Textpaint.measuretext (bottomstr[i-1])/2), GetHeight ()-leftgap/2+fontheight/2, Textpaint); } canvas.drawtext (title,bottomgap,leftgap/2, Textpaint); for(inti =1; i<=dividercount+1; i++) {//Draw the left wordCanvas.drawtext (pervalue* (i-1)+"", bottomgap/2-(Textpaint.measuretext (pervalue* (i-1)+"")/2), (((dividercount+2-i)) *leftgap+fontheight/2, Textpaint);//Draw horizontal LineCanvas.drawline (Bottomgap,getheight ()-((i) *leftgap), getwidth ()-bottomgap,getheight ()-((i) *leftgap),        Mborderpaint); }/** * Plot trajectory * Y coordinate point according to Y/LEFTGAP = values[i]/pervalue calculation * */         for(inti =0; i<values.length;i++) {if(i==0) {Mpath.moveto (Bottomgap, dividercount+1) *leftgap-(Values[i]*leftgap/pervalue)); }Else{Mpath.lineto (i+1) *bottomgap, (dividercount+1) *leftgap-(Values[i]*leftgap/pervalue)); }/** * Draw Trajectory dots * /Canvas.drawcircle ((i+1) *bottomgap, (dividercount+1) *leftgap-(Values[i]*leftgap/pervalue),6, Circlepaint);    } canvas.drawpath (Mpath,mpathpaint); } Public Static int dip2px(Context context,floatDpvalue) {Final floatScale = Context.getresources (). Getdisplaymetrics (). density;return(int) (Dpvalue * scale +0.5f); }

The code is annotated, mostly with calculations, Drawline,drawpath,drawtext, and some knowledge of the text width.

Yissan's blog, without permission is strictly prohibited reprint Http://blog.csdn.net/yissan

4. Use

Declare the view, then get the view in the activity and call the Setbottomstr and Setvalues methods

<com  .qiangyu  .test   . Statisticsview  .view   android:id= "@+id/statisticsview"  android:layout_width        = "match_parent"  android:layout_height= "300DP"  App:viewtitle=/>  
publicvoid invalidate(View view) {        this.view.setBottomStr(new String[]{"星期一","星期二","星期三","星期四","星期五","星期六","星期天"});        this.view.setValues(newfloat[]{10f,90f,33f,66f,42f,99f,0f});    }

Another one.

5. Summary

Custom view is more practice, see a favorite effect, do not want to be able to draw one of their own, a long time, I believe we can easily write a good custom view

Because the work is a little busy recently, so many places are imperfect. Here to share, I hope you like.

Android Custom view4--Chart view

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.