自定义view实现流式布局
来源:互联网 发布:淘宝直通车的作用 编辑:程序博客网 时间:2024/05/20 10:12
显示效果如下,自定义view,重写onMeasure方法,测量wrap_content模式下控件的宽高,重写onLayout的方法,布局里面的子view,支持paddign属性.其实整个逻辑并不复杂,各位猿友可别复制粘贴啊!
/** * Created by Administrator on 2017/7/24. */public class MyFlowLayout extends ViewGroup{ //存储所有的view,行数就是该集合的元素个数 private List<List<View>> mAllViews=new ArrayList<>(); //记录每一行的行高,行数就是该集合的元素个数 private List<Integer> mLineHeight=new ArrayList<>(); public MyFlowLayout(Context context) { this(context,null); } public MyFlowLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int modeWidth = MeasureSpec.getMode(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); int modeHeight = MeasureSpec.getMode(heightMeasureSpec); //wrap_content时,需要自己计算宽高 int width=0; int height=0; //记录每一行的宽度和高度 int lineWidth=0; int lineHeight=0; //得到内部元素的个数 int cCount=getChildCount(); for (int i = 0; i < cCount; i++) { View child = getChildAt(i); //测量子view的宽和高 measureChild(child,widthMeasureSpec,heightMeasureSpec); //得到layoutParams MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); //子view占据的宽度 int childWidth=child.getMeasuredWidth()+lp.leftMargin+lp.rightMargin; //子view占据的高度 int childHeight=child.getMeasuredHeight()+lp.topMargin+lp.bottomMargin; //换行 if (lineWidth+childWidth>sizeWidth-getPaddingLeft()-getPaddingRight()) { //对比得到最大的宽度 width= Math.max(width,lineWidth); //重置lineWidth lineWidth=childWidth; //记录行高 height+=lineHeight; lineHeight=childHeight; } else { //叠加行宽 lineWidth+=childWidth; //得到当前行最大的高度 lineHeight=Math.max(lineHeight,childHeight); } //如果是最后一个控件 if (i==cCount-1) { width=Math.max(width,lineWidth); height+=lineHeight; } } setMeasuredDimension(modeWidth==MeasureSpec.EXACTLY?sizeWidth:width+getPaddingLeft()+getPaddingRight(), modeHeight==MeasureSpec.EXACTLY?sizeHeight:height+getPaddingBottom()+getPaddingTop()); //super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { //清除数据,因为会重复调用 mAllViews.clear(); mLineHeight.clear(); //当前viewgroup的宽度 int width=getWidth(); int lineWidth=0; int lineHeight=0; List<View> lineViews=new ArrayList<>(); int cCount=getChildCount(); for (int i = 0; i < cCount; i++) { View child = getChildAt(i); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth=child.getMeasuredWidth(); int childHeight=child.getMeasuredHeight(); //如果需要换行 if (childWidth+lp.leftMargin+lp.rightMargin+lineWidth>width) { //记录lineHeight mLineHeight.add(lineHeight); //记录当期的views mAllViews.add(lineViews); //重置我们的行宽和行高 lineWidth=0; lineHeight=childHeight+lp.topMargin+lp.bottomMargin; //重置我们的view集合 lineViews=new ArrayList<>(); } lineWidth+=childWidth+lp.leftMargin+lp.rightMargin; lineHeight=Math.max(lineHeight,childHeight+lp.topMargin+lp.bottomMargin); lineViews.add(child); } //处理最后一行 mLineHeight.add(lineHeight); mAllViews.add(lineViews); //设置子view的位置 int left=getPaddingLeft(); int top=getPaddingTop(); //行数 int lineNum=mAllViews.size(); for (int i = 0; i < lineNum; i++) { lineViews=mAllViews.get(i); lineHeight = mLineHeight.get(i); for (int j = 0; j < lineViews.size(); j++) { View child = lineViews.get(j); //判断child的状态 if (child.getVisibility()==GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int lc=left+lp.leftMargin; int tc=top+lp.topMargin; int rc=lc+child.getMeasuredWidth(); int bc=tc+child.getMeasuredHeight(); //为子view进行布局 child.layout(lc,tc,rc,bc); left+=child.getMeasuredWidth()+lp.leftMargin+lp.rightMargin; } left=getPaddingLeft(); top+=lineHeight; } } //与当前viewgroup对应的layoutParams @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(),attrs); }}
阅读全文
0 0
- android 自定义view实现流式布局
- Android自定义View实现流式布局
- 自定义view实现流式布局
- 自定义View流式布局
- 简单自定义View流式布局实现模版
- 自定义RelativeLayout view实现布局。
- android 自定义view 流式布局
- 28 自定义View流式布局
- 自定义view之流式布局
- android自定义view实现流式布局(FlowLayout)和热门标签
- Android自定义View实现流式布局(热门标签效果)
- 自定义LinearLayout并搭配流式布局,实现商城app商品规格选择View
- Android中的自定义View(二)之 流式布局实现
- 自定义ViewGroup实现view的自由布局
- 自定义 流式布局实现
- Android--View自定义—标签<流式布局>
- 自定义View实例(三)----滑动刻度尺与流式布局
- 自定义ViewGroup实现流式布局(支持ViewGroup Padding, 子View margin,每行高度可以不一样)
- 日期选取器、单滚轮选取器、多滚轮选取器、滚轮内容根据环境变化、自定义选取器创建一个简单游戏( 抽奖机 )
- 中国人工智能大会报告现场速记-基本情况(一)
- Android 反编译apk 语句
- Kafka无消息丢失配置
- Java中面向对象分拣存储
- 自定义view实现流式布局
- PenTbox工具学习入门
- nginx的重定向与反向代理
- Masonry介绍与使用实践(快速上手Autolayout)
- java事件监听机制,spring中的event listener模式和解耦
- MTK平台user版本下怎样开启和抓取MTKlog
- Oracle 之 ORA-01847: day of month must be between 1 and last day of month
- --nodeps强制删除pcre后再安装报错
- curl模拟提交(post)