Android自定义View之自定义一个简单的阶梯式布局

Posted fakerXuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义View之自定义一个简单的阶梯式布局相关的知识,希望对你有一定的参考价值。

  • onMeasure:
    1. 确定自身的大小
    2. 确定子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之自定义一个简单的阶梯式布局的主要内容,如果未能解决你的问题,请参考以下文章

Android - View之自定义View实现“刮刮卡”效果

Android 自定义View之自绘控件

android进阶之自定义view(文字圆形边框)

Android自定义View之自定义drawable

Android自定义View之自定义drawable

Android自定义View之自定义drawable