自定义倾斜的ViewGroup

想到这个控件最开始是因为一场面试,问到了我倾斜的布局要怎么实现。我第一反应就是直接添加LayoutParams  想怎么控制就怎么控制,But,面试官想让我做的更彻底,直接在布局中添加之后就是倾斜的。当时没说好,今天闲了,直接写了一个。

/*************************************************divider*************************************************************/
我的思路比较简单,重写给子控件的布局。

代码如下:

/**
 * Created by cheng on 2017/9/7.
 */
public class LeansLayout extends FrameLayout {
    /**
     * 默认是宽度/长度
     */
    private float mRadioWH = 0;
    private float DEFAULT_RADIOWH = 0;

    private String TAG = "LeansLayout";

    public LeansLayout(Context context) {
        super(context);
        init(context, null);
    }

    public LeansLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public LeansLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.LeansLayout);
        mRadioWH = typedArray.getFloat(R.styleable.LeansLayout_roateWH, mRadioWH);
        typedArray.recycle();
    }

    /**
     * 获得宽高的同时,取得宽高比
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (DEFAULT_RADIOWH > 0) {
        } else {
            DEFAULT_RADIOWH = w * 1.0f / h;
        }
        if (mRadioWH > 0) {
        } else {
            mRadioWH = DEFAULT_RADIOWH;
        }
        Log.i(TAG, "roateWH=" + mRadioWH);
    }

    /**
     * 对子View进行测量
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
        }
    }
    /***
     * 手动帮子类布局成倾斜的 
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        int totalheight = 0;
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            int width = childView.getMeasuredWidth();
            int height = childView.getMeasuredHeight();
            totalheight = totalheight + height;
            //获取子View的margin
            FrameLayout.LayoutParams frameLayoutParams = (LayoutParams) childView.getLayoutParams();

            int left = frameLayoutParams.leftMargin;
            int top = frameLayoutParams.topMargin;
            int bottom = frameLayoutParams.bottomMargin;
            //保证第一个View的位置不显示到布局外面
            if (i != 0) {
                int yPoint = totalheight - height / 2;
                left = left + (int) (mRadioWH * yPoint - width / 2);
                top = top + totalheight - height;
            }
            //布局  默认的左上右下
            childView.layout(left, top, left + width, top + height + bottom);
        }
    }
}

/*************************************************divider*************************************************************/

总结:功能虽然简单,但是还是记录下来。这段代码让我重新熟悉了ViewGroup的绘制。这个View本身是继承ViewGroup的

但是在获取LayoutParams的时候,ViewGroup无法获得Margin的属性,于是选用了FrameLayout。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值