Why is this chapter called Advanced? (although basic content is about), because since this will be the mysteries of the custom View gradually, each will be deeper than the last one content, using the learned knowledge to make more cool custom View, just like on the steps, each article to the next level, help you step by step toward the peak, life as a CEO, Marry Bai Fumei. Wrong, is to help you know more about the cool custom View is how to make, to achieve the effect of extrapolation.

Custom View drawing process function call chain (simplified version)

I. Custom View classification

I’ve divided custom Views into two categories (sloop personal taxonomy, unofficial) :

1. Customize the ViewGroup

Custom ViewGroup is generally used to use existing components according to a specific Layout to form a new component, most inherit from the ViewGroup or a variety of layouts, including child views.

For example: the application at the bottom of the navigation bar entry, generally is the above icon (ImageView), the following text (TextView), then the two can be combined with a custom ViewGroup into a Veiw, providing two properties respectively for setting text and image, it will be more convenient to use.

2. Customize the View

When there is no existing View and you need to implement it yourself, you use a custom View, which usually inherits from a View, SurfaceView, or other View, without any child View.

For example: create an ImageView that automatically loads web images, create charts, etc.

PS: In most cases, there are alternatives to custom View, using images or combined animation to achieve, but using the latter may face a lot of problems such as excessive memory consumption, production trouble.


Two. A couple of important functions

1. Constructor

Constructors are entrances to views that can be used to initialize some content and get custom properties.

The View constructor has four overloads:

public void SloopView(Context context) {}
public void SloopView(Context context, AttributeSet attrs) {}
public void SloopView(Context context, AttributeSet attrs, int defStyleAttr) {}
public void SloopView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {}
Copy the code

The View constructor has a lot of arguments, so we’ll exclude some of the less common ones and leave some of the more common ones.

The four-argument constructor was added in API21 and is not considered.

The third argument in the three-argument constructor is the default Style. The default Style refers to the default Style in the current Application or Activity Theme, and is only valid when explicitly called.

Public ImageButton(Context Context, AttributeSet attrs) {// Call the constructor for three parameters, This explicitly specify the third parameter (context, attrs. Com. Android. Internal. State Richard armitage TTR event. ImageButtonStyle); } public ImageButton(Context Context, AttributeSet attrs, int defStyleAttr) { This (context, attrs, defStyleAttr, 0); }Copy the code

Note: Even if you use the Style property in the View, you do not call the three-argument constructor. You still call the two-argument constructor.

Since the third parameter of the three-parameter constructor is generally not used, it is not considered for the moment. The specific usage of the third parameter will be introduced in detail in the future.

After two are excluded, only one argument and the constructor for two arguments are left, as follows:

// This is called when a View is created. Public void SloopView(Context Context) {} Public void SloopView(Context Context) {} Public void SloopView(Context Context) {} Public void SloopView(Context Context) {} public void SloopView(Context context, AttributeSet attrs) {}Copy the code

The following method calls the constructor of a parameter:

// SloopView new SloopView(this);Copy the code

The following method calls the constructor for two arguments:

// In the layout file - format: package name. The View name < com. The sloop. Study. SloopView android: layout_width "wrap_content" android: layout_height "wrap_content" / >Copy the code

So much for constructors, more on how to customize attributes and use attrs later, but for now you just need to know when these two constructors are called.

2. Measure the View size (onMeasure)

Q: Why measure the View size?

A: The size of A View is not only determined by itself, but also affected by the parent control. In order to better adapt to various situations, we generally measure ourselves.

The onMeasure function is used to measure the size of View. We can extract the width and height data from the two parameters of onMeasure:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthsize MeasureSpec.getSize(widthMeasureSpec); Int WidthMode MeasureSpec. GetMode (widthMeasureSpec); Int HeightSize MeasureSpec. GetSize (HeightSize); Int HeightMode MeasureSpec. GetMode (HeightMode MeasureSpec); // Select height measurement mode}Copy the code

WidthMeasureSpec and heightMeasureSpec are two int parameters in the onMeasure function. They are widthMeasureSpec and heightMeasureSpec. It is a value synthesized by width, height, and corresponding measurement modes in each direction:

MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec: MeasureSpec:

model Binary value describe
UNSPECIFIED 00 By default, the parent control does not impose any restrictions on the child view, which can be set to any size.
EXACTLY 01 Indicates that the parent control has specified the exact size of the child View.
AT_MOST 10 The size of the child View is not limited, but there is an upper limit, the upper limit is generally the size of the parent View.

In the 32-bit binary of int, the two bits 31-30 represent the measurement mode, and the thirty bits 29-0 represent the actual values of width and height, which are actually as follows:

Take the value 1080(binary: 1111011000) (where the pattern and the actual value are joined, I’ve separated them for demonstration) :

Model name Model numerical The actual numerical
UNSPECIFIED 00 000000000000000000001111011000
EXACTLY 01 000000000000000000001111011000
AT_MOST 10 000000000000000000001111011000

MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec = MeasureSpec

Note:

Do not call super.onMeasure(widthMeasureSpec, heightMeasureSpec) if you change the width and height of the View; To call setMeasuredDimension(WidthSize, HeightSize); This function.

3. Determine View size (onSizeChanged)

This function is called when the view size changes.

Q: Why resize the View after measuring it and using the setMeasuredDimension function?

A: This is because the View size is controlled not only by the View itself, but also by the parent control, so it is best to use the onSizeChanged callback provided by the system to determine the size of the View.

OnSizeChanged is as follows:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
}
Copy the code

As you can see, it has four parameters: width, height, previous width, and previous height.

This function is relatively simple, we only need to focus on the width (w), height (h), and these two parameters are the final size of the View.

4. Determine the location of the sub-view layout (onLayout)

The function to determine the layout is onLayout, which is used to determine the location of the child View, used in the custom ViewGroup, it is called the child View layout function.

In the custom ViewGroup, onLayout is generally loop out the child View, and then calculated the coordinate value of each child View position, and then use the following function to set the child View position.

child.layout(l, t, r, b);
Copy the code

The four parameters are:

The name of the instructions Corresponding function
l The distance between the left side of a View and the left side of its parent View getLeft();
t The distance between the top of the View and the top of the parent View getTop();
r The distance between the right side of a View and the left side of its parent View getRight();
b The distance between the bottom of the View and the top of the parent View getBottom();

Refer to the coordinate system article for details.

PS: The onLayout function will be explained in more detail when we talk about customizing viewgroups.

5. OnDraw

OnDraw is the part that’s actually drawn, the part that we really care about, using Canvas drawing.

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
}
Copy the code

Canvas drawing is the focus of this chapter and will be explained in detail in several articles. Please look forward to OwO.

6. Provide external operation methods and listen for callbacks

After customizing a View, it usually exposes some interfaces to control the state of the View or monitor the change of the View.

This content will be explained with examples in subsequent articles.


Iii. Sorting out key knowledge

Custom View classification

PS: ViewGroup is actually a subclass of View.

category Inherited from The characteristics of
View The View SurfaceView etc. Does not contain the View
ViewGroup ViewGroup xxLayout etc. Contains a View

Custom View flow:

steps The keyword role
1 The constructor The View is initialized
2 onMeasure Measure View size
3 onSizeChanged Size the View
4 onLayout Determine the layout of child views (useful when customizing a View to include child views)
5 onDraw Actual drawing content
6 Provide the interface Control the View or listen to some state of the View.

Sequel:

Android custom controls advanced

  • Android Custom control advanced 01- Custom control development routines and processes
  • Android custom controls advanced 02-Canvas drawing graphics
  • Android custom controls advanced 03-Canvas Canvas operation
  • Android custom controls advanced 04-Canvas picture text
  • Android custom controls advanced 05-PATH basic operations
  • Android custom control advanced 06-Path bezier curve
  • The end of Android Custom controls Advanced 07-Path
  • Android custom controls advanced 08-PathMeasure details
  • Android custom control advanced 09- Control core Matrix principle
  • Android custom control advanced 10- control core Matrix Camera
  • Android custom controls Advanced 11- Event distribution mechanism principle
  • Android Custom controls Advanced 11- Event distribution mechanism 01
  • Android Custom controls Advanced 12- Event distribution mechanism principle 02
  • Android custom controls advanced 13-MotionEvent details
  • Android Custom Controls Advanced 14- Special controls event handling scheme