• Android--根据子控件的大小自动换行的ViewGroup


    1、自定义ViewGroup

      1 /**
      2  * Created by Administrator on 2016/2/26.
      3  *
      4  * --------自动换行的ViewGroup-----------
      5  */
      6 public class LineWrapLayout extends ViewGroup {
      7     private static final boolean DEBUG = true;
      8     private static final String TAG = "AutoLineFeedLayout";
      9 
     10     /**
     11      * 左间距
     12      */
     13     private int paddingLeft = 10;
     14     /**
     15      * 右间距
     16      */
     17     private int paddingRight = 10;
     18     /**
     19      *
     20      */
     21     private int paddingTop = 10;
     22     /**
     23      *
     24      */
     25     private int paddingBottom = 10;
     26 
     27     /**
     28      * 水平方向间距
     29      */
     30     private int horizontalSpace = 10;
     31     /**
     32      * 行间距
     33      */
     34     private int verticalSpace = 5;
     35 
     36 
     37     private List<Integer> listX;
     38     private List<Integer> listY;
     39 
     40     public LineWrapLayout(Context context) {
     41         super(context);
     42 
     43     }
     44     public LineWrapLayout(Context context, AttributeSet attrs) {
     45         super(context, attrs);
     46         init(attrs);
     47     }
     48 
     49     public LineWrapLayout(Context context, AttributeSet attrs, int defStyle) {
     50         super(context, attrs, defStyle);
     51         init(attrs);
     52     }
     53 
     54 
     55     @Override
     56     protected void onLayout(boolean changed, int l, int t, int r, int b) {
     57         if(DEBUG) Log.d(TAG, "--- onLayout changed :" + changed + " l :" + l + ",t :" + t + ",r :" + r + ",b :" + b);
     58         int count = getChildCount();
     59         int width = getWidth();
     60         Log.i(TAG, "宽度 :"+width);
     61 
     62 
     63         int startOffsetX = paddingLeft;// 横坐标开始
     64         int startOffsety = 0;//纵坐标开始
     65         int rowCount = 1;
     66 
     67         int preEndOffsetX = startOffsetX;
     68 
     69         for (int i = 0; i < count; i++) {
     70             final View childView = getChildAt(i);
     71 
     72             int w = childView.getMeasuredWidth();
     73             int h = childView.getMeasuredHeight();
     74 
     75             int x = listX.get(i);
     76             int y = listY.get(i);
     77 
     78             // 布局子控件
     79             childView.layout(x, y, x + w, y + h);
     80         }
     81     }
     82     @Override
     83     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     84         if(DEBUG) Log.v(TAG, "--- onMeasure()");
     85 
     86         int count = getChildCount();
     87         int width = measureWidth(widthMeasureSpec);
     88         Log.i(TAG, "宽度 :"+width);
     89 
     90 
     91         int startOffsetX = paddingLeft;// 横坐标开始
     92         int startOffsety = 0+paddingTop;//纵坐标开始
     93         int rowCount = 1;
     94 
     95         int preEndOffsetX = startOffsetX;
     96 
     97         listX.clear();
     98         listY.clear();
     99         for (int i = 0; i < count; i++) {
    100             Log.v(TAG, "----");
    101             final View childView = getChildAt(i);
    102             // 设置子空间Child的宽高
    103             childView.measure(0,0);
    104             /* 获取子控件Child的宽高 */
    105             int childWidth = childView.getMeasuredWidth();
    106             int childHeight = childView.getMeasuredHeight();
    107             Log.v(TAG, "childWidth :"+childWidth+" childHeight :"+childHeight);
    108             preEndOffsetX = startOffsetX + childWidth /*+ CHILD_MARGIN*/;
    109             //TODO [yaojian]margin属性?
    110             if (preEndOffsetX > width - paddingRight ) {
    111                 if (startOffsetX > paddingLeft) {
    112                     /* 换行  */
    113                     startOffsetX = paddingLeft;
    114                     startOffsety += childHeight+verticalSpace;
    115                     rowCount++;
    116                 }
    117             }
    118             Log.d(TAG, "measure child :"+startOffsetX+", "+startOffsety+", "+preEndOffsetX+", "+(startOffsety+childHeight));
    119             listX.add(startOffsetX);
    120             listY.add(startOffsety);
    121 
    122 //            childView.layout(startOffsetX, startOffsety, preEndOffsetX, startOffsety+childHeight);
    123             startOffsetX = startOffsetX + childWidth + horizontalSpace;
    124         }
    125         int lastLineHeight = 0;
    126         View lastChild = getChildAt(count-1);
    127         if(null != lastChild){
    128             lastLineHeight = lastChild.getMeasuredHeight();
    129         }
    130         setMeasuredDimension(measureWidth(widthMeasureSpec), startOffsety+lastLineHeight+paddingBottom);
    131 //        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    132 
    133         // 注意setMeasuredDimension和resolveSize的用法
    134 //        setMeasuredDimension(resolveSize(measuredWidth, widthMeasureSpec),
    135 //                resolveSize(top, heightMeasureSpec));
    136     }
    137 
    138     private int measureWidth(int measureSpec) {
    139         int specMode = MeasureSpec.getMode(measureSpec);
    140         int specSize = MeasureSpec.getSize(measureSpec);
    141 
    142 
    143         // Default size if no limits are specified.
    144         int result = 400;
    145 
    146         if (specMode == MeasureSpec.AT_MOST) {
    147             // Calculate the ideal size of your control
    148             // within this maximum size.
    149             // If your control fills the available space
    150             // return the outer bound.
    151             result = specSize;
    152         } else if (specMode == MeasureSpec.EXACTLY) {
    153             // If your control can fit within these bounds return that value.
    154             result = specSize;
    155         }
    156         return result;
    157     }
    158 
    159     private void init(AttributeSet attrs) {
    160         TypedArray attrArray = getContext().obtainStyledAttributes(attrs, R.styleable.AutoLineFeedLayout);
    161         int attrCount = attrArray.getIndexCount();
    162         for (int i = 0; i < attrCount; i++) {
    163             int attrId = attrArray.getIndex(i);
    164             switch (attrId) {
    165                 case R.styleable.AutoLineFeedLayout_horizontalSpacing:{
    166                     float dimen = attrArray.getDimension(attrId, 0);
    167                     horizontalSpace = (int) dimen;
    168                 }
    169                 break;
    170                 case R.styleable.AutoLineFeedLayout_verticalSpacing:{
    171                     float dimen = attrArray.getDimension(attrId, 0);
    172                     verticalSpace = (int) dimen;
    173                 }
    174                 break;
    175                 case R.styleable.AutoLineFeedLayout_paddingBottom:{
    176                     float dimen = attrArray.getDimension(attrId, 0);
    177                     paddingBottom = (int) dimen;
    178                 }
    179                 break;
    180                 case R.styleable.AutoLineFeedLayout_paddingLeft:{
    181                     float dimen = attrArray.getDimension(attrId, 0);
    182                     paddingLeft = (int) dimen;
    183                 }
    184                 break;
    185                 case R.styleable.AutoLineFeedLayout_paddingRight:{
    186                     float dimen = attrArray.getDimension(attrId, 0);
    187                     paddingRight = (int) dimen;
    188                 }
    189                 break;
    190                 case R.styleable.AutoLineFeedLayout_paddingTop:{
    191                     float dimen = attrArray.getDimension(attrId, 0);
    192                     paddingTop = (int) dimen;
    193                 }
    194                 break;
    195                 case R.styleable.AutoLineFeedLayout_debug:{
    196 
    197                 }
    198                 break;
    199 
    200                 default:
    201                     break;
    202             }
    203 
    204         }
    205 
    206         listX = new ArrayList<Integer>();
    207         listY = new ArrayList<Integer>();
    208     }
    209 }

    2、有一部分自定义属性可供使用 attrs.xml

        <declare-styleable name="AutoLineFeedLayout">
            <attr name="debug" format="boolean"></attr>
    
            <attr name="paddingLeft" format="reference|dimension"/>
            <attr name="paddingRight" format="reference|dimension"/>
            <attr name="paddingTop" format="reference|dimension"/>
            <attr name="paddingBottom" format="reference|dimension"/>
    
            <attr name="verticalSpacing" format="reference|dimension"/>
            <attr name="horizontalSpacing" format="reference|dimension"/>
        </declare-styleable>

    3、在布局文件中和普通ViewGroup使用相同

    4、在Activity中动态添加View或者ViewGroup

    for (int i = 0;i < myData.getList().length;i++){
                            View child = View.inflate(ZhuanTiActivity.this,R.layout.item_mygridview_layout,null);
                            TextView textView = (TextView) child.findViewById(R.id.tv_title_item);
                            textView.setText(myData.getList()[i].getName());
                            textView.setTextColor(Color.argb(255, colorR, colorG, colorB));
                            textView.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    Log.d("aaa",textView.getText());
                                }
                            });
                            custom_index_zhuanTiActivity.addView(child);
                        }
  • 相关阅读:
    Pass360[最新].cpp
    在任意的远程桌面的session中运行指定的程序
    C++内存泄露的检测(三)
    在release模式下debug
    [转]VC Studio 使用技巧大全
    C++内存泄露的检测(一)
    获取系统用户所对应的配置路径
    关于Debug和Release之本质区别的讨论
    GDB 的使用
    struct termios
  • 原文地址:https://www.cnblogs.com/819158327fan/p/5222039.html
Copyright © 2020-2023  润新知