Android自定义View之自定义一个简单的阶梯式布局
Posted fakerXuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义View之自定义一个简单的阶梯式布局相关的知识,希望对你有一定的参考价值。
- onMeasure:
- 确定自身的大小
- 确定子View的大小
流程:
1. ViewGroup开始测量自己的尺寸
2. 为每个子View计算测量的限制信息
3. 把上一步确定的限制信息,传递给每一个字View,然后子View开始measure自己的尺寸
4. 获取子View测量完成后的尺寸
5. ViewGroup根据自身的情况,计算自己的尺寸
6. 保存自身的尺寸
onLayout:
1. 根据规则确定子View位置
流程:
1. 遍历子View
2. 确定自己的规则
3. 子View的测量尺寸
4. left,top,right,bottom
5. child.layout
- 效果
- 代码
自定义View代码
package com.example.as.proj.myviewgroupdemo2;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import java.util.jar.Attributes;
public class MyViewGroup extends ViewGroup {
public static final int OFFSET = 100; //表示缩进尺寸
public MyViewGroup(Context context){
super(context);
}
public MyViewGroup(Context context, AttributeSet attrs){
super(context, attrs);
}
public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//测量自身
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//2.为每个子View计算测量的限制信息, Mode Size
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//把上一步确定的限制信息,传递给每一个子View,然后子View开始measure自己的尺寸
int childCount = getChildCount();
for(int i = 0; i < childCount; i++){
View child = getChildAt(i);
ViewGroup.LayoutParams lp = child.getLayoutParams();
int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
int childHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
child.measure(childWidthSpec, childHeightSpec);
}
int width = 0;
int height = 0;
//h获取子View测量完成后的尺寸
//viewgroup 根据自身的情况,奢姿自己的尺寸
switch (widthMode){
case MeasureSpec.EXACTLY:
width = widthSize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
for(int i = 0; i < childCount; i++){
View child = getChildAt(i);
int widthAddOffset = i * OFFSET + child.getMeasuredWidth();
width = Math.max(width, widthAddOffset);//取最大宽度
}
break;
default:
break;
}
switch (heightMode){
case MeasureSpec.EXACTLY:
height = heightSize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
for(int i = 0; i < childCount; i++){
View child = getChildAt(i);
height += child.getMeasuredHeight();
}
break;
default:
break;
}
//保存自身的尺寸
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//遍历子View
//确定自己的规则
//子View的测量尺寸
//left top right bottom
//child.layout
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
int childCount = getChildCount();
for(int i = 0; i < childCount; i++){
View child = getChildAt(i);
left = i * OFFSET;
right = left + child.getMeasuredWidth();
bottom = top + child.getMeasuredHeight();
child.layout(left, top, right, bottom);
top += child.getMeasuredHeight();
}
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.example.as.proj.myviewgroupdemo2.MyViewGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
</com.example.as.proj.myviewgroupdemo2.MyViewGroup>
以上是关于Android自定义View之自定义一个简单的阶梯式布局的主要内容,如果未能解决你的问题,请参考以下文章