Android瀑布流实现二

来源:互联网 发布:暗黑3数据库app 编辑:程序博客网 时间:2024/06/08 06:12
public class FlowView extends ViewGroup {    // 用来记录描述有多少行View    private List<LineView> mLineViews = new ArrayList<LineView>();    // 用来记录当前已经添加到了哪一行    private LineView mCurrentLineView;    private int mHorizontalSpace = 20;//水平间隔    private int mVerticalSpace = 20;//垂直间隔    public FlowView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public FlowView(Context context) {        this(context, null);    }    /**     * 向外公布的方法     * @param horizontalSpace     * @param VerticalSpace     */    public void setSpace(int horizontalSpace, int VerticalSpace){        this.mHorizontalSpace = horizontalSpace;        this.mVerticalSpace = VerticalSpace;    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // 给Child 布局---> 给Line布局        int paddingLeft = getPaddingLeft();        int paddingTop = getPaddingTop();        for (int i = 0; i < mLineViews.size(); i++) {            LineView lineView = mLineViews.get(i);            //给每个lineViewlayout即可            lineView.layout(paddingLeft, paddingTop);            //表示下一行的高度            paddingTop += mVerticalSpace + lineView.mHeight;        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //清空        mLineViews.clear();        mCurrentLineView = null;        //获得布局的宽度        int layoutWidth = MeasureSpec.getSize(widthMeasureSpec);        //获取行最大的宽度        int maxWidth = layoutWidth - getPaddingLeft() - getPaddingRight();        // 测量孩子        int count = getChildCount();        for (int i = 0; i < count; i++) {            View view = getChildAt(i);            //如果孩子不可见,就不必测量            if (view.getVisibility() == View.GONE) {                continue;            }            //测量孩子            measureChild(view, widthMeasureSpec, heightMeasureSpec);            //子行添加view            if (mCurrentLineView == null) {                mCurrentLineView = new LineView(maxWidth, mHorizontalSpace);                //添加到行中                mLineViews.add(mCurrentLineView);                //航中一个孩子没有                mCurrentLineView.addView(view);            }else {                //行不空,说明有孩子                if (mCurrentLineView.canAdd(view)) {                    // 可以添加                    mCurrentLineView.addView(view);                }else {                    //添加不下去,换行添加                    mCurrentLineView = new LineView(maxWidth, mHorizontalSpace);                    //添加到集合                    mLineViews.add(mCurrentLineView);                    // 将view添加到line                    mCurrentLineView.addView(view);                }            }        }        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //设置自己的宽度与高度        int measuredWidth = layoutWidth;        float allHeight = 0;        for (int i = 0; i < mLineViews.size(); i++) {            float height = mLineViews.get(i).mHeight;            // 加行高            allHeight += height;            if (i != 0) {                // 加间距                allHeight += mVerticalSpace;            }        }        int measuredHeight = (int) (getPaddingBottom() + getPaddingTop() + allHeight + 0.5f);        //测量自身的高度        setMeasuredDimension(measuredWidth, measuredHeight);    }    class LineView {        public List<View> mViews = new ArrayList<View>();// 用来记录每一行有几个View        public int mUsedWidth;//已使用的宽度        public int mMaxWidth;//最大宽度        public int mHorizontalSpace;//// View和view之间的水平间距        public int mHeight;//高度        public int mMaginLeft;        public int mMaginBottom;        public int mMaginRight;        public int mMaginTop;        public LineView(int maxWidth, int space){            this.mMaxWidth = maxWidth;            this.mHorizontalSpace = space;        }        /**         * 给孩子布局         *          * @param paddingLeft         * @param paddingTop         */        public void layout(int paddingLeft, int paddingTop) {            int currentLeft = paddingLeft;            //把剩余的空间评分            float extra = 0;            float widthAvg = 0;            int size = mViews.size();            // 判断已经使用的宽度是否小于最大的宽度            if (mMaxWidth > mUsedWidth) {                extra = mMaxWidth - mUsedWidth;                widthAvg = extra / size;            }            for (int i = 0; i < size; i++) {                View view = mViews.get(i);                int viewWidth = view.getMeasuredWidth();                int viewHeight = view.getMeasuredHeight();                // 判断是否有富余                if (widthAvg != 0) {                    int newWidth = (int) (viewWidth + widthAvg + 0.5f);                    int widthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);                    int heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY);                    view.measure(widthMeasureSpec, heightMeasureSpec);                    //重新赋值                    viewWidth = view.getMeasuredWidth();                    viewHeight = view.getMeasuredHeight();                }                // 布局                int left = currentLeft;                //int top = paddingTop;                //让子view垂直居中                int top = (int) (paddingTop + (mHeight - viewHeight)/2.0f + 0.5f);                int right = left + viewWidth;                int bottom = top + viewHeight;                view.layout(left, top, right, bottom);                //下一个view的left                currentLeft += viewWidth + mHorizontalSpace;            }        }        /**         * 添加view         * @param view         */        public void addView(View view){            int size = mViews.size();            int viewWidth = view.getMeasuredWidth();            int viewHeight = view.getMeasuredHeight();            //mUsedWidth += viewWidth;            if (size == 0) {                // 说还没有添加View                if (viewWidth > mMaxWidth) {                    mUsedWidth = mMaxWidth;                }else {                    mUsedWidth = viewWidth;                }                //初始化高度                mHeight = viewHeight;            }else {                // 多个view的情况                mUsedWidth += viewWidth + mHorizontalSpace;                //如果当前的高度》最新加入view的高度,就是当前的高度,否则就是行加入的view的高度                mHeight = mHeight > viewHeight ? mHeight : viewHeight;            }            // 将View记录到集合中            mViews.add(view);        }        /**         * 能否添加         * @param view         * @return         */        public boolean canAdd(View view){            //如果没有view,就可添加            if (mViews.size() == 0) {                return true;            }            int viewWidth = view.getMeasuredWidth();            if (mUsedWidth + mHorizontalSpace + viewWidth > mMaxWidth) {                // 加不进去                return false;            }else {                return true;            }        }    }}
0 0
原创粉丝点击