1. Foundation 1: Coordinate calculation
1.1 Android window coordinate system calculation takes the upper left corner of the screen as the origin,
If you go to the right, you have a positive X-axis, and if you go down, you have a positive Y-axis
1.2 View Coordinate system
Note that the coordinates obtained are pixel values, not dp values. Note that the coordinates obtained are pixel values, not DP values.
// Get the relative coordinates (distance) inside the ViewGetX (), getY ()// Get the relative coordinate value of the View relative to the parent View.GetLeft (), getTop(), getRight(), getBottom()// Get the actual coordinate value in the screen (distance)GetRawX (), getRawY ()Copy the code
The activity in the figure refers to a full-screen window. Strictly speaking, it should be a screen
1.3 Actual Development Scenarios
Get the width and height of the View
width = getRight() - getLeft();
height = getBottom() - getTop();
Copy the code
2. Get the upper left corner coordinates of the View in the parent View
Point point = new Point();
point.set(ivState.getLeft() ,ivState.getTop());
Copy the code
3. Obtain the coordinate of the center point of the View in the parent View
Point point = new Point();
point.set(ivState.getRight() - ivState.getLeft() ,ivState.getBottom() - ivState.getTop());
Copy the code
2. Customize attributes
2.1 Constructors & Initialize properties
public class MDButton extends Button {
// Called when Java dynamically creates a view
public MDButton(Context context) {
super(context);
initInnerView(context);
}
// when the XML layout is initialized
public MDButton(Context context, AttributeSet attrs) {
super(context, attrs);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
initAttrs(context, attrs);
}
/ / the default style, in MDButton (Context Context, AttributeSet attrs) called MDButton (Context, attrs, defStyleAttr);
public MDButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
initAttrs(context, attrs);
}
// Only used when API version >21
/ / the default style, in MDButton (Context Context, AttributeSet attrs) called MDButton (Context, attrs, defStyleAttr);
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MDButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
initAttrs(context, attrs);
}
// When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
private void initInnerView(Context context) {
/ /...
}
private void initAttrs(Context context, AttributeSet attrs) {
/ /...}}Copy the code
2.2 Custom Attributes
1. Write attribute & type in /res/values/attrs. XML in module;
<resources>
<declare-styleable name="MDButton">
<! You can specify multiple types of values when you define a property -->
<attr name="mdb_bg" format="color|reference" />
<attr name="mdb_txt_color" format="color|reference" />
<! -- String -->
<attr name="mdb_txt" format="string" />
<! -- boolean -->
<attr name="mdb_auto_anim" format="boolean" />
<! -- Percentage type -->
<attr name="mdb_anim_pivotX" format="fraction" />
<! - an int value -- -- >
<attr name="mdb_auto_anim_delay" format="integer" />
<! -- floating point value -->
<attr name="mdb_auto_anim_alpha" format="float" />
<! -- dp size value -->
<attr name="mdb_min_width" format="dimension" />
<! -- Enumeration types -->
<attr name="mdb_size">
<enum name="small" value="0" />
<enum name="normal" value="1" />
<enum name="big" value="2" />
</attr>
<! -- flag: bit or operation -->
<attr name="mdb_radius_corner">
<flag name="empty" value="0x00" />
<flag name="top" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<flag name="right" value="0x08" />
</attr>
</declare-styleable>
</resources>
Copy the code
2. Customize the View class to get the property value and use
public class MDButton extends Button {
// When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
private void initInnerView(Context context) {
/ /...
}
private void initAttrs(Context context, AttributeSet attrs) {
//1. Get the attribute array
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MDButton);
//2. Get the attribute value
Drawable bgDrawable = typedArray.getDrawable(R.styleable.MDButton_mdb_bg);
int txtColor = typedArray.getInteger(R.styleable.MDButton_mdb_txt_color,Color.parseColor("# 808080"));
String txt = typedArray.getString(R.styleable.MDButton_mdb_txt);
boolean isAutoAnim = typedArray.getBoolean(R.styleable.MDButton_mdb_auto_anim, false);
float fraction = typedArray.getFraction(R.styleable.MDButton_mdb_anim_pivotX, 1.1.1.0 f);
float alpha = typedArray.getFloat(R.styleable.MDButton_mdb_auto_anim_alpha , 1.0 f);
float minWidth = typedArray.getDimension(R.styleable.MDButton_mdb_min_width, 32.0 f);
int sizeType = typedArray.getInt(R.styleable.MDButton_mdb_size, 1);//0=small 1=normal 2=big
int radiusCorner = typedArray.getInt(R.styleable.MDButton_mdb_radius_corner ,0);
int delay = typedArray.getInt(R.styleable.MDButton_mdb_auto_anim_delay ,0);
Log.e("bgDrawable".""+bgDrawable);
Log.e("txtColor".""+txtColor);
Log.e("txt".""+txt);
Log.e("isAutoAnim".""+isAutoAnim);
Log.e("fraction".""+fraction);
Log.e("alpha".""+alpha);
Log.e("minWidth".""+minWidth);
Log.e("sizeType".""+sizeType);
Log.e("radiusCorner".""+radiusCorner);
Log.e("delay".""+delay);
Log.e("= = = = = = = = = = = = = ="."= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
//3. Set the attribute value to the corresponding attribute
setText(txt);
//tv.setDelay(delay);
/ /...
4 / / release
typedArray.recycle();
}
// Called when Java dynamically creates a view
public MDButton(Context context) {
super(context);
initInnerView(context);
}
// when the XML layout is initialized
public MDButton(Context context, AttributeSet attrs) {
super(context, attrs);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
initAttrs(context, attrs);
}
/ / the default style, in MDButton (Context Context, AttributeSet attrs) called MDButton (Context, attrs, defStyleAttr);
public MDButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be called
initAttrs(context, attrs);
}
// Only used when API version >21
// When there is a default style, call in MDButton(Context Context, AttributeSet attrs)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MDButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// initInnerView(context); // When you combine a custom View (ViewGroup), you need to initialize the internal subview; An extended custom View does not need to be calledinitAttrs(context, attrs); }}Copy the code
3. Use the control in the layout file.xml.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:orientation="vertical"
>
<com.cupster.base_super_resource.MDButton
app:mdb_anim_pivotX="80%"
app:mdb_auto_anim="true"
app:mdb_auto_anim_alpha="1.0"
app:mdb_auto_anim_delay="100"
app:mdb_bg="@drawable/shape_btn_gray_radius5"
app:mdb_min_width="60dp"
app:mdb_radius_corner="right"
app:mdb_size="big"
app:mdb_txt="btn1"
app:mdb_txt_color="#ff00ff"
android:layout_width="120dp"
android:layout_height="60dp"
/>
<com.cupster.base_super_resource.MDButton
app:mdb_anim_pivotX="70%"
app:mdb_auto_anim="false"
app:mdb_auto_anim_alpha="0.4"
app:mdb_auto_anim_delay="100"
app:mdb_bg="@drawable/shape_btn_gray_radius5"
app:mdb_min_width="60px"
app:mdb_radius_corner="bottom|left|top|right"
app:mdb_size="small"
app:mdb_txt="btn1"
app:mdb_txt_color="#ff00ff"
android:layout_width="120dp"
android:layout_height="60dp"
/>
<com.cupster.base_super_resource.MDButton
app:mdb_anim_pivotX="100%"
app:mdb_auto_anim_alpha="0.9"
app:mdb_auto_anim_delay="100"
app:mdb_bg="@drawable/shape_btn_gray_radius5"
app:mdb_min_width="90dp"
app:mdb_radius_corner="empty"
app:mdb_size="normal"
app:mdb_txt="btn1"
app:mdb_txt_color="#ff00ff"
android:layout_width="120dp"
android:layout_height="60dp"
/>
</LinearLayout>
Copy the code
** Addendum: Correctness verification of attribute value acquisition **
3. Customize the View category
3.1 combined
As the name implies, the root layout of the XML file uses a RelativeLayout(similar to other layout controls), and the internal use of other View controls, layout, combined to create the original layout of the XxxView. The Java class then inherits from the container class corresponding to the root layout tag, overrides the constructor, and initializes variables for each child View. Is the most commonly used, the most reliable, not easy to produce excessive drawing, memory leaks and other problems.
Android Custom View(2) : composite
3.2 Inheritance overrides, derivations, and extensions
In short, if you inherit Button, change the default background, Button elevation value when state_press state, cancel the default minimum height 56dp, and so on. It is also the most commonly used feature that directly extends/modifies native Views
Android Custom View(3) : inherit rewrite, derivative/extension
3.3 since the painting style
Strong advice: Be familiar with View drawing, Android event passing, gesture processing and then start drawing yourself.
Method: Directly inherit View, rewrite the drawing process three steps
- Measure () measurement
- Calculate the layout coordinates
- The draw ()
Android Custom View(4) : self – drawn
4. The lifecycle of the View
The lifecycle of the View and the sequence of function calls associated with the Activity linkage
- [View] The constructor
- “The View” onFinishInflate ()
- “The Activity” onCreate ()
- “The Activity” onStart ()
- “The Activity” onResume ()
- “The View” onAttachedToWindow ()
- 【View】onMeasure()
- 【View】onSizeChanged()
- 【View】onLayout()
- 【View】onDraw()
- 【View】onWindowFocusChanged() (called before activity.onPause (), hasWindowFocus==false)
- “The Activity” onPause ()
- “The Activity” onStop ()
- “The Activity” onDestroy ()
- “The View” onDetachedFromWindow