美文网首页Android开发Android开发Android开发经验谈
自定义viewGroup位置摆放onLayout以及设置marg

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

作者: ccccccal | 来源:发表于2018-07-19 18:42 被阅读11次

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

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

    • getMeasuredWidth()是在measure过程后就可以获取到的,getWidth()是在layout()过程结束后才能获得到的
    • getMeasuredWidth()中的值是子view在侧来最后使用setMeasuredDimension(width, height)来设置的,getWidth()的值是在onlayout()方法之后父view动态设置的
    • setMeasuredDimension(width, height)只是先确定了给父view的一个建议宽高,子view最终的宽高还是通过childAt.layout(0,top,measuredWidth,measuredHeight+top)来设置的
    • getMeasureWidth()只有在measure()过程中才可以获得,getWidth()只有在layout()之后才可以获得

    如下所示:

    @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);
        }
    

    相关文章

      网友评论

        本文标题:自定义viewGroup位置摆放onLayout以及设置marg

        本文链接:https://www.haomeiwen.com/subject/ghfxmftx.html