Android Development Learning Path-custom controls (Weather Trend line chart)

Source: Internet
Author: User
Tags drawtext

Previously wrote a weather app with 4-day forecasts and 5-day historical information. So want to add a line chart to show the weather trend, rare to have time, wrote a bit, here to do some records, the head is not easy to forget things.

Let's put the effect first:

Control content is relatively simple, is a normal line chart, the upper and lower respectively with the number, click on the time to display the difference in the temperature of the day.

Create a class that inherits from view and adds two construction methods:

 Public class extends View {    public  trendgraph (Context context) {//Creates a call        to Super in Java code ( context);    }      Public Trendgraph (Context context, AttributeSet attrs) {//create in XML        call Super(context, attrs);    }}

Because there is no need to consider the situation of wrap_content, so the Onmeasure method does not need to rewrite, the key is OnDraw, and OnDraw method is not difficult, only need to determine the specific location of each point is good, because the line is also needed to point the coordinates, the code is more verbose, Can skip:

1 @Override2     protected voidOnDraw (canvas canvas) {3         Super. OnDraw (canvas);4         if(Melements = =NULL|| Melements.size () = = 0) {5             return;6         }7         DoubleMAX_UP =getmaxup ();8         DoubleMin_down =Getmindown ();9 Canvas.setdrawfilter (mdrawfilter);Ten mpaint.setstrokewidth (lineweith); One         floatwidth =getwidth (); A         floatGrap = width/melements.size (); -         floatTextSize =mtextpaint.gettextsize (); -         intTextmargin = Circleradius * 2; the         floatMargin_top = textSize + 2 *Textmargin; -LOG.D (TAG, "OnDraw:" + margin_top + "|" +textSize); -         floatHeight = getheight ()-2 *Margin_top; -  +          for(inti = 0; I < Melements.size ()-1; i++) { -             floatStartX = i * grap + GRAP/2; +             floatSTOPX = (i + 1) * Grap + GRAP/2; A             floatStarty = (float) (Max_up-melements.get (i). GetUp ())/(float) (MAX_UP- atMin_down) * height +Margin_top; -             floatStopy = (float) (Max_up-melements.get (i + 1). GetUp ())/(float) (MAX_UP- -Min_down) * height +Margin_top; -  -Canvas.drawtext ((int) Melements.get (i). GetUp () + "℃", Startx-textsize, Starty- - Textmargin, mtextpaint); in canvas.drawcircle (StartX, Starty, Circleradius, mpaint); - canvas.drawline (StartX, Starty, Stopx, Stopy, mpaint); to             if(i = = Melements.size ()-2) { +Canvas.drawtext ((int) Melements.get (i + 1). GetUp () + "℃", stopx-textSize, Stopy --Textmargin, mtextpaint); the canvas.drawcircle (stopx, Stopy, Circleradius, mpaint); *             } $ Panax NotoginsengStarty = (float) (Max_up-melements.get (i). Getdown ())/(float) (Max_up-min_down) * -Height +Margin_top; theStopy = (float) (Max_up-melements.get (i + 1). Getdown ())/(float) (MAX_UP- +Min_down) * height +Margin_top; ACanvas.drawtext ((int) Melements.get (i). Getdown () + "℃", startx-textsize, Starty + theTextSize +Textmargin, mtextpaint); + canvas.drawcircle (StartX, Starty, Circleradius, mpaint); - canvas.drawline (StartX, Starty, Stopx, Stopy, mpaint); $             if(i = = Melements.size ()-2) { $Canvas.drawtext ((int) Melements.get (i + 1). Getdown () + "℃", stopx-TextSize, -Stopy + textSize +Textmargin, mtextpaint); - canvas.drawcircle (stopx, Stopy, Circleradius, mpaint); the             } -         }Wuyi}

Consider the need to allow users to make simple settings, such as point size, text size, and so on, so define some custom attributes (Res/values/attr.xml):

<?XML version= "1.0" encoding= "Utf-8"?><Resources>    <declare-styleablename= "Trendgraph">        <attrname= "LineWidth"format= "Dimension"/>        <attrname= "Circleradius"format= "Dimension" />        <attrname= "TextSize"format= "Dimension" />        <attrname= "TextColor"format= "Reference" />    </declare-styleable></Resources>

Format refers to the formatting of the property, which is specified as dimension, which is the size, the unit of value is DP, SP, or PX and so on, while reference is a reference, that is, a generic reference to other resources in XML, such as @string/app_name. There are other types of documents that you can find yourself.

To parse the custom attribute, this parsing needs to be done in the second constructed method defined above, with the following code:

     Public Trendgraph (Context context, AttributeSet attrs) {        Super(context, attrs);         = GetContext (). Obtainstyledattributes (Attrs, r.styleable.trendgraph);         = Array.getdimensionpixelsize (R.styleable.trendgraph_circleradius, 5);         = Array.getdimensionpixelsize (R.styleable.trendgraph_linewidth, 3);         ));        Mtextpaint.setcolor (Array.getcolor (R.styleable.trendgraph_textcolor, Color.Black));        Array.recycle ();    }

The Getdimensionpixelsize method is converted to a specific pixel (px) value by passing in the value, which eliminates the hassle of manual conversion. However, it is important to note that the DefaultValue is still px.

You can then specify these properties through XML, adding namespaces to the layout:

xmlns:app= "Http://schemas.android.com/apk/res-auto"

Then Android Studio will be introduced automatically, and can be complete, specific use:

    < com.fndroid.byweather.views.TrendGraph         Android:id = "@+id/tg"         android:layout_width= "Match_parent"        app:textcolor= "@color/ Coloraccent "        app:textsize=" 22SP "        app:circleradius=" 2DP "          android:layout_height= "200DP"/>

Finally, add an event listener to make a callback when clicking on the view:

① Defining interfaces:

     Public Interface onitemclicklistener{        void  onitemclick (view view, element Element);    }

② add an interface object to the view and set the setter method:

 Public class extends View {    private  onitemclicklistener monitemclicklistener;     // Omit code     Public void Setonitemclicklistener (Onitemclicklistener onitemclicklistener) {        = onitemclicklistener;    }} 

③ handle Ontouchevent, override the method, and the code is as follows:

@Override Public Booleanontouchevent (Motionevent event) {intViewwidth =getwidth (); intItemwidth = viewwidth/melements.size (); intViewheight =getheight (); BooleanIsmove =false;//The outermost layer in the interface is a nestedscrollview, so it is also triggered to avoid sliding, adding variable handlingSwitch(Event.getaction ()) { CaseMotionEvent.ACTION_MOVE:isMove=true;  Break;  Casemotionevent.action_up:if(!ismove) {//Judge callback only when clickedintPosition = (int) (Event.getx ()/itemwidth); Get the location of the click Monitemclicklistener.onitemclick ( This, Melements.get (position)); CALLBACK} Break; }        return true; }

④ in activity, listen to the settings and process:

Historygraph.setonitemclicklistener (this);
    @Override    publicvoid  onitemclick (view view, Trendgraph.element Element) {         int dt = (int) (Element.getup ()- element.getdown ());        " The difference of the day is: "+ dt +" ℃ ", Snackbar.length_short). Show    ();

The effect is complete! We welcome your attention to communication.

Android Development Learning Path-custom controls (Weather Trend line chart)

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.