Android自定义之流式布局

流式布局,好处就是父类布局可以自动的判断子孩子是不是需要换行,什么时候需要换行,可以做到网页版的标签的效果。今天就是简单的做了自定义的流式布局。

具体效果:

原理:

其实很简单,Measure  Layout。只需要这两个步骤就可以搞定了。完全的手动去Measure  Layout。

我们看一下代码。

解释就在代码里面做注释了,因为使用为知笔记写的博客,格式不符合代码格式。大家可以看具体的源码。最后又源码下载地址。

1.Measure  测量

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

int widthMode = MeasureSpec.getMode(widthMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

int heightMode = MeasureSpec.getMode(heightMeasureSpec);

int lineHeight = 0 ;

int lineWidth = 0 ;

int width = 0 ;

int height = 0 ;

int childCount = getChildCount();

Log.i("Test", getPaddingLeft() + "==right="  +getPaddingRight());

for (int i = 0; i < childCount; i++) {

View childView = getChildAt(i);

measureChild(childView, widthMeasureSpec, heightMeasureSpec);

MarginLayoutParams params = (MarginLayoutParams)                                       childView.getLayoutParams();

int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ;

int childHeight  = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin ;

if ((lineWidth + childWidth ) > widthSize - getPaddingLeft() - getPaddingRight() ) {

width = Math.max(width, lineWidth);

lineWidth = childWidth ;

height += lineHeight ;

lineHeight = childHeight;

}else {

lineWidth += childWidth ;

lineHeight = Math.max(lineHeight, childHeight);

}

if (i  == childCount-1) {

width = Math.max(width, lineWidth);

height += lineHeight ;

}

}

height += getPaddingTop() + getPaddingBottom() ;

setMeasuredDimension(widthMode == MeasureSpec.EXACTLY?widthSize:width,

heightMode == MeasureSpec.EXACTLY?heightSize:height);

}

2.onLayout  布局

@Override

protected void onLayout(boolean a, int l, int t, int r, int b) {

childViewList.clear();

int childCount = getChildCount() ;

int width = getWidth();

int lineWidth = 0 ;

int lineHeight = 0 ;

List<View> lineViews = new ArrayList<View>();

for (int i = 0; i < childCount; i++) {

View childView = getChildAt(i);

MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();

int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin ;

int childHeight = childView.getMeasuredHeight() + params.topMargin +  params.bottomMargin  ;

if (lineWidth + childWidth > width - getPaddingLeft() - getPaddingRight()) {

childViewList.add(lineViews);

lineViews = new ArrayList<View>();

if (i == 0 ) {

lineHeight += getPaddingTop() ;

}else if (i== childCount - 1) {

lineHeight += getPaddingBottom() ;

}

this.lineHeight.add(lineHeight);

lineHeight = 0 ;

lineWidth = 0 ;

}

lineWidth += childWidth;

lineHeight = Math.max(lineHeight, childHeight) ;

lineViews.add(childView);

}

childViewList.add(lineViews);

this.lineHeight.add(lineHeight);

int left = getPaddingLeft() ;

int top = getPaddingTop();

for (int i = 0; i < childViewList.size(); i++) {

lineViews = childViewList.get(i);

for (int j = 0; j < lineViews.size(); j++) {

View childView = lineViews.get(j);

MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();

int lc = left + params.leftMargin ;

int tc = top + params.topMargin ;

int rc = lc + childView.getMeasuredWidth()  ;

int bc = tc + childView.getMeasuredHeight() ;

childView.layout(lc,tc,rc,bc);

left += params.leftMargin + childView.getMeasuredWidth() + params.rightMargin ;

}

left =  getPaddingLeft() ;

top += this.lineHeight.get(i) ;

}

}

代码下载地址:

百度网盘:  http://pan.baidu.com/s/1hqH1kFU

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-02 06:47:08

Android自定义之流式布局的相关文章

自定义ViewGroup 流式布局

使用 public class MainActivity extends Activity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_flowlayout);         FlowLayout flow_layout = 

ViewGroup2——自定义实现流式布局

Android中的线性布局LinearLayout,只能横向或纵向排列子控件,而且横向排列时不能自动换行.实际上,通过扩展ViewGroup就能够实现控件自动的往右添加,如果当前行剩余空间不足,则自动添加到下一行,也就是所谓的流式布局. 自定义CustomViewGroup.java如下 public class CustomViewGroup extends ViewGroup { int mCellWidth; int mCellHeight; public CustomViewGroup(

100行Android代码自定义一个流式布局-FlowLayout

首先来看一下 手淘HD - 商品详情 - 选择商品属性 页面的UI 商品有很多尺码,而且展现每个尺码所需要的View的大小也不同(主要是宽度),所以在从服务器端拉到数据之前,展现所有尺码所需要的行数和每一行的个数都无法确定,因此不能直接使用GridView或ListView. 如果使用LinearLayout呢? 一个LinearLayout只能显示一行,如果要展示多行,则每一行都要new一个LinearLayout出来,而且还必须要计算出每一个LinearLayout能容纳多少个尺码对应的Vi

Android 自动换行流式布局的RadioGroup

用法 使用FlowRadioGroup代替RadioGroup import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.RadioGroup; /** * 流式布局的RadioGroup */ public class FlowRadioGroup extends RadioGroup { public FlowRadioGr

Android之自定义流式布局FlowLayout

流式布局常常用于“热门标签”中,大概功能就是将所有的子View一行一行的排列,如果一行中剩下的空间不足以盛放下一个子View,则换到另一行继续排列.这样做的好处是不需要在主线程中自己麻烦定义控件的位置,只需要把生成的控件放到容器中,容器自己会自动排列.首先来看一下运行结果: Android中的自定义容器控件(继承自ViewGroup的控件)都有两个必须实现的方法:onMeasure()和onLayout() (1)onMeasure:测量子View的宽和高,设置自己的宽和高,根据自View的布局

Android自定义ViewGroup实现流式布局

实现宽度不足自动换行的流式布局: FlowLayout.java package com.jackie.flowlayout; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * Created by Jackie on 8/28/15. */ public class FlowLayout

android流式布局热门标签的实现

在日常的app使用中,我们会在android 的app中看见热门标签等自动换行的流式布局,今天就为大家分享一种android流式布局的实现. 先看最终效果 自定义流式布局的实现 package com.sunny.flowlayout.view; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.util.AttributeSet; import an

Android中常见的热门标签的流式布局的实现

一.概述:在日常的app使用中,我们会在android 的app中看见 热门标签等自动换行的流式布局,今天,我们就来看看如何 自定义一个类似热门标签那样的流式布局吧(源码下载在下面最后给出) 类似的自定义布局.下面我们就来详细介绍流式布局的应用特点以及用的的技术点: 1.流式布局的特点以及应用场景    特点:当上面一行的空间不够容纳新的TextView时候,    才开辟下一行的空间 原理图: 场景:主要用于关键词搜索或者热门标签等场景2.自定义ViewGroup,重点重写下面两个方法 1.o

Android流式布局实现

查看我的全部开源项目[开源实验室] 欢迎加入我的QQ群:[201055521],本博客客户端下载[请点击] 摘要 新项目用到了一种全新布局----Android标签流式布局的功能,正好一直说给大家讲自定义控件的实现,今天就为大家讲一种android流式布局的实现. 本文原创,转载请注明地址:http://blog.kymjs.com/ 正文 在日常的app使用中,我们会在android 的app中看见热门标签等自动换行的流式布局,今天,我们就来看看如何自定义一个类似热门标签那样的流式布局吧(源码