Android Custom View

Source: Internet
Author: User
Tags getcolor naming convention

Objective:

Although Android has provided us with a rich set of controls, such as Button,imageview,textview,edittext and many other controls, there are times when you need developers to customize some of the controls that need to be reused during project development. Making it easy to use like any other control provided by Android, fortunately Android has removed the barriers to our custom control process, provided a set of basic classes (such as View,canvas, etc.) and XML tags (such as the Resources tab that will be mentioned below). Declare-styleable labels, attr labels, etc.);

To create a process:

One, create a new XML file named "Attrs" in the Value folder:

Take a look at the Attrs.xml file in this example

Attrs.xml file:

1 <?xml version= "1.0" encoding= "Utf-8"? >2 <resources>3     <declare-styleable name= "CustomView" >4         <attr name= "textstring"  format= "string" ></attr>5 <attr         name= "ColorValue" format= " Color "></attr>6         <attr name=" textSize "format =" Dimension "></attr>7     </ Declare-styleable>8 </resources>

In the Attrs.xml file, the outer layer introduces the following tags:

<declare-styleable name= "CustomView" >

This tag is to let our custom view, have its own properties, from the above code, we can see that the tag contains a definition of three attributes, respectively named: "TextString", "ColorValue", "TextSize", This allows us to easily use these properties of the view, as we set the properties of the TextView Textsize,textcolor in the layout file when using the system-supplied TextView.

We named declare-styleable the Name field "CustomView" because we will name the custom view "CustomView" below, Why does Declare-styleable's name have to be the same as the name of our custom view? Flip through Google Docs and find explanations:

The name of the styleable entity is, by convention, the same name as the name of the class that defines the custom view.  Although it ' s not strictly necessary to follow this convention, many popular code editors depend on this naming convention To provide statement completion.

The outer declare-styleable tag is analyzed here, let's take a closer look at the attr tag:

<attr name= "TextString"  format= "string" ></attr><attr name= "colorvalue" format= "Color" ></ Attr>
<attr name= "textSize" format = "Dimension" ></attr>

In this example, a custom view has three properties, TextString: The text content of the view display, ColorValue: The color of the font, TextSize: The size of the font. The attr tag has not only the name field, but also the format field (what are the values for the Format field, in the appendix we give its specific definition and application examples)

Second, write the layout file, referencing the custom view

<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "    xmlns:app=" http://schemas.android.com/apk/res/com.project.summary "    android:layout_width=" Match_parent "    android:layout_height=" match_parent "    android:orientation=" vertical "     android: background= "@color/bgcolor" >    <com.project.summary.customview.customview        android:id= "@+id/ CustomView "        android:layout_width=" wrap_content "        android:layout_height=" Wrap_content "        app: Colorvalue= "@color/textred"        app:textstring= "this Custom View!!!"        App:textsize= "20SP"        /></linearlayout>

Here are two places to note:

1, new layout file namespace

Because we have customized the view and customized the properties, these properties are no longer part of the

Http://schemas.android.com/apk/res/android

This namespace, but belongs to

Http://schemas.android.com/apk/res/[your Package name].

So we need to increase the namespace in the layout file and change it to

xmlns:app= "Http://schemas.android.com/apk/res/com.project.summary"

2, customizing the View reference in the layout file

<com.project.summary.customview.customview

We need to write the package name of this custom class complete;

Also: If the CustomView class is the inner class of the Parentcustomview class, then the reference in the layout file should be written as

<com.project.summary.customview.parentcustomview$customview

That is, you need to increment the characters between classes and

3, custom attributes are referenced in the layout file

        App:colorvalue= "@color/textred"        app:textstring= "this Custom View!!!"        App:textsize= "20SP"

You need to precede the custom attribute with the App field (because app= "http://schemas.android.com/apk/res/com.project.summary", where the app refers to the new namespace).

Third, write your custom view code

Google Docs requires that the custom view be constructed with at least the context and AttributeSet parameters for two reasons:

1.
To allow the Android Developer Tools to interact with your view, at a minimum you must provide a constructor that takes a Context and an AttributeSet object as parameters. This constructor allows the layout editor to create and edit an instance of your view.
2.
When a view was created from an XML layout, all of the attributes in the XML tag was read from the resource bundle and pass Ed into the view ' s constructor as an attributeset. Although it ' s possible to read values from the AttributeSet directly, doing so have some disadvantages:a:resource reference s within attribute values is not resolved; B:styles is not applied;instead, pass the AttributeSet to Obtainstyledattributes (). This method passes the TypedArray array of values that has already been dereferenced and styled. The Android Resource compiler does a lot of work for your make calling obtainstyledattributes () easier. For each <declare-styleable> resource in the Res directory, the generated R.java defines both an array of attribute IDs and a set of constants that define the index for each attribute in the array. The predefined constants to read the attributes from the TypedArray.

The first reason: in order for our development tool layout editor to create and edit our own custom view;

The second reason: This is also the main reason, when we create the view from the layout file, all the tags in the layout file, all the attributes in the tag are read into the resource bundle, and the resource bundle is packaged into a property set AttributeSet passed to the custom view construction method;

In the construction method, the Obtainstyledattributes () method is used to convert these properties into an Typedarray array containing our custom property IDs and constant collections, so that We can easily read our defined properties from Typedarray with the constant name we define.

So we'll at least write a constructor that includes context and attributeset as arguments

1 public class CustomView extends View {2     private int color; 3     private String mText; 4     private int textSize; 5  6 Public     CustomView (context context, AttributeSet Attrs) {7         super (context, attrs); 8         TypedArray a = Co Ntext.obtainstyledattributes (attrs, 9                 r.styleable.customview);         try {one             MText = a.getstring ( r.styleable.customview_textstring);             color = A.getcolor (r.styleable.customview_colorvalue,13                     r.color.textred);             textSize = A.getdimensionpixeloffset (                     r.styleable.customview_textsize, 20); 16         } finally {             a.recycle ();         }19     }

As can be seen from the code, we can use the relevant methods provided by Typedarray to take out the related properties we set in the layout file, we also need to pay attention to Typedarray recycling!

Four, in this case, we have customized a view to implement the display text, similar to the TextView

Since this article only describes how to customize the view and its use, the functional part of the custom view is not in the scope of this article and will be described in the next article, so the following code is not specifically described.

public class CustomView extends View {private int color;    Private Paint Mtextpaint;    Private String MText;    private int textSize;    private int mascent;        Public CustomView (context context, AttributeSet Attrs) {Super (context, attrs);        Initlabelview ();        TypedArray a = Context.obtainstyledattributes (Attrs, R.styleable.customview);            try {mText = a.getstring (r.styleable.customview_textstring);            color = A.getcolor (R.styleable.customview_colorvalue, r.color.textred);            if (mText! = null) {Setcustomtext (mText);            } settextcolor (color);            TextSize = A.getdimensionpixeloffset (r.styleable.customview_textsize, 20);            if (TextSize > 0) {settextsize (textSize);        }} finally {a.recycle ();  }}/** * Sets the text to display in this label * * @param text   * The text to display.     This is drawn as one line.        */private void Setcustomtext (String text) {//TODO auto-generated method Stub mText = text;        Requestlayout ();    Invalidate ();        Private final void Initlabelview () {mtextpaint = new Paint ();        Mtextpaint.setantialias (TRUE); Must manually scale the desired text size to match screen density mtextpaint.settextsize (* getresources (). Get        Displaymetrics (). density);        Mtextpaint.setcolor (0xff000000);    Setpadding (3, 3, 3, 3); } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {setmeasureddimension (meas    Urewidth (Widthmeasurespec), Measureheight (Heightmeasurespec)); }/** * Determines the width of this view * * @param measurespec * A measurespec packed int o an int * @return The width of the view, honoring constraints from Measurespec */private int measurewidth (int measurespec) {int result = 0;        int specmode = Measurespec.getmode (Measurespec);        int specsize = measurespec.getsize (Measurespec);        if (Specmode = = measurespec.exactly) {//We were told how big to be result = specsize;                    } else {//Measure the text result = (int) mtextpaint.measuretext (mText) + getpaddingleft ()            + Getpaddingright ();                if (Specmode = = Measurespec.at_most) {//Respect At_most value if that's what's called for by            Measurespec result = Math.min (result, specsize);    }} return result; }/** * Determines the height of this view * * @param measurespec * A Measurespec packed in to a int * @return The height of the view, honoring constraints from MEASURESPEC */private int measureheight (        int measurespec) {int result = 0; InchT specmode = Measurespec.getmode (Measurespec);        int specsize = measurespec.getsize (Measurespec);        mascent = (int) mtextpaint.ascent ();        if (Specmode = = measurespec.exactly) {//We were told how big to be result = specsize; } else {//Measure the text (beware:ascent is a negative number) result = (int) (-mascent + MTEXTP            Aint.descent ()) + getpaddingtop () + Getpaddingbottom ();                if (Specmode = = Measurespec.at_most) {//Respect At_most value if that's what's called for by            Measurespec result = Math.min (result, specsize);    }} return result;  }/** * Sets the text size for this label * * @param size * Font size */public void        settextsize (int size) {//This text size have been pre-scaled by the Getdimensionpixeloffset//method   Mtextpaint.settextsize (size);     Requestlayout ();    Invalidate ();     }/** * Sets the text color for this label. * * @param color * ARGB value for the text */public void SetTextColor (int color) {Mtex        Tpaint.setcolor (color);    Invalidate ();    /** * Render The text * * @see Android.view.view#ondraw (android.graphics.Canvas) */@Override        protected void OnDraw (canvas canvas) {super.ondraw (canvas);    Canvas.drawtext (MText, Getpaddingleft (), Getpaddingtop ()-mascent, Mtextpaint); }//@Override//protected void Onmeasure (final int widthmeasurespec,//FINAL int heightmeasurespec) {//In    T width = measurespec.getsize (widthmeasurespec);    int height = (int) (width * heightscale/widthscale);    int height = measurespec.getsize (heightmeasurespec);    if (height = = 0) {//Super.onmeasure (Widthmeasurespec, Heightmeasurespec); } else {//Super.onmeasure (//MeasurespeC.makemeasurespec (width, measurespec.exactly),//Measurespec.makemeasurespec (height, measurespec.exactly)); // }    // }}

Appendix: Definition of format and application examples:

1. Reference: Resource reference.

Property Definition:

<attr name = "Background" format = "Reference"/>

Properties using:

<com.lin.gw.customview   android:layout_width = "42dip"   android:layout_height = "42dip"   app: Background = "@drawable/Picture id"/>

2. Color: Colour value.

Property Definition:

<attr name = "TextColor" format = "Color"/>

Properties using:

<com.lin.gw.customview   android:layout_width = "42dip"   android:layout_height = "42dip"   App:textcolor = "#fff000"/>

3. Boolean: Boolean value.

Property Definition:

<attr name = "focusable" format = "Boolean"/>

Properties using:

<com.lin.gw.customview   android:layout_width = "42dip"   android:layout_height = "42dip"   app:focusable = "true"/>

4. Dimension: Dimension value.

Property Definition:

<attr name = "customwidth" format = "Dimension"/>

Properties using:

<com.lin.gw.customview   app:customwidth = "42dip"   android:layout_height = "Wrap_content"/>

5. Float: floating-point value.

Property Definition:

<attr name = "Fromalpha" format = "float"/>

Properties using:

<com.lin.gw.customview   App:fromalpha = "2.0"/>

6. Integer: Integer value.

Property Definition:

<attr name = "frameduration" format= "integer"/>

Properties using:

<com.lin.gw.customview   app:frameduration = "/>"

7. String: Strings.

Property Definition:

<attr name= "TextString"  format= "string" ></attr>

Properties using:

<com.lin.gw.customview   app:textstring = "Hello lingling!" />

8. Fraction: percentage.

Property Definition:

<attr name = "Pivotx" format = "fraction"/>

Properties using:

<com.lin.gw.customview   app:pivotx = "30%"/>

9. Enum: enumeration value.

Property Definition:

<attr name= "Orientation" >   <enum name= "Horizontal" value= "0"/>   <enum name= "vertical" value= "1 "/> </attr>      

Properties using:

<com.lin.gw.customview   app:orientation = "vertical"/>

Flag: Bit or operation.

Property Definition:

<declare-styleable name= "CustomView" >     <attr name= "Windowsoftinputmode" >           <flag name = " Stateunspecified "value =" 0 "/>           <flag name =" stateunchanged "value =" 1 "/>           <flag name =" Statehidde N "value =" 2 "/>           <flag name =" Statealwayshidden "value =" 3 "/>           <flag name =" Statevisible "value = "4"/>           <flag name = "Statealwaysvisible" value = "5"/>           <flag name = "Adjustunspecified" value = "0x00 "/>           <flag name =" Adjustresize "value =" 0x10 "/>           <flag name =" Adjustpan "value =" 0x20 "/>           <flag name = "adjustnothing" value = "0x30"/>     </attr>         </declare-styleable>

Properties using:

App:windowsoftinputmode = "Stateunspecified | stateunchanged | Statehidden ">
Turn from
Http://www.cnblogs.com/crashmaker/p/3521310.htmlFrom crash_coder Linguowu[email protected]

Android Custom 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.