Android开发Android开发Android开发经验谈

自定义viewGroup位置摆放onLayout以及设置marg

2018-07-19  本文已影响11人  ccccccal

自定义viewGroup必须要实现的一个方法,实现所有子控件布局的函数,自顶向下通过计算好的尺寸放置每一个子View

首先有关getWidth()和getMeasuredWidth()的区别为:onlayout()方法内会用到

如下所示:

@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int lineWidth = 0;
        int lineHeight = 0;
        int top = 0;
        int left = 0;

        int count = getChildCount();

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

            View childAt = getChildAt(i);

            MarginLayoutParams layoutParams = (MarginLayoutParams) childAt.getLayoutParams();

            //得到子view的测量建议高度
            int measuredHeight = childAt.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
            int measuredWidth = childAt.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin;

            //换行
            if (measuredWidth + lineWidth > getMeasuredWidth()) {

                top += lineHeight;
                left = 0;
                lineHeight = measuredHeight;
                lineWidth = measuredWidth;
            } else {

                lineHeight = Math.max(measuredHeight, lineHeight);
                lineWidth += measuredWidth;
            }

            //的到字view的当前位置
            int ll = left + layoutParams.leftMargin;
            int tt = top + layoutParams.topMargin;
            int rr = ll + childAt.getMeasuredWidth();
            int bb = tt + childAt.getMeasuredHeight();

            //设置子view的确定位置
            childAt.layout(ll, tt, rr, bb);

            left += measuredWidth;
        }

设置margin时需要重载的方法有:

 @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return new MarginLayoutParams(p);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(),attrs);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new MarginLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
    }

设置子view的点击事件

    /**
     * 设置点击事件
     *
     * @param listener
     */
    public void setOnItemClickListener(final OnItemClickListener listener) {
        for (int i = 0; i < getChildCount(); i++) {
            final int index = i;
            View childAt = getChildAt(i);
            childAt.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onItemClick(index);
                }
            });
        }
    }
    
    public interface OnItemClickListener {
        void onItemClick(int position);
    }
上一篇 下一篇

猜你喜欢

热点阅读