Android Custom View detailed description

Source: Internet
Author: User

Starting from inheritance

Know a bit about object-oriented language knowledge: encapsulation, inheritance, and polymorphism, which are the three basic features of object-oriented, so the simplest way to customize a view is to inherit the existing view

With this code, I define a sketchview, inherit from the View object, and make a copy of its three construction methods, I mainly analyze these three construction methods:

    • The first way to construct this method is to create a new view in the code, such as

Sketchview Sketchview = new Sketchview (this);

In this way, a custom view is created and can be added to the layout as needed

    • The second construction method is that we typically add a view to the XML file

<me. Shaohui. Androidpractise. Widget. Sketchview

android:layout_width="Match_parent"

android:layout_height="Match_parent"

android:layout_marginright="16DP"

android:layout_margintop="16DP" />

    • In this way, we add a sketchview to the layout file, plus some layout properties, the width and Height properties, and the margin property, which are stored in the AttributeSet parameter of the second constructor.

    • The third constructor is more than the second constructor of the value of an int, called defstyleattr, judging from the name, this is a parameter about the custom property, in fact, our guess is correct, the third constructor will not be called by the system default, but we need to explicitly call, For example, call the third function in the second constructor and set the third argument to 0.

Measure->layout->draw

Before learning how to write a custom control, it is necessary to understand the drawing process of a control, in Android, a view drawing process includes: Measure,layout and draw, through onmeasure know a view to occupy the size of the interface, Then through the onlayout know where the control should be placed, and finally through the OnDraw method to draw the control, and then to show in front of the user, I will analyze each of the three methods of the role.

    • Onmeasure measurement, by measuring the size of a view to be accounted for, the method parameter is a value of two int, we all know that in Java, the int is composed of 4 bytes (32bit), in Measurespce, with the first two to represent mode, Use the latter 30 digits to indicate size

There are three types of mode in Measurespce: Exactly, at_most,unspecified, except UNSPECIFIED, the other two mode: When the parent layout is exactly, the child controls determine size or match_parent, Mode is exactly, when the child control is wrap_content, mode is At_most, when the parent layout is at_most, the child controls determine the size, mode is exactly, the child controls Wrap_content or Match_parent , Mode is at_most. Therefore, in determining the size of the control, you need to determine the mode of measurespec, not directly with the measurespec size. After some logical processing, the Setmeasuredimension () method is called, and the measured width is passed in for layout use.

It is important to understand that the width of the measurement is not necessarily the final display of the width of the height, the final width is determined in the OnLayout method, Layou (Left,top,right,bottom), but generally the same.

    • OnLayout Actually, I did not rewrite the OnLayout method when I was customizing Sketchview, because Sketchview is simply a view, it is not a view container, no child view, And the OnLayout method is mainly specific placement of sub-view position, horizontal or vertical placement, so in a simple custom view is not required to rewrite the OnLayout method, but it is important to note that Whether or not the margin property of a child view is in effect depends on whether the parent is processing in its own OnLayout method, and the view Padding property is in effect in the OnDraw method.

In fact, there is a property in the OnLayout method I have been concerned about and did not make it very clear, is the first parameter boolean:changed, indicating whether the size of the view has changed, the subsequent understanding, will come back to fill the pit.

    • OnDraw finally talked about the play, general custom control the most expensive thing is this method, need in this method, with paint on the canvas to draw the pattern you want, so a custom view is finished. Here's a detailed picture of how to draw the pattern you want on the canvas.

On the OnDraw method, in addition, if the view is directly inherited, then the way to rewrite OnDraw is to completely delete the Super.ondraw (canvas), because its default implementation is NULL.

To get a square view

The last part of the main said that the view of the drawing process, from the three methods, we can know how to measure a control, how to place the child elements of the control, how to draw the pattern, below I said I learned through onmeasure a little trick.

In daily development, we occasionally need a square imageview, generally by specifying the width of the height, but when the height is uncertain, we can only hope that the Android OST support to define the scale of the view, but the reality is brutal, the system seems to have not provided similar properties, So we can only achieve by ourselves, in fact, their own writing is also very simple, only need to change a parameter on OK,

@Override

protected void onmeasure(int widthmeasurespec, int Heightmeasurespec) {

Super. Onmeasure(widthmeasurespec, widthmeasurespec);

}

Not careful observation is not to see the mystery of it, although here to make a copy of the view of the onmeasure, but seemingly did not do any processing, directly call the Super method, but carefully observe the words will find that when the super method is called, the second parameter changed, Originally should be heightmeasurespec but replaced with Widthmeasurespec, so the view height is the width of the view, a squareview realized, even if through a custom attribute to achieve a custom scale view.

Custom properties

Custom view does not have a custom attribute germs, to support custom properties for view, you need to define a name in the Values/attrs.xml file that defines the view name for yourself declare-styleable

<resources>

<declare-styleable name="Sketchview">

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

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

</Declare-styleable>

</Resources>

This allows you to use your own defined attributes in the XML file.

<me. Shaohui. Androidpractise. Widget. Sketchview

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

android:layout_width="Match_parent"

android:layout_height="Match_parent"

android:layout_marginright="16DP"

android:layout_margintop="16DP"

app:background_color="@color/colorprimary"

app:size="24DP"/>

Don't forget to add a custom namespace to this, adding custom attributes is nothing, but it takes a bit of effort to customize the properties, which leaves the foreshadowing: the defstyleattr parameter of the third construction method is coming up.

Public Sketchview(context context, attributeset attrs, int defstyleattr) {

Super(context, attrs, defstyleattr);

TypedArray a = context. Obtainstyledattributes(attrs, R. Styleable. Sketchview, defstyleattr, R. Style. Apptheme);

custom_size = a. Getdimensionpixelsize(R. Styleable. Sketchview_size, size);

Custon_background = a. GetColor(R. Styleable. Sketchview_background_color, default_color);

a. Recycle();

}

After a good operation, the XML definition of the attributes can be taken out, the specific value of how much, I have explained in the previous, it is not here to say more, the next operation is to take these attributes to do what you want to do.

Combat: A Dynamic view

Here's a quick introduction to how to draw a custom color circle at the center of the canvas in OnDraw (canvas canvas), and let the circle move through a valueanimator, without saying much, directly on the code:

(Only the core code is affixed, the complete code will be the link at the end of the article)

As you can see in the OnDraw () method, I have called the canvas's Drawcircle method to draw a circle, the position of the center is determined by the position of the canvas, the center of the canvas, the width and height parameters are obtained in the OnLayout () method, It is important to note that the height and width are inaccurate. The radius of the circle is the Size*scale defined in the XML file, and the scale is determined by a valueanimator that varies from 1 to 2,valueanimator and is assigned to the size and is called postinvalidate () method, the function of this method is to redraw, and then the radius of the circle will change, so refresh will achieve the effect of animation.

Requstlayout and Invalidate

When customizing the view, we often use the method of refreshing the view, there are three ways for us to choose: Requestlayout (), invalidate (), Postinvalidate (), In fact invalidate and postinvalidate these two methods function is the same, the only difference is invalidate used in the main thread, and Postinvalidate used in the asynchronous thread, The following compares the internal implementations of Requestlayout and invalidate:

From the code can be seen, in fact, these two methods are called the Scheduletraversals () method, the difference is that the Requestlayout method to set the mlayoutrequested flag to True, Scheduletraversals This method after the opportunity to further detailed analysis, now only a simple conclusion,

    • Requestlayout invokes a series of operations, such as measure and layout, and then decides whether or not to call draw, depending on whether the layout has changed and whether surface is destroyed. That is to say Requestlayout will definitely call measure and layout, but not necessarily call draw, the reader can try to change the small program I wrote above, the postinvalidate changed to Requestlayout, the animation effect disappears, Because the layout has not changed.

    • Invalidate will only call draw, and it will definitely be tuned, even if nothing has changed and it is redrawn.

So if there is a layout that needs to be changed, call the Requestlayout method, and if you just refresh the animation, you only need to call the Invalidate method.

Android Custom View detailed description

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.