Android--根据子控件的大小自动换行的ViewGroup
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的更多相关文章
- Android ScrollView 子控件不占满的问题
经常碰到很笨的 ScrollView的子控件无法占满 ScrollView 的空间的问题. 其实只需要加一行,android:fillViewport="true" 但不加上这行就 ...
- Android listview子控件的的点击事件(转)
1.先看图,是否是你想要的 2.布局文件<?xml version="1.0" encoding="utf-8"?><LinearLayout ...
- Android ListView 子控件点击事件
android:descendantFocusability beforeDescendants:viewgroup会优先其子类控件而获取到焦点 afterDescendants:viewgroup只 ...
- Android 布局之LinearLayout 子控件weight权重的作用详析(转)
关于Android开发中的LinearLayout子控件权重android:layout_weigh参数的作用,网上关于其用法有两种截然相反说法: 说法一:值越大,重要性越高,所占用的空间越大: 说法 ...
- Android 布局之LinearLayout 子控件weight权重的作用详析
关于Android开发中的LinearLayout子控件权重android:layout_weigh参数的作用,网上关于其用法有两种截然相反说法: 说法一:值越大,重要性越高,所占用的空间越大: 说法 ...
- [转]Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件
Android ListView最佳处理方式,ListView拖动防重复数据显示,单击响应子控件. 1.为了防止拖动ListView时,在列表末尾重复数据显示.需要加入 HashMap<In ...
- Android中动态改变控件的大小的一种方法
在Android中有时候我们需要动态改变控件的大小.有几种办法可以实现 一是在onMeasure中修改尺寸,二是在onLayout中修改位置和尺寸.这个是可以进行位置修改的,onMeasure不行. ...
- 记录下帮助一位网友解决的关于android子控件的onTouch或onClick和父OnTouch 冲突的问题。
前三天收到位网友的私信求助,问题大概如标题所示.具体是下面的情况,个人感觉,这个问题挺有趣,也会在实际项目开发中很常见.不想看前奏的请直接跳至解决方法. 问题原型: 父控件是自定义的 LinearLa ...
- Android自定义组合控件内子控件无法显示问题
今天自定义了一个组合控件,与到了个奇葩问题: 我自定义了一个RelativeLayout,这个layout内有多个子控件.但奇怪的是这些子控件一直显示不出来.调试了一下午,竟然是因为在获取(infla ...
随机推荐
- 从用户浏览器输入url到用户看到页面结果的过程,发生了什么事情?
1.域名解析 域名解析的过程: 1).查询浏览器自身DNS缓存 2).若上面没有查找到,则搜索操作系统自身的dns缓存 3).若上面没有找到,则尝试读取hosts文件 4).若上面没有找到,向本地配 ...
- ThreadLocal是否会引发内存泄露的分析 good
这篇文章,主要解决一下疑惑: 1. ThreadLocal.ThreadLocalMap中提到的弱引用,弱引用究竟会不会被回收? 2. 弱引用什么情况下回收? 3. JAVA的ThreadLocal和 ...
- jenkins 通过shell启动tomcat会随着job完成而被自动关闭的解决方法
jenkins 通过shell启动tomcat会随着job完成而被自动关闭的解决方法 填入BUILD_ID=随便填什么 原理是:我不知道
- JAVA面试精选【Java基础第三部分】
上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...
- CentOS安装PHP7+Nginx+MySQL
本文属于动手搭建PHP开发环境的一部分,更多点击链接查看. 本文以centos6为例.命令部分均省略sudo命令. 安装PHP 下载 http://cn2.php.net/distributions/ ...
- 面试:C++输入数据
最近在做笔试题,相比与leetcode,笔试题都是要自己写输入输出的,每次在这里都浪费了不少时间,这篇文章总结了一下在C++中怎么向数组中输入数据. 1. 先输入数组大小,然后输入数据数据,中间以空格 ...
- vi/vim编辑器必知必会
一.我们为什么要学习vim编辑器? Linux的命令行界面下面有非常多的文本编辑器.比如经常听说的就有Emacs.pico.nano.joe与vim等.vim可以看做是vi的高级版.我们为什么一定要学 ...
- laravel 区块继承
看到我的文章感觉有用的话,在评论区下面扣1,能够让我感受到你们的存在,也给我动力继续写的更好,谢谢 定义: 在layouts\admin.blade.php @yield('要定义的区块名') @yi ...
- 基于spring boot的定时器
首先,搭建好一个springboot项目 方法一:通过springboot自带入口来开启定时器. 首先我们都知道,springboot有一个自己的入口,也就是@SpringBootApplicatio ...
- abp运行机制分析
abp运行流程 由于公司现在大量向abp框架+react前后端分离架构转型,所以有必要分析abp框架是如何在iis运行的,所以才有这篇文章 public class MvcApplication : ...