To determine if you know this, conduct a mock interview and see if you can explain it to the other person

1. The coordinate system

In the Android coordinate system, the origin is at the top left corner of the screen, and the origin is to the right of the positive X axis and down the positive Y axis. As follows:

In addition to Android coordinate system, there is also View coordinate system. The internal relationship of View coordinate system is shown in the figure.

2. Customize attributes

Android controls that start with Android are built-in properties of the system. To facilitate the configuration of custom View properties, we can also customize property values. Android custom attributes can be divided into the following steps:

  1. Customize a View
  2. Write values/attrs.xml, where you write tag elements like styleable and item
  3. View uses custom properties in layout file (note namespace)
  4. Retrieved from TypedArray in the View constructor

Customizing View properties is important, but not complicated, so look it up again if you need to

3. View drawing process

View drawing is basically completed by measure(), layout(), draw() this three functions

function role Relevant methods
measure() Measure the width and height of View measure(),setMeasuredDimension(),onMeasure()
layout() Calculates the position of the current View and its children layout(),onLayout(),setFrame()
draw() View drawing draw(),onDraw()

3.1 MeasureSpec

MeasureSpec is a MeasureSpec class that encapsulates the size of a View. OnMeasure () measures the width and height of a View according to MeasureSpec.

MeasureSpec values are stored in an int value. An int value has 32 bits. The first two bits represent the mode and the last 30 bits represent the size. MeasureSpec= mode+ size

Currently, three modes exist in MeasureSpec: UNSPECIFIED, EXACTLY, and AT_MOST.

For a MeasureSpec View, the mode and Size of MeasureSpec have the following meanings

model meaning The corresponding
EXACTLY Precise mode: The View needs an exact value, which is the Size of MeasureSpec match_parent
AT_MOST Max mode: A View has a maximum Size and cannot exceed a MeasureSpec Size wrap_content
UNSPECIFIED Unrestricted, the View does not have any size restrictions, the View should be set to whatever size General internal system use

3.2 the Layout ()

The layout() process is used to calculate the position parameters of a View. For a ViewGroup, in addition to measuring its own position, it also needs to measure the position of its child views.

3.3 the Draw ()

Draw process is the process of View drawing to the screen, the entrance of the whole process in View draw() method, and the source notes are also written very clear, the whole process can be divided into 6 steps.

  1. Draw the background if necessary.
  2. If necessary, save the current canvas.
  3. Draws the contents of the View.
  4. Draw the child View.
  5. If necessary, draw edges, shadows, and other effects.
  6. Draw decorations such as scroll bars and so on.

Use the flow chart below:

Layout process customization:

Method: Rewrite the layout process related method \

1. OnMeasure () 2. OnLayout ()Copy the code

Specific:

1. Rewrite onMeasure() to change the size of the existing View. Rewrite onMeasure() to calculate the size of a custom View. Rewrite onMeasure() and onLayout() to compute the internal layout of a custom ViewGroupCopy the code
public class SquareImageView extends AppCompatImageView {
    private static final String TAG = "SquareImageView";

    public SquareImageView(Context context) {
        super(context);
    }

    public SquareImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Execute the original measurement algorithm first
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Get the original measurement result
        int measureWidth = getMeasuredWidth();
        int measureHeight = getMeasuredHeight();
        Log.d(TAG, "onMeasure11" +
                ", measureWidth = " + measureWidth +
                ", measureHeight = " + measureHeight +
                "");

        // Use the original measurement results to calculate the new size
        if (measureWidth > measureHeight) {
            measureWidth = measureHeight;
        } else {
            measureHeight = measureWidth;
        }
        Log.d(TAG, "onMeasure22" +
                ", measureWidth = " + measureWidth +
                ", measureHeight = " + measureHeight +
                "");
        // Save the calculated resultsetMeasuredDimension(measureWidth, measureHeight); }}Copy the code

Overwrite onMeasure() to change the size

1. Overwrite onMeasure() to change the size and call super.onMeasure triggers the original measurement 2. Use getMeasuredWidth() and getMeasuredHeight() to take the previously measured measurements, and use these measurements to calculate the final measurements. 3. Save dimensions using setMeasuredDimension()Copy the code

Android custom View full solution