深入剖析:Android中RelativeLayout源代码大揭秘
Relativelayout是Android中的一种布局方式,它基于父容器中的其他视图来确定自身的位置。下面是Relativelayout的源代码: ```java public class RelativeLayout extends ViewGroup { private static final String TAG = "RelativeLayout"; public RelativeLayout(Context context) { super(context); init(); } public RelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RelativeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setChildrenDrawingOrderEnabled(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int totalWidth = 0; int totalHeight = 0; int top = 0; int left = 0; int right = 0; int bottom = 0; int usedWidth = 0; int usedHeight = 0; final int specMode = MeasureSpec.getMode(widthMeasureSpec); final int specSize = MeasureSpec.getSize(widthMeasureSpec); final int specModeHeight = MeasureSpec.getMode(heightMeasureSpec); final int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec); for (int i = 0; i < count; i++) { View child = getChildAt(i); measureChild(child, widthMeasureSpec, heightMeasureSpec); if (specMode == MeasureSpec.AT_MOST && specSize < child.getMeasuredWidth()) { throw new IllegalStateException("The total width of all child views under RelativeLayout exceeds the parent width"); } if (specModeHeight == MeasureSpec.AT_MOST && specSizeHeight < child.getMeasuredHeight()) { throw new IllegalStateException("The total height of all child views under RelativeLayout exceeds the parent height"); } int childWidth = child.getMeasuredWidth(); int childHeight = child.getMeasuredHeight(); int childLeft; int childTop; if (child.getLayoutParams() instanceof RelativeLayout.LayoutParams) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) child.getLayoutParams(); childLeft = layoutParams.leftMargin + left; childTop = layoutParams.topMargin + top; int childWidthSpec = MeasureSpec.makeMeasureSpec(specSize - usedWidth, MeasureSpec.EXACTLY); int childHeightSpec = MeasureSpec.makeMeasureSpec(specSizeHeight - usedHeight, MeasureSpec.EXACTLY); child.measure(childWidthSpec, childHeightSpec); childLeft += layoutParams.leftMargin; childTop += layoutParams.topMargin; childWidth = child.getMeasuredWidth(); childHeight = child.getMeasuredHeight(); } else { childLeft = left; childTop = top; child.measure(widthMeasureSpec, heightMeasureSpec); } if (childLeft < left) { left = childLeft; } if (childTop < top) { top = childTop; } if (childLeft + childWidth > right) { right = childLeft + childWidth; } if (childTop + childHeight > bottom) { bottom = childTop + childHeight; } usedWidth += childWidth; usedHeight += childHeight; } setMeasuredDimension(specMode == MeasureSpec.EXACTLY ? specSize : Math.max(specSize, usedWidth), specModeHeight == MeasureSpec.EXACTLY ? specSizeHeight : Math.max(specSizeHeight, usedHeight)); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } int childLeft; int childTop; if (child.getLayoutParams() instanceof RelativeLayout.LayoutParams) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) child.getLayoutParams(); childLeft = layoutParams.leftMargin + left; childTop = layoutParams.topMargin + top; } else { childLeft = left; childTop = top; } child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } @Override protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof RelativeLayout.LayoutParams; } @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); } @Override protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { return new RelativeLayout.LayoutParams(p); } @Override protected void onLayoutChildren(List<Animator> layoutChild animators) { // do nothing. } } ``` 这段代码定义了Relativelayout的构造函数、初始化方法、测量方法和布局方法。在测量方法中,它遍历所有的子视图,为每个子视图分配宽度和高度,然后根据子视图的位置和大小来调整父视图的大小。在布局方法中,它同样遍历所有的子视图,为每个子视图设置位置。 ######[AI写代码神器 | 1096点数解答 | 2023-11-08 00:27:00]
- RealtimeMonitoringFragment 代码片段:Android 实时监控功能核心代码剖析(字节豆包 | 30点数解答 | 2024-10-12 10:31:18)294
- 揭秘:Android实时监控片段(RealTimeMonitoringFragment)代码实现(GPT | 531点数解答 | 2024-10-12 10:32:25)269
- AIDE编写Xposed软件:参考代码教你拦截Smail类方法名(阿里通义 | 649点数解答 | 2024-10-12 00:15:48)305
- 深入剖析:Android中RelativeLayout源代码大揭秘(阿里通义 | 1096点数解答 | 2023-11-08 00:27:00)275
- 智能电话窗口按钮1弹起:获取坐标与手机IMEI码待处理(GPT | 208点数解答 | 2024-09-12 16:36:31)353
- C++ 利用栈求解唯一路径迷宫:从起点 (1,1) 到终点 (m - 2,n - 2)(阿里通义 | 732点数解答 | 2024-11-03 02:34:53)524
- 模板匹配任意对象:附源代码解析(字节豆包 | 28点数解答 | 2024-11-15 09:10:30)252
- C++实现计算超过能量平均值的宝石数量(字节豆包 | 216点数解答 | 2026-03-07 19:02:43)11
- C++ 实现根据能量宝石和原核能量值计算武器图鉴数量(字节豆包 | 314点数解答 | 2026-03-07 19:10:43)19
- Android开发必知:android:layout_gravity与android:gravity的区别解析(阿里通义 | 299点数解答 | 2023-11-07 22:38:25)359
- Android开发必知:android:layout_gravity使用规则全解析(阿里通义 | 411点数解答 | 2023-11-07 22:38:52)377
- Android开发神器TypedArray:轻松读取XML资源属性的秘籍(阿里通义 | 347点数解答 | 2023-11-07 22:40:21)339