zoukankan      html  css  js  c++  java
  • 自定义ViewGroup

    (自定义ViewGroup)

    自定义布局主要是重写两个方法:

    • onMeasure() 这个是写自定义容器的大小。
    • onLayout() 这个是写子元素的布局。 
      我自己写了一个自定义布局,是顺序填充会延对角线进行排列。

    3.1onMeasure()

     @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            /**
             * 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式
             */
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
            int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
    
            // 计算出所有的childView的宽和高
            measureChildren(widthMeasureSpec, heightMeasureSpec);
            /**
             * width和height是当wrap_content时使用的属性。
             */
            int width = 0;
            int height = 0;
            int cCount = getChildCount();
            int cWidth = 0;
            int cHeight = 0;
            /**
             * 在这里计算当wrap_content时,布局的大小。
             */
            for (int i = 0; i < cCount; i++) {
                View childView = getChildAt(i);
                cWidth = childView.getMeasuredWidth();
                cHeight = childView.getMeasuredHeight();
                width += cWidth;
                height += cHeight;
            }
            /**
             * 如果是wrap_content设置为我们计算的值
             * 否则:直接设置为父容器计算的值
             */
            setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth
                    : width, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight
                    : height);
    
        }

    首先要说一下布局计算模式,即最后的EXACTLY。一共有三种计算模式:

    • MeasureSpec.EXACTLY:精确尺寸,相当于具体数值和match_parent。
    • MeasureSpec.AT_MOST:最大尺寸,相当于 warp_content。
    • MeasureSpec.UNSPECIFIED:未指定尺寸,这种情况不多,一般用于AdapterView。

    最后的设定大小时,如果是精确尺寸就是用sizeWidth即获取的尺寸,如果是最大尺寸就是要我们自己计算的那个尺寸了。 
    onMeasure()最主要的功能就是计算wrap_content的尺寸设置尺寸。 
    我将这个方法称为“建画布”,先建了画布才能在上面绘图嘛。

    3.2 onLayout()

    @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int cCount = getChildCount();
    
            /**
             * 遍历所有childView根据其宽和高,以及margin进行布局
             */
            for (int i = 0; i < cCount; i++) {
                View childView = getChildAt(i);
                r = l + childView.getMeasuredWidth();
                b = t + childView.getMeasuredHeight();
                childView.layout(l, t, r, b);
                l += childView.getMeasuredWidth();
                t += childView.getMeasuredHeight();
            }
        }

    这个方法的作用是设置摆放子元素的位置。其中onLayout()传入的l、t、r、b分别是这样 

    • l,t分别对应子元素左上角的left,top坐标
    • r,b分别对应子元素右下角的right,bottom坐标

    并且可以使用childview.getMeasuredWidth()和childView.getMeasureHeight()得到子元素的宽和高。 
    这样就可以来对每个子元素进行布局了。 
    我称这个方法为“定位置”。定完位置后那么子元素就被放到了我们想要的地方。 
    这样一个自定义ViewGroup就可以使用了。 
    xml文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <com.example.layoutdemo.MyLayout.MyLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >
    
            <TextView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#b2dfdb" />
    
            <TextView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#80cbc4" />
    
            <TextView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#4db6ac" />
    
            <TextView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="#26a69a" />
    
    </com.example.layoutdemo.MyLayout.MyLayout>

    最后效果如图: 
    MyLayout

  • 相关阅读:
    java基础多线程
    java反射基础
    JSP-4(Session)
    JSP-3
    JSP-2
    复试计算机专业文献翻译
    jsp
    实现输入输出对应模型
    servlet
    tomcat的入门(1)
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7930742.html
Copyright © 2011-2022 走看看