天天看點

學習安卓小碼哥自定義控件的筆記(四)

<?xml version="1.0" encoding="utf-8"?>
<com.example.wtz.verticallayoutview.VerticallayoutView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark"
    tools:context=".MainActivity">

    <View
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="#f00"/>

    <View
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="#0f0"/>

    <View
        android:layout_width="120dp"
        android:layout_height="50dp"
        android:background="#00f"/>

</com.example.wtz.verticallayoutview.VerticallayoutView>
           
package com.example.wtz.verticallayoutview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

public class VerticallayoutView extends ViewGroup {

    public VerticallayoutView(Context context) {
        super(context);
    }

    public VerticallayoutView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    //onMeasure


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //如果是wrap_content,寬應該是多大?  寬應該是子控件中最大的那個寬度
        //如果是wrap_content,高應該是多大?  高應該是所有子控件的高度之和
        //提前去測量一個子控件,不然待會拿不到子控件的尺寸
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);


        int childWidthMax = getChildWidthMax();
        int childHeightSum = getChildHeightSum();

        switch (widthMode) {
            case MeasureSpec.AT_MOST:
                widthSize = childWidthMax;
                heightSize = childHeightSum;
                break;
            case MeasureSpec.EXACTLY:

                break;
        }

        setMeasuredDimension(widthSize, heightSize);

    }

    //獲得所有子控件的高度之和
    private int getChildHeightSum() {
        int childCount = getChildCount();

        int sumHeight = 0;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            int measuredHeight = childView.getMeasuredHeight();
            sumHeight += measuredHeight;
        }
        Log.d(getClass().getSimpleName(), "getChildHeightSum: sumHeight" + sumHeight);
        return sumHeight;
    }

    //獲得是子控件中最大的那個寬度
    private int getChildWidthMax() {
        int childCount = getChildCount();

        int maxWidth = 0;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //直接通過getWidth是拿不到寬度的
//            int width = childView.getWidth();
            //寫自定義控件時,要通過getMeasuredWidth來拿寬度的
            //有個前提,需要先去測量一下這個子控件,你才能拿得到
            int width = childView.getMeasuredWidth();
            Log.d(getClass().getSimpleName(), "getChildWidthMax: width :" + width);
            if (maxWidth < width) {
                maxWidth = width;
            }
        }
        return maxWidth;
    }

    //設定子控件的排列
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //将子控件們布局到合适的位置
        //周遊子控件,調用子控件的layout方法,去布局到合适的位置
        int childCount = getChildCount();
        int top = 0;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //假如是第一個子控件
            childView.layout(0, top, childView.getMeasuredWidth(), top + childView.getMeasuredHeight());
            top += childView.getMeasuredHeight();
        }
    }
}

           
學習安卓小碼哥自定義控件的筆記(四)