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

来源:互联网 发布:java 数组去重效率 编辑:程序博客网 时间:2024/05/05 19:38

首先看下效果图:



自定义组件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() {@Overridepublic 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;    }



1 0