当前位置:网站首页>Custom view incomplete to be continued
Custom view incomplete to be continued
2022-07-03 20:49:00 【Purple wish_ Best in the world】
Customize View
List of articles
Purple wish _ The world is perfect , A teenager committed to internship in the factory during the sophomore summer vacation , First written in 2022/2/13
What is customization View
Customize View And customization ViewGroup The difference between ?
Customize View Generally, you need to realize your own
onMeasure()
andonDraw()
Method .Customize ViewGroup Need to achieve
onMeasure()
andonLayout()
Method .
Customize View Steps for
Three steps :
- Layout
onLayout(){}
- draw
onDraw(){}
- Touch event
onTouchEvent(){}
Layout
Layout , About to confirm View The size and location of , If not set, then sub View Will be in the upper left corner of the parent control . Then according to the size of the child control , Determine the size you need .
First of all, you need the child controls to measure themselves , That is, call the... Of the child control onMeasure()
Method , Let child controls measure themselves . Before the layout The measurement operation must be carried out first , otherwise get
When the width and height of the child control are obtained, there will be multiple times of obtaining Inconsistent values The situation of . Then call the sub control onMeasure()
Method time , Including rewriting your own onMeasure()
Method time , You will encounter two parameters widthMeasureSpec: Int
and heightMeasureSpec: Int
, Why are there these two parameters ? How to set the values of these two parameters ? How to use the values of these two parameters ? I believe these problems are difficult for beginners and must be solved .
widthMeasureSpec and heightMeasureSpec What is it?
Let's see what these two words mean first :
width measure spec: Width measurement specification
height measure spec: Height measurement specification
Through the name, we can easily understand , Is the father View Tell me View Recommended width of / Height value .
So father View How to set the recommended width with only one parameter / Height value to child View Clearly described ? This is wonderful , Really amazed Google The ingenuity of the engineer . Don't underestimate this variable , He also stored specMode
and specSize
Two messages . How to do it ? We know that integer in computer is 4 Binary representation of bytes , That is, by 32 individual 0 perhaps 1. In general ,Android The pixel value of the width or height of the device of the system does not exceed 230,Google Engineers put the high-ranking first 31 and 30 Bits specifically store other intention information .
Although there are only two , There are three kinds of information stored in it , It happens to be doomed dp value 、wrap_content and match_parent, Cooperate with parent view Limitations on oneself and self pairs View The limitation of , When you put it together, you have 9 In this case , this 9 This situation covers all the current situations —— Father View yes match_parent, Son View yes wrap_content; Father view yes wrap_content, Son view yes match_parent And so on . So the rest 30 Bit stores information about the specific value size . This way of storing information in high places, which is not used at all, is a new idea .
Let's see Google How does the official figure out Spec The result of
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
@MeasureSpecMode int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
sUseBrokenMakeMeasureSpec
by true When , yes API17 And the calculation method of previous versions , It's going to be size and mode Add up , The sequence of the passed in parameters is inconsistent, and it can still be executed normally , But any overflow of the two values will affect MeasureSpec Result , this Caused ConstraintsLayout Of bug,Google The official replaced it with a more rigorous bit calculation method to solve this problem . So now sUseBrokenMakeMeasureSpec
The values for are as follows :
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT; // The first 31、30 Position as 1, The rest are 0
// Use the old (broken) way of building MeasureSpecs.
private static boolean sUseBrokenMakeMeasureSpec = false;
The default is false
, Then it will be (size & ~MODE_MASK) | (mode & MODE_MASK)
To calculate .
widthMeasureSpec and heightMeasureSpec What value should the parameter be set to
The system has given a very good conversion to WidthMeasureSprc or heightMeasureSpec Methods
public static int getChildMeasureSpec(int spec, int padding, int childDimension) {
int specMode = MeasureSpec.getMode(spec);
int specSize = MeasureSpec.getSize(spec);
int size = Math.max(0, specSize - padding);
int resultSize = 0;
int resultMode = 0;
switch (specMode) {
// Parent has imposed an exact size on us
case MeasureSpec.EXACTLY:
if (childDimension >= 0) {
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} else if (childDimension == LayoutParams.MATCH_PARENT) {
// Child wants to be our size. So be it.
resultSize = size;
resultMode = MeasureSpec.EXACTLY;
} else if (childDimension == LayoutParams.WRAP_CONTENT) {
// Child wants to determine its own size. It can't be
// bigger than us.
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
}
break;
// Parent has imposed a maximum size on us
case MeasureSpec.AT_MOST:
if (childDimension >= 0) {
// Child wants a specific size... so be it
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} else if (childDimension == LayoutParams.MATCH_PARENT) {
// Child wants to be our size, but our size is not fixed.
// Constrain child to not be bigger than us.
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
} else if (childDimension == LayoutParams.WRAP_CONTENT) {
// Child wants to determine its own size. It can't be
// bigger than us.
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
}
break;
// Parent asked to see how big we want to be
case MeasureSpec.UNSPECIFIED:
if (childDimension >= 0) {
// Child wants a specific size... let them have it
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} else if (childDimension == LayoutParams.MATCH_PARENT) {
// Child wants to be our size... find out how big it should
// be
resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
resultMode = MeasureSpec.UNSPECIFIED;
} else if (childDimension == LayoutParams.WRAP_CONTENT) {
// Child wants to determine its own size.... find out how
// big it should be
resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
resultMode = MeasureSpec.UNSPECIFIED;
}
break;
}
//noinspection ResourceType
return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
}
in other words , Here you only need to pass three parameters int spec, int padding, int childDimension
, How to pass parameters ?
- spec It can be directly transferred into its own
widthMeasureSpec
andheightMeasureSpec
, Used to get subclasseswidthMeasureSpec
andheightMeasureSpec
- padding You need to set the corresponding padding Pass in
- childDimension Transitions View Of layoutParams The width or height of
Here is my general way of writing :
val childLayoutParams = childView.layoutParams
val chileWidthMeasureSpec = getChildMeasureSpec(
widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams.width
)
val chileHeightMeasureSpec = getChildMeasureSpec(
heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams.height
)
// Finally, according to business needs , Calculate your own width and height settings
Some small problems
onMeasure()
Methods may be used by parents View Call several times , Therefore, you need to reset and initialize the used object attributes . Here we can see an example :
// sdk30 -FrameLayout.java Source code
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMatchParentChildren.clear();
/**
* Omitted code
*/
for (int i = 0; i < count; i++) {
if (mMeasureAllChildren || child.getVisibility() != GONE) {
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
}
}
if (count > 1) {
for (int i = 0; i < count; i++) {
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
}
Here we can see that subclasses are called twice onMeasure
Method , and FrameLayout In itself onMeasure
I also emptied my own ArrayList.
draw
Update after learning
Touch event
Update after learning
Purple wish _ The world is perfect , A teenager committed to internship in the factory during the sophomore summer vacation , First written in 2022/2/13
边栏推荐
- @Transactional注解失效的场景
- 2.7 format output of values
- 淺析 Ref-NeRF
- Global and Chinese market of full authority digital engine control (FADEC) 2022-2028: Research Report on technology, participants, trends, market size and share
- Research Report on the overall scale, major manufacturers, major regions, products and application segmentation of rotary tablet presses in the global market in 2022
- The global industrial design revenue in 2021 was about $44360 million, and it is expected to reach $62720 million in 2028. From 2022 to 2028, the CAGR was 5.5%
- Machine learning support vector machine SVM
- Line segment tree blue book explanation + classic example acwing 1275 Maximum number
- Rhcsa third day notes
- How to set the system volume programmatically- How to programmatically set the system volume?
猜你喜欢
Line segment tree blue book explanation + classic example acwing 1275 Maximum number
How to handle wechat circle of friends marketing activities and share production and release skills
如临现场的视觉感染力,NBA决赛直播还能这样看?
JMeter plug-in installation
In 2021, the global revenue of thick film resistors was about $1537.3 million, and it is expected to reach $2118.7 million in 2028
2.6 formula calculation
Operate BOM objects (key)
Qt6 QML Book/Qt Quick 3D/基础知识
XAI+网络安全?布兰登大学等最新《可解释人工智能在网络安全应用》综述,33页pdf阐述其现状、挑战、开放问题和未来方向
@Transactional注解失效的场景
随机推荐
Interval product of zhinai sauce (prefix product + inverse element)
Global and Chinese market of full authority digital engine control (FADEC) 2022-2028: Research Report on technology, participants, trends, market size and share
MySQL dump - exclude some table data - MySQL dump - exclude some table data
Battle drag method 1: moderately optimistic, build self-confidence (1)
Analysis of gas fee setting under eip1559
Introduction to golang garbage collection
Hcie security Day11: preliminarily learn the concepts of firewall dual machine hot standby and vgmp
如临现场的视觉感染力,NBA决赛直播还能这样看?
MDM mass data synchronization test verification
Producer consumer mode (multithreading, use of shared resources)
Shortest path problem of graph theory (acwing template)
Qt6 QML Book/Qt Quick 3D/基础知识
全网都在疯传的《老板管理手册》(转)
TLS environment construction and plaintext analysis
Global and Chinese market of speed limiter 2022-2028: Research Report on technology, participants, trends, market size and share
MySQL learning notes - single table query
How to handle wechat circle of friends marketing activities and share production and release skills
String and+
Global and Chinese market of cyanuric acid 2022-2028: Research Report on technology, participants, trends, market size and share
19、 MySQL -- SQL statements and queries