Read The Fucking Source Code

The introduction

Android custom controls involve the process of drawing and distributing views

Android Q — API 29

[Android drawing process]

1. Preview

2. layout

2.1 Differences between a View and a ViewGroup

  • View: View mainly executes layout method, using serFrame method to set the position of the four vertices of its own View, determine the position of the View itself.
  • ViewGroup: The ViewGroup mainly executes onLayout method, recursively traverses all the child views, determines the location of the child View.

2.2 Summary of Views and ViewGroups

2.2.1 the View layout

2.2.2 ViewGroup layout

2.3 Layout Layout from top to bottom

2.3.1 DecorView distribution

  • The layout distributed by the top DecorView
  • Let’s look at the view rule PLperformLayout()methods
Private void performLayout (WindowManager. LayoutParams lp, int desiredWindowWidth, int desiredWindowHeight) {/ / code omitted... // DecorView final View host = mView; // code omitted...... // Distribute host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight()); // code omitted...... }Copy the code

See here, what is host.getMeasuredWidth()/host.getMeasuredHeight()? It calls the methods in the View directly, which are the width and height of the DecorView measured by the measure. This is explained in the Android custom control Measure.

2.3.2 ViewGroup distribution

ViewGroup (for example, LinearLayout) Distribution layouts

2.3.2.1 Let’s look at the Layout () method in ViewGroup

@override public final void layout(int l, int t, int r, int b) {//ViewGoup LayoutTransition animation, animation related, can ignore if (! mSuppressLayout && (mTransition == null || ! mTransition.isChangingLayout())) { if (mTransition ! = null) { mTransition.layoutChange(this); } // Call the layout method super.layout(l, t, r, b); } else { // record the fact that we noop'd it; request layout when transition finishes mLayoutCalledWhileSuppressed = true; }}Copy the code

The layout inside the ViewGroup will eventually be called into the parent View’s Layout, which will be explained later. So you’ll end up calling the View’s onLayout method, and the onLayout of the ViewGroup is an abstract method, so the subclass LinearLayout has to be implemented.

2.3.2.2 Let’s look again at the onLayout() method on the LinearLayout.

Override protected void onLayout(Boolean changed, int l, int t, int r, int b) {if (mOrientation == VERTICAL) {Override protected void onLayout(Boolean changed, int l, int t, int r, int b) { Android :orientation="vertical" layoutVertical(L, T, r, b); } else {// Android :orientation="horizontal" layoutHorizontal(l, t, r, b); }}Copy the code

2.3.2.3 Choose a vertical one. Let’s look at the layoutVertical() method on a LinearLayout.

Void layoutVertical(int left, int top, int right, int bottom) {// // Each subview is measured to determine its width and height, so the layout is determined only by the position of left and top. int childTop; int childLeft; // code omitted...... View for (int I = 0; i < count; i++) { final View child = getVirtualChildAt(i); if (child == null) { childTop += measureNullChild(i); } else if (child.getVisibility() ! Final int childWidth = child.getMeasuredWidth(); child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); // code omitted...... // Determine the position of its child View (recursively call setChildFrame() of the child View, SetChildFrame (Child, childLeft, childTop + getLocationOffset(Child), childWidth, childHeight); // code omitted...... }}}Copy the code

2.3.2.4 Let’s look at the setChildFrame() method on the LinearLayout.

private void setChildFrame(View child, int left, int top, int width, Child.layout (left, top, left + width, top + height); }Copy the code

Once again, back to the View layout method, let’s look at the layout distributed by the View.

2.3.3 the View to distribute

Let’s start with the Layout () method in the View.

Public void layout(int l, int t, int r, int b) { Int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; Boolean changed = isLayoutModeOptical(mParent)? setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b); // If the size & position of the view changes. Reposition all of the View's children in the parent container: OnLayout () if (changed | | (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) = = PFLAG_LAYOUT_REQUIRED) {/ / to determine the View all the View in the position of the parent container  onLayout(changed, l, t, r, b); // code omitted...... }}Copy the code

Let’s start with the onLayout() method in the View.

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    }
Copy the code

Empty. In fact, the layout of the View is determined by the parent container, so empty implementation is normal, of course, can also be changed in the custom View.

Xiaobian extension links

Android View Module Family Bucket

Recommended Blogs

Android development of a custom control (2)- onLayout details custom View Layout process – the most understandable custom View principle series (3)