onMeasure相关

1、继承自View的自定义View为什么要重写onMeasure方法:

View.java中的onMeasure方法如下:

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }
    /**
     * Utility to return a default size. Uses the supplied size if the
     * MeasureSpec imposed no constraints. Will get larger if allowed
     * by the MeasureSpec.
     *
     * @param size Default size for this view
     * @param measureSpec Constraints imposed by the parent 即父布局的大小
     * @return The size this view should be.
     */
    public static int getDefaultSize(int size, int measureSpec) {
        int result = size;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        switch (specMode) {
        case MeasureSpec.UNSPECIFIED:
            result = size;
            break;
        case MeasureSpec.AT_MOST://wrap_content和match_parent都执行result=specSize,即填满父布局
        case MeasureSpec.EXACTLY:
            result = specSize;
            break;
        }
        return result;
    }

从源码来看,继承自View的自定义View的宽高总是填满父布局,导致wrap_content失效。但android:width="100dp"是生效的。

所以为了使wrap_content生效,就需要重写onMeasure方法,计算最小宽高。



比如:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.d("SIZES", "called onMeasure()");

    int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
    int minh = getSuggestedMinimumHeight() + getPaddingBottom() + getPaddingTop();

    setMeasuredDimension(
            resolveSize(minw, widthMeasureSpec),
            resolveSize(minh, heightMeasureSpec));
}

但对于继承自View的自定义View来说,使用wrap_content好像意义不大,一般都用match_parent或100dp之类。

如果有需要,也可以重写getSuggestedMinimunWidth和resolveSize方法。一般没必要。如果觉得getSuggestedMinimunWidth总是返回0,那就往下看↓


另外,getSuggestedMinimumWidth的值如果设置了background那就返回background的最小width;如果没有backgroud,则取mMinWidth值。

    protected int getSuggestedMinimumWidth() {
        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
    }
                case R.styleable.View_minWidth:
                    mMinWidth = a.getDimensionPixelSize(attr, 0); //如果没有设置style属性View_minWidth,那么其默认值为0.
                    break;
    public void setMinimumWidth(int minWidth) {//-------------------除了设置style属性View_minWidth,也可以调用setMinimumWidth方法。
        mMinWidth = minWidth;
        requestLayout();

    }



















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值