1、自定义ViewGroup

 /**
* Created by Administrator on 2016/2/26.
*
* --------自动换行的ViewGroup-----------
*/
public class LineWrapLayout extends ViewGroup {
private static final boolean DEBUG = true;
private static final String TAG = "AutoLineFeedLayout"; /**
* 左间距
*/
private int paddingLeft = 10;
/**
* 右间距
*/
private int paddingRight = 10;
/**
*
*/
private int paddingTop = 10;
/**
*
*/
private int paddingBottom = 10; /**
* 水平方向间距
*/
private int horizontalSpace = 10;
/**
* 行间距
*/
private int verticalSpace = 5; private List<Integer> listX;
private List<Integer> listY; public LineWrapLayout(Context context) {
super(context); }
public LineWrapLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
} public LineWrapLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(DEBUG) Log.d(TAG, "--- onLayout changed :" + changed + " l :" + l + ",t :" + t + ",r :" + r + ",b :" + b);
int count = getChildCount();
int width = getWidth();
Log.i(TAG, "宽度 :"+width); int startOffsetX = paddingLeft;// 横坐标开始
int startOffsety = 0;//纵坐标开始
int rowCount = 1; int preEndOffsetX = startOffsetX; for (int i = 0; i < count; i++) {
final View childView = getChildAt(i); int w = childView.getMeasuredWidth();
int h = childView.getMeasuredHeight(); int x = listX.get(i);
int y = listY.get(i); // 布局子控件
childView.layout(x, y, x + w, y + h);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(DEBUG) Log.v(TAG, "--- onMeasure()"); int count = getChildCount();
int width = measureWidth(widthMeasureSpec);
Log.i(TAG, "宽度 :"+width); int startOffsetX = paddingLeft;// 横坐标开始
int startOffsety = 0+paddingTop;//纵坐标开始
int rowCount = 1; int preEndOffsetX = startOffsetX; listX.clear();
listY.clear();
for (int i = 0; i < count; i++) {
Log.v(TAG, "----");
final View childView = getChildAt(i);
// 设置子空间Child的宽高
childView.measure(0,0);
/* 获取子控件Child的宽高 */
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
Log.v(TAG, "childWidth :"+childWidth+" childHeight :"+childHeight);
preEndOffsetX = startOffsetX + childWidth /*+ CHILD_MARGIN*/;
//TODO [yaojian]margin属性?
if (preEndOffsetX > width - paddingRight ) {
if (startOffsetX > paddingLeft) {
/* 换行 */
startOffsetX = paddingLeft;
startOffsety += childHeight+verticalSpace;
rowCount++;
}
}
Log.d(TAG, "measure child :"+startOffsetX+", "+startOffsety+", "+preEndOffsetX+", "+(startOffsety+childHeight));
listX.add(startOffsetX);
listY.add(startOffsety); // childView.layout(startOffsetX, startOffsety, preEndOffsetX, startOffsety+childHeight);
startOffsetX = startOffsetX + childWidth + horizontalSpace;
}
int lastLineHeight = 0;
View lastChild = getChildAt(count-1);
if(null != lastChild){
lastLineHeight = lastChild.getMeasuredHeight();
}
setMeasuredDimension(measureWidth(widthMeasureSpec), startOffsety+lastLineHeight+paddingBottom);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 注意setMeasuredDimension和resolveSize的用法
// setMeasuredDimension(resolveSize(measuredWidth, widthMeasureSpec),
// resolveSize(top, heightMeasureSpec));
} private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec); // Default size if no limits are specified.
int result = 400; if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
} private void init(AttributeSet attrs) {
TypedArray attrArray = getContext().obtainStyledAttributes(attrs, R.styleable.AutoLineFeedLayout);
int attrCount = attrArray.getIndexCount();
for (int i = 0; i < attrCount; i++) {
int attrId = attrArray.getIndex(i);
switch (attrId) {
case R.styleable.AutoLineFeedLayout_horizontalSpacing:{
float dimen = attrArray.getDimension(attrId, 0);
horizontalSpace = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_verticalSpacing:{
float dimen = attrArray.getDimension(attrId, 0);
verticalSpace = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_paddingBottom:{
float dimen = attrArray.getDimension(attrId, 0);
paddingBottom = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_paddingLeft:{
float dimen = attrArray.getDimension(attrId, 0);
paddingLeft = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_paddingRight:{
float dimen = attrArray.getDimension(attrId, 0);
paddingRight = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_paddingTop:{
float dimen = attrArray.getDimension(attrId, 0);
paddingTop = (int) dimen;
}
break;
case R.styleable.AutoLineFeedLayout_debug:{ }
break; default:
break;
} } listX = new ArrayList<Integer>();
listY = new ArrayList<Integer>();
}
}

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);
}

Android--根据子控件的大小自动换行的ViewGroup的更多相关文章

  1. Android ScrollView 子控件不占满的问题

    经常碰到很笨的 ScrollView的子控件无法占满 ScrollView 的空间的问题. 其实只需要加一行,android:fillViewport="true" 但不加上这行就 ...

  2. Android listview子控件的的点击事件(转)

    1.先看图,是否是你想要的 2.布局文件<?xml version="1.0" encoding="utf-8"?><LinearLayout ...

  3. Android ListView 子控件点击事件

    android:descendantFocusability beforeDescendants:viewgroup会优先其子类控件而获取到焦点 afterDescendants:viewgroup只 ...

  4. Android 布局之LinearLayout 子控件weight权重的作用详析(转)

    关于Android开发中的LinearLayout子控件权重android:layout_weigh参数的作用,网上关于其用法有两种截然相反说法: 说法一:值越大,重要性越高,所占用的空间越大: 说法 ...

  5. Android 布局之LinearLayout 子控件weight权重的作用详析

    关于Android开发中的LinearLayout子控件权重android:layout_weigh参数的作用,网上关于其用法有两种截然相反说法: 说法一:值越大,重要性越高,所占用的空间越大: 说法 ...

  6. [转]Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件

      Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件. 1.为了防止拖动ListView时,在列表末尾重复数据显示.需要加入 HashMap<In ...

  7. Android中动态改变控件的大小的一种方法

    在Android中有时候我们需要动态改变控件的大小.有几种办法可以实现  一是在onMeasure中修改尺寸,二是在onLayout中修改位置和尺寸.这个是可以进行位置修改的,onMeasure不行. ...

  8. 记录下帮助一位网友解决的关于android子控件的onTouch或onClick和父OnTouch 冲突的问题。

    前三天收到位网友的私信求助,问题大概如标题所示.具体是下面的情况,个人感觉,这个问题挺有趣,也会在实际项目开发中很常见.不想看前奏的请直接跳至解决方法. 问题原型: 父控件是自定义的 LinearLa ...

  9. Android自定义组合控件内子控件无法显示问题

    今天自定义了一个组合控件,与到了个奇葩问题: 我自定义了一个RelativeLayout,这个layout内有多个子控件.但奇怪的是这些子控件一直显示不出来.调试了一下午,竟然是因为在获取(infla ...

随机推荐

  1. Android之apk优化

    公司的apk越做越大...作为一个有追求的程序员,我觉得有必要给apk瘦身了... 优化之前,先来分析一下apk结构,下面附上一张apk结构图: apk结构.png 由于我这个项目集成了百度地图.百度 ...

  2. 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来定时任务apscheduler库(图文详解)

    不多说,直接上干货!  Anaconda2 里 PS C:\Anaconda2\Scripts> PS C:\Anaconda2\Scripts> pip.exe install apsc ...

  3. Eclipse \ MyEclipse \Scala IDEA for Eclipse里如何将控制台console输出的过程记录全程保存到指定的文本文件(图文详解)

    不多说,直接上干货! 问题详情 运行Java程序的时候,控制台输出过多,或者同时运行多个Java程序,输出结果一闪而过的时候,可以考虑将将控制台输出,改为输出到文本文件.无须修改Java代码,引入流这 ...

  4. spring boot 与 thymeleaf (2): 常用表达式

    在asp.net mvc 中, 有一个视图解析器, 可以支持Razor语法. 使用起来, 是非常的方便, 并且, 写在前台页面的后台方法, 是可调试的. 但是在java中, 目前我还没有接触到, 像. ...

  5. CRM项目再分析建表

    今天老师带着我们分析了一点项目的业务,我们就觉得有些地方呢 有一些不妥额地方,然后呢  我们就在原来表的基础上做了一些修改! 我们也把我们组的项目业务的工作分配了一下! 但是我们遇到了一个组员不和我们 ...

  6. ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(1)

    文章转自:http://www.xuboyi.com/298.html 前言 网站运营有一段时间了,记录的内容都是杂七杂八的,思前想后,决定给大家分享一套ASP.Net的系列教程.手把手的做一套通用后 ...

  7. Windows服务设置

    [服务列表]services.msc [注册服务] 描述:在注册表和服务数据库中创建服务项. 用法:sc <server> create [service name] [binPath= ...

  8. 【angular5项目积累总结】文件上传

    <div class="form-group row"> <label class="col-sm-2 col-form-label"> ...

  9. VB.NET工作记录

    1.字符串移除最后一个字符 s = s.Remove(s.Length - 1, 1) 2.日期格式 常用:yyyy-MM-dd HH:mm:ss 毫秒用fff 字符 说明 (:) 时间分隔符.在某些 ...

  10. JavaSE Collection集合

    集合:是java中提供的一种容器,可以用来存储多个对象.可是我们前面学习的数组也是可以保存多个对象的,为什么还要提供集合容器呢?集合和数组它们有啥区别呢? 数组的长度是固定的.一旦创建完成不能改变长度 ...