自定义组件---瀑布流布局

首先看下效果图:



自定义组件FlowLayoutView代码

<pre name="code" class="java">import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/*
 *  @项目名:  GoegleMarket 
 *  @包名:    
 *  @文件名:   FlowLayoutView
 *  @创建者:   Administrator
 *  @创建时间:  2016/8/1 0001 下午 12:08
 *  @描述:    TODO
 */
public class FlowLayoutView extends ViewGroup {

    private List<LineView> groupList = new ArrayList<>();
    private LineView mCurrentLine;
    private int verticalSpace = 15;

    public FlowLayoutView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FlowLayoutView(Context context) {
        this(context,null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mCurrentLine = null;
        groupList.clear();
        //1.获取宽高信息
        int width = MeasureSpec.getSize(widthMeasureSpec);
//        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        //父容器FlowLayoutvieW给孩子开辟的最大宽度
        int maxWidth = width - getPaddingLeft() - getPaddingRight();
        //2.根据宽高信息计算测量孩子
        //获取孩子的数量,然后测量每个孩子的宽高
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            //获取每个孩子对象
            View child = getChildAt(i);
            //测量孩子
            measureChild(child,widthMeasureSpec,heightMeasureSpec);
            //由于所有的孩子分布在不同的行,所以在测量时进行判断,以便合理的添加孩子
            if (mCurrentLine == null) {
                //该行尚添加,进行添加
                mCurrentLine = new LineView(maxWidth, 14);
                mCurrentLine.addChild(child);
                groupList.add(mCurrentLine);//添加行
            } else {
                if (mCurrentLine.canAddChild(child)) {
                    mCurrentLine.addChild(child);
                } else {
                    //当前行添加孩子已达上限,新建下一行
                    mCurrentLine = new LineView(maxWidth,14);
                    mCurrentLine.addChild(child);
                    groupList.add(mCurrentLine);//添加行
                }
            }

        }
        //3.测量自己
        Toast.makeText(getContext(),"" + groupList.size(),Toast.LENGTH_SHORT).show();
        //根据已经添加的孩子,计算测量
        int height = getPaddingTop();
        for (LineView line : groupList) {
            height += line.height;
            height += verticalSpace;
        }
        setMeasuredDimension(width,height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left = l;
        int top = t + getPaddingTop();
        for (LineView line : groupList) {
            //布局孩子
            line.layout(left,top);
            //更新行参数
            top += line.height;
            top += verticalSpace;
        }
    }


    class LineView{
        public int maxWidh;
        public int height;
        public int Horizontolspace;
        public List<View> childList = new ArrayList<>();
        public int usedWidth;

        public LineView(int maxWidh, int horizontolspace) {
            this.maxWidh = maxWidh;
            Horizontolspace = horizontolspace;
        }

	/**
	 * 是否可以继续添加孩子
         * @param child
         * @return
         */
        public boolean canAddChild(View child){
            if (childList.size() == 0) {
                //没有孩子时,第一个孩子必然可以添加
                return true;
            }
            //获取孩子的宽度
            int childWidth = child.getMeasuredWidth();
            if (usedWidth + Horizontolspace + childWidth > maxWidh) {
                return false;
            }
           return true;
        }

	/**
	 * 添加孩子的方法
         * @param child
         */

        public void addChild(View child) {
            //获取孩子的宽高
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();
            //添加孩子
            childList.add(child);
            //更新已使用的宽度信息
            usedWidth += childWidth;
            usedWidth += Horizontolspace;
            //根据添加进来的孩子,动态获取行的高度
            height = height > childHeight ? height : childHeight;
        }

        /**
         * 在行内布局孩子的方法
         * @param l left
         * @param t top
         */
        public void layout(int l,int t){
            for (View child : childList) {
                int left = l;
                int top = t;
                int right = left + child.getMeasuredWidth();
                int bottom = top + child.getMeasuredHeight();
                //布局孩子
                child.layout(left,top,right,bottom);
                //从每行的第二个孩子开始添加前更新l
                l += child.getWidth();
                l += Horizontolspace;
            }
        }
    }


}

 接着就可将其作为一个依赖的Lib库,引用到所需要的地方了 

 @Override
    protected View getChildSuccessView() {
	//rankfragment的具体化view页面
	ScrollView scrollView = new ScrollView(UiUtil.getContext());
	scrollView.setFillViewport(true);
	//创建flowLayout对象
	FlowLayoutView flowLayoutView = new FlowLayoutView(UiUtil.getContext());
	flowLayoutView.setPadding(5,5,5,5);
	//循环添加孩子的内容
	for (String textContent : mData) {
	    TextView textView = new TextView(getContext());
	    textView.setTextSize(16);
	    textView.setPadding(5, 5, 5, 5);
	    textView.setGravity(Gravity.CENTER);
	    textView.setText(textContent);

	    //生成随机颜色背景
	    Random random = new Random();
	    int alpha = 255;
	    int r = 80 + random.nextInt(155);
	    int g = 80 + random.nextInt(155);
	    int b = 80 + random.nextInt(155);

	    //添加颜色背景需要gradientDrawable
	    GradientDrawable gradientDrawable = new GradientDrawable();
	    gradientDrawable.setCornerRadius(5);
	    gradientDrawable.setShape(GradientDrawable.RECTANGLE);
	    gradientDrawable.setColor(Color.argb(alpha, r, g, b));

	    //按压下的状态
	    GradientDrawable particalDrawable = new GradientDrawable();
	    particalDrawable.setCornerRadius(5);
	    particalDrawable.setShape(GradientDrawable.RECTANGLE);
	    particalDrawable.setColor(Color.GRAY);
	    //创建状态选择器
	    StateListDrawable selector = new StateListDrawable();
	    selector.addState(new int[]{android.R.attr.state_pressed}, particalDrawable);
	    selector.addState(new int[]{}, gradientDrawable);

	    //设置背景
	    textView.setBackground(selector);
	    //设置点击事件
	    textView.setOnClickListener(new View.OnClickListener() {
		@Override
		public void onClick(View v) {

		}
	    });

	    //添加到flowLayout中
	    flowLayoutView.addView(textView,
				   new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
							      ViewGroup.LayoutParams.WRAP_CONTENT));
	}

	//将flowLayout添加到scrollView中
	scrollView.addView(flowLayoutView);
	return scrollView;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值