Android 自定义可以设置 最大宽高和最小宽高的 Fram

2019-07-19  本文已影响0人  河里的枇杷树

Android 提供的 FrameLayout 中只提供了 设置最小宽高的属性,在xml中使用的话就是
android:minHeight="335dp"
然而有时需求会要求我们控制最大宽高,这样就需要 我们自己实现了,其实很简单,就直接上代码了。

/**
 * Created by niluogege on 2019/5/16.
 * 
 * 可限制最大 最小 宽高的 FrameLayout
 */
public class LimitLayout extends FrameLayout {

    public static final float DEF_VALUE = -1f;

    private Context mContext;

    private float mMaxHeight = -1f;
    private float mMaxWidth = -1f;

    public LimitLayout(Context context) {
        this(context, null, 0);
    }

    public LimitLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LimitLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        initAttrs(attrs);
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray ta = mContext.obtainStyledAttributes(attrs, R.styleable.LimitLayout);
        mMaxHeight = ta.getDimension(R.styleable.LimitLayout_ml_maxheight, DEF_VALUE);
        mMaxWidth = ta.getDimension(R.styleable.LimitLayout_ml_maxWidth, DEF_VALUE);

        ta.recycle();
    }

    public void setMaxHeight(float maxHeight) {
        mMaxHeight = maxHeight;
    }

    public void setMaxWidth(float maxWidth) {
        mMaxWidth = maxWidth;
    }


    public float getMaxHeight() {
        return mMaxHeight;
    }

    public float getMaxWidth() {
        return mMaxWidth;
    }

    public void clearMaxWidthFlag() {
        mMaxWidth = -1f;
    }

    public void clearMaxHeightFlag() {
        mMaxHeight = -1f;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        // 拿到原来宽度,高度的  size
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);


        widthSize = getWidth(widthSize);
        heightSize = getHeight(heightSize);

        int maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
        int maxWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);

        super.onMeasure(maxWidthMeasureSpec, maxHeightMeasureSpec);

    }


    private int getWidth(int widthSize) {
        int minimumWidth = getMinimumWidth();

        if (mMaxWidth == DEF_VALUE) {//没有设置最大高度

            if (minimumWidth >= widthSize) {
                return minimumWidth;
            } else {
                return widthSize;
            }
        } else {
            if (widthSize >= mMaxWidth) {
                return (int) mMaxWidth;
            } else {
                if (minimumWidth >= widthSize) {
                    return minimumWidth;
                } else {
                    return widthSize;
                }
            }
        }
    }


    private int getHeight(int heightSize) {
        int minimumHeight = getMinimumHeight();

        if (mMaxHeight == DEF_VALUE) {//没有设置最大高度

            if (minimumHeight >= heightSize) {
                return minimumHeight;
            } else {
                return heightSize;
            }
        } else {
            if (heightSize >= mMaxHeight) {
                return (int) mMaxHeight;
            } else {
                if (minimumHeight >= heightSize) {
                    return minimumHeight;
                } else {
                    return heightSize;
                }
            }
        }
    }
}

因为有自定义属性,所以需要在attrs.xml中添加

 <declare-styleable name="LimitLayout">
        <!--最大宽度-->
        <attr name="ml_maxWidth" format="dimension" />
        <!--最大高度-->
        <attr name="ml_maxheight" format="dimension" />
    </declare-styleable>

这样就OK了,如果我们需要控制一个控件的 最大最小宽高,只需要 在外面包裹异一层LimitLayout

上一篇 下一篇

猜你喜欢

热点阅读