• 自定义ViewGroup的一个小例子


    自定义ViewGroup的的讲解有很多,没必要再过多的赘述,网上一搜一大把,下面写一个简单的例子,供自己以后复习的时候可以用到。

    • 自定义属性
      在values下面新建一个attrs.xml文件,用来自定义属性
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CascadeLayout">
            <attr name="horizontal_spacing" format="dimension"/>
            <attr name="veritcal_spacing" format="dimension"/>
        </declare-styleable>
    </resources>
    • 新建两个属性的默认的尺寸大小在dimens.xml文件中
     <dimen name="default_horizontal_spacing">15dp</dimen>
     <dimen name="default_vertical_spacing">15dp</dimen>
    • 构建我们的主体类CascadeLayout
    package com.gearmotion.app.cascadeviewgroupmotion;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    
    /**
     * Created by Charles on 2016/3/22.
     */
    public class CascadeLayout extends ViewGroup {
    
       //水平间距
       private int mHorizontalSpacing;
       //垂直间距
       private int mVerticalSpacing;
    
       public CascadeLayout(Context context) {
          this(context, null);
       }
    
       public CascadeLayout(Context context, AttributeSet attrs) {
          super(context, attrs);
          TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CascadeLayout);
          mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.CascadeLayout_horizontal_spacing,
                  this.getResources().getDimensionPixelSize(R.dimen.default_horizontal_spacing));
          mVerticalSpacing = a.getDimensionPixelSize(R.styleable.CascadeLayout_veritcal_spacing, this
                  .getResources().getDimensionPixelSize(R.dimen.default_vertical_spacing));
          a.recycle();
       }
    
       @Override
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          final int count = this.getChildCount();
          int width = 0;
          int height = 0;
          for (int i = 0; i < count; i++) {
             View currentView = this.getChildAt(i);
             //对每个子view测量
             measureChild(currentView, widthMeasureSpec, heightMeasureSpec);
             LayoutParams lp = (LayoutParams) currentView.getLayoutParams();
             width = getPaddingLeft() + mHorizontalSpacing * i;
             height = getPaddingTop() + mVerticalSpacing * i;
             //设置每个子view的坐标信息
             lp.x = width;
             lp.y = height;
          }
          width += getChildAt(count - 1).getMeasuredWidth();
          height += getChildAt(count - 1).getMeasuredHeight();
          setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height,
                  heightMeasureSpec));
       }
    
       @Override
       protected void onLayout(boolean changed, int l, int t, int r, int b) {
          final int count = this.getChildCount();
          for (int i = 0; i < count; i++) {
             View view = this.getChildAt(i);
             LayoutParams lp = (LayoutParams) view.getLayoutParams();
             view.layout(lp.x, lp.y, lp.x + view.getMeasuredWidth(), lp.y + view.getMeasuredHeight());
          }
       }
    
       @Override
       protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
          return p instanceof LayoutParams;
       }
    
       @Override
       protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
          return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams
                  .WRAP_CONTENT);
       }
    
       @Override
       protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
          return new LayoutParams(p);
       }
    
       //创建自定义LayoutParams用来记录位置信息
       private static class LayoutParams extends ViewGroup.LayoutParams {
          //用来保存坐标信息
          public int x;
          public int y;
    
          public LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
          }
    
          public LayoutParams(ViewGroup.LayoutParams source) {
             super(source);
          }
    
          public LayoutParams(int width, int height) {
             super(width, height);
          }
       }
    }
    
    • xml布局文件
    <?xml version="1.0" encoding="utf-8"?>
    <com.gearmotion.app.cascadeviewgroupmotion.CascadeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:ns="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ns:horizontal_spacing="20dp"
        ns:veritcal_spacing="20dp"
        tools:context="com.gearmotion.app.cascadeviewgroupmotion.MainActivity">
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#668B8B"/>
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#00FF00"/>
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#FF6A6A"/>
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#9BCD9B"/>
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#000080"/>
    </com.gearmotion.app.cascadeviewgroupmotion.CascadeLayout>
    
    • 最后显示的效果如下:
      这里写图片描述
  • 相关阅读:
    Linux rsync 命令详解
    docker 容器间网络配置
    git合并分支
    基于Docker的Mysql主从复制搭建
    MySQL字符串函数substring:字符串截取
    mysql 存储过程
    分布式系统唯一ID生成方案汇总 转
    mysql 比较函数和操作符
    Distributed PostgreSQL on a Google Spanner Architecture – Storage Layer
    Distributed PostgreSQL on a Google Spanner Architecture – Query Layer
  • 原文地址:https://www.cnblogs.com/summerpxy/p/13648336.html
Copyright © 2020-2023  润新知