Basic knowledge and steps for customizing view

Source: Internet
Author: User
Tags drawtext

When I first started using native controls for Android, I was beginning to feel that native controls could actually meet some of the school's small project developments, and it didn't go deep into customizing the view. But after taking part in the work, I found that sometimes the design drawings given by some of the functions of the implementation is very tricky, so began to customize the view of the study. Maybe a lot of people think that customizing view is a difficult thing, but when you really try to get a few custom view, you will find that it is not that difficult. As a result of personal productivity or pretty fast, the project after a busy egg pain, often see those fun things on their own custom view to draw down.

The basic steps for customizing view are just a few steps:

1. Create the Attrs.xml file under the Values folder and add the attributes you want to add to your view in Attrs. Cases:

Attrs.xml

<?xml version= "1.0" encoding= "Utf-8"?><resources> <declare-styleable    name= "Mytextview" >        <attr name= "text" format= "string"/>        <attr name= "textSize" format= "Dimension"/>    </ Declare-styleable></resources>
Declare-styleable is a set of new defined properties for your custom view, which contains the various properties you want to define attr

Format is the unit that specifies the Attr property, which includes:

(1) Reference: Reference to a resource, such as: src= "@drawable/sourcename";

(2) Color: colors, such as color= "#ff0000";

(3) Boolean: Boolean value, True or false;

(4) Dimension: dimension value, such as sp,dp,px;

(5) Float: Floating point type, that is, decimal, such as 0.5, 1.8;

(6) Integer: Plastic, such as 1, 100;

(7) String: string

(8) Fraction: percentages, such as 100%

(9) Enum: enumeration, such as orientation= "vertical"

Flag: bits or operations, such as gravity= "Centerhorizontal | Right

A detailed format for format can refer to this


2. Create the class file, add the constructor, get the property, and initialize the variable. Cases:

public class Mytextview extends View {private String text;private int textsize;private Paint Paint;public Mytextview (context context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, defstyleattr );//TODO auto-generated constructor stub//as the name implies, get the style and attributes, get an array of arrays containing various attributes, including your custom attr attributes// R.styleable.mytextview is a idtypedarray array=context.obtainstyledattributes (Attrs, which points to the array of properties you have just customized in Attrs.xml. R.styleable.mytextview);//Get text content text=array.getstring (r.styleable.mytextview_text);//Get text font size, the second parameter is the default value, The sp2px () is the SP to PX function when you do not use the supplied value when you define the attribute. Textsize=array.getdimensionpixelsize (R.styleable.mytextview_textsize, sp2px (18));//This thing must be recycled after initialization is complete array.recycle () ;//brush initialization, for the subsequent drawing; paint=new paint ();//To this end, the initialization of the variable is}public mytextview (context context, AttributeSet Attrs) {This ( Context, attrs, 0);//TODO auto-generated constructor stub//If you use XML to load a view, you must override the above or the constructor}public Mytextview (context Context) {This (context, null);//TODO Auto-generated constructor stub//Unified to the first constructor for initialization}} 

3. Rewrite the Onmeasure (), and measure the view to determine the size of the view. (This step is not a necessary step for customizing the view, but can be adapted to the wrap_content parameter, etc.)

This step is not necessary, can be skipped, but when you set Layout_width and Layout_height can only set match_parent or specify the value, otherwise set wrap_content will be very awkward.

@Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//TODO auto-generated method stub// The Widthmeasurespec parameter can be parsed by the static method of the Measurespec class for the mode and value of the width calculation//mode has at_most, exactly, Unspecifiedint width=measureviewwidth ( WIDTHMEASURESPEC);//calculate height, and width handle almost int height=measureviewheight (HEIGHTMEASURESPEC); Setmeasureddimension (width, height);} Handles the width of the view private int measureviewwidth (int widthspec) {int result=0;int mode=measurespec.getmode (widthspec); int Width=measurespec.getsize (WIDTHSPEC);//corresponds to Wrap_content, ViewGroup only provides a maximum value, sub-view size cannot exceed this value//in this case, You can set the size of the view based on the content size, such as the width of the width=text of the View if (mode==measurespec.at_most) {int textwidth=measuretextwidth (); result= Math.min (textWidth, width);} Corresponds to match_parent or the specified value, VIEWGOURP provides the width of the parent or the specified width if (mode==measurespec.exactly) {result=width;} return result;} Handles the height of the view private int measureviewheight (int heightspec) {int result=0;int mode=measurespec.getmode (heightspec); int Height=measurespec.getsize (HEIGHTSPEC); if (mode==measurespec.at_most) {int Textheight=meaSuretextheight (); Result=math.min (textHeight, height);} if (mode==measurespec.exactly) {result=height;} return result;} Measure the width of the text private int measuretextwidth () {int textwidth= (int) paint.measuretext (text); return textWidth;} Measure the height of text private int measuretextheight () {fontmetrics fm=paint.getfontmetrics (); int textheight= (int) ( Fm.bottom-fm.top); return textHeight;}

Widthmeasurespec and Heightmeasurespec Two values are viewgroup passed to the child view, through the resolution of measurespec and then calculate the final value according to the mode, if WRAP_ Content calculates the size of the view content and then calculates the size of the view, if Match_parent or the specified value, then directly uses the value passed by the ViewGroup, after processing, Finally, call Setmeasureddimension to determine the final dimension of the view.

The size of the view is set to Wrap_content, and the left side is not rewritten onmeasure,viewgroup the maximum size that a parent component can assign to a child view, so the child view size is as large as the parent container. , and the right side overrides the Onmeasure, because the child view size is equal to the text content size, so the size is only text size.


4. Rewrite OnDraw () to draw what you want on a blank view, this step is the most important. Such as:

@Overrideprotected void OnDraw (canvas canvas) {//TODO auto-generated method stub//paints the background of the view as a yellow canvas.drawcolor ( Color.yellow);//measure the height of the drawing font FontMetrics fm=paint.getfontmetrics (); int textheight= (int) (fm.bottom-fm.top);// Parameter 1. The text to be drawn, 2. The left side of the text is in the X coordinate of the view, 3. The text baseline is located in the y-coordinate of the view, 4. Brush//Because the distance baseline to the bottom of the text cannot be obtained, only the text height of the 3/10canvas.drawtext ( Text, 0, textheight-textheight*0.3f, paint);}

The canvas class encapsulates a whole bunch of drawing tools, so drawing is not a very difficult thing to do, but to achieve a more complex diagram, you need to know a bit more about geometry computing, which simply draws the text up.

There is the text of the height of the processing can not understand Baidu Search Android baseline or Android measurement font height.


5. Use in the layout file, remember to add the space used by the property, that is, the top xmlns=xxxxxx, that a string of things.

Activity_main.xml

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"    xmlns:custom= "http// Schemas.android.com/apk/res/com.example.test "    android:id=" @+id/layout "    android:layout_width=" Match_ Parent "    android:layout_height=" match_parent "    android:orientation=" vertical ">      < Com.example.test.MyTextView        android:layout_width= "wrap_content"       android:layout_height= "Wrap_content"       custom:text= "AAAAAAAAAAAGGGGGGGGGGGGGGGG"       custom:textsize= "18SP"/></linearlayout>

The following custom property namespace must be added with xmlns:custom= "http://schemas.android.com/apk/res/com.example.test" to use

Format: xmlns: Defines the namespace name = "Http://schemas.android.com/apk/res/the package name in Androidmanifest."

At this point, a simple custom view is implemented, it looks like a lot of code, but actually to write it down, it feels like the custom view is just that. Of course, simple view as long as the implementation of the above steps, the basic can meet the need, if you want to achieve gorgeous effect, only the above steps are not enough, but also to re-ontouchevent such functions, so that view can handle touch events to achieve interactive effect.

The complete code is posted below:

Mytextview.java

public class Mytextview extends View {private String text;private int textsize;private Paint paint;public mytextview (Conte  XT context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);//TODO Auto-generated constructor stub//as the name implies, get the style and attributes, get an array of arrays containing various attributes, including your custom attr properties// R.styleable.mytextview is a idtypedarray array=context.obtainstyledattributes (Attrs, which points to the array of properties you have just customized in Attrs.xml. R.styleable.mytextview);//Get text content text=array.getstring (r.styleable.mytextview_text);//Get text font size, the second parameter is the default value, The sp2px () is the SP to PX function when you do not use the supplied value when you define the attribute. Textsize=array.getdimensionpixelsize (R.styleable.mytextview_textsize, sp2px (18));//This thing must be recycled after initialization is complete array.recycle () ;//brush initialization, for the subsequent drawing; paint=new paint ();//To this end, the initialization of the variable paint.settextsize (textSize);} Public Mytextview (context context, AttributeSet Attrs) {This (context, attrs, 0);//TODO auto-generated constructor stub// If you use XML to load a view, you must override the above or the struct}public Mytextview (context context) {This (context, null);//TODO Auto-generated constructor stub//Unified to the first constructor for initialization} @Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {//TODO auto-generated method stub// The Widthmeasurespec parameter can be parsed by the static method of the Measurespec class for the mode and value of the width calculation//mode has at_most, exactly, Unspecifiedint width=measureviewwidth ( WIDTHMEASURESPEC);//calculate height, and width handle almost int height=measureviewheight (HEIGHTMEASURESPEC); Setmeasureddimension (width, height);} Handles the width of the view private int measureviewwidth (int widthspec) {int result=0;int mode=measurespec.getmode (widthspec); int Width=measurespec.getsize (WIDTHSPEC);//corresponds to Wrap_content, ViewGroup only provides a maximum value, sub-view size cannot exceed this value//in this case, You can set the size of the view based on the content size, such as the width of the width=text of the View if (mode==measurespec.at_most) {int textwidth=measuretextwidth (); result= Math.min (textWidth, width);} Corresponds to match_parent or the specified value, VIEWGOURP provides the width of the parent or the specified width if (mode==measurespec.exactly) {result=width;} return result;} Handles the height of the view private int measureviewheight (int heightspec) {int result=0;int mode=measurespec.getmode (heightspec); int Height=measurespec.getsize (HEIGHTSPEC); if (mode==measurespec.at_most) {int Textheight=measuretextheiGht (); Result=math.min (textHeight, height);} if (mode==measurespec.exactly) {result=height;} return result;} Measure the width of the text private int measuretextwidth () {int textwidth= (int) paint.measuretext (text); return textWidth;} Measure the height of text private int measuretextheight () {fontmetrics fm=paint.getfontmetrics (); int textheight= (int) ( Fm.bottom-fm.top); return textHeight;} @Overrideprotected void OnDraw (canvas canvas) {//TODO auto-generated method stub//paints the background of the view as a yellow canvas.drawcolor ( Color.yellow);//measure the height of the drawing font FontMetrics fm=paint.getfontmetrics (); int textheight= (int) (fm.bottom-fm.top);// Parameter 1. The text to be drawn, 2. The left side of the text is in the X coordinate of the view, 3. The text baseline is located in the y-coordinate of the view, 4. Brush//Because the distance baseline to the bottom of the text cannot be obtained, only the text height of the 3/10canvas.drawtext ( Text, 0, textheight-textheight*0.3f, paint);} SP turn px Unit private int sp2px (int sp) {return (int) typedvalue.applydimension (typedvalue.complex_unit_sp, SP, Getresources (). Getdisplaymetrics ());}}

Layout file is simply not affixed, Attrs file is also very simple, on the above.




Basic knowledge and steps for customizing view

Related Article

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.