关于Android 尝试在onCreate方法内测量view的宽高的测试

本文通过实测Android中不同方法获取自定义View宽高的效果,揭示了在onCreate方法执行期间无法获取宽高的现象,并对比了三种方法的优劣,最后提供了在onResume方法执行后获取正常宽高的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前两天看了一篇博客,写的是关于Android中view的宽高获取的,于是用自己的手机试了一下,结果如今天的博客。

测试条件:

测试手机:华为荣耀3

系统版本:Android4.2.2

ROM版本:华为Emui 2.0

开发工具:AndroidStudio


测试内容:

工程中build.gradle文件关键配置如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.xiaogeas.measureviewdemo001"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}

自定义View代码如下,用于观察view的onMeasure和onDraw方法的执行情况:

public class CustomView extends ImageView {

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d("Xiao","onMeasure::" + System.currentTimeMillis());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d("Xiao","onDraw::" + System.currentTimeMillis());
    }
}

主Activity的所有代码如下,由于只是观察view的一些方法的执行情况,所以代码比较简陋(嗯,人比较懒是真的),其中三个测量方法的输出我就放到方法注释里里(好懒-。-):

XML布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <com.xiaogeas.measureviewdemo001.CustomView
        android:id="@+id/iv_customIV"
        android:layout_width="match_parent"
        android:src="@drawable/ic_launcher"
        android:layout_height="match_parent" />

</RelativeLayout>

Java代码:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final CustomView customView = (CustomView) findViewById(R.id.iv_customIV);
//        measure1(customView);
        measure2(customView);
//        measure3(customView);
        Log.d("Xiao","MainActivity::onCreate执行完毕" + System.currentTimeMillis());
    }

    /**
     01-27 18:14:17.232    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422353657237
     01-27 18:14:17.232    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ viewWidth = 96, viewHeight = 96
     01-27 18:14:17.232    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onCreate执行完毕1422353657237
     01-27 18:14:17.235    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onResume执行完毕1422353657241
     01-27 18:14:17.282    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422353657286
     01-27 18:14:17.282    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422353657286
     01-27 18:14:17.342    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422353657347
     01-27 18:14:17.342    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422353657347
     01-27 18:14:17.345    7503-7503/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onDraw::1422353657350
     * @param view
     */
    private void measure1(CustomView view) {
        int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
        view.measure(w, h);
        int viewWidth = view.getMeasuredWidth();
        int viewHeight = view.getMeasuredHeight();
        Log.d("Xiao", "viewWidth = " + viewWidth + ", viewHeight = " + viewHeight);
    }

    /**
     * 01-27 18:25:23.902    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onCreate执行完毕1422354323906
     01-27 18:25:23.906    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onResume执行完毕1422354323909
     01-27 18:25:23.926    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354323929
     01-27 18:25:23.926    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354323929
     01-27 18:25:23.962    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ viewWidth = 656, viewHeight = 1056
     01-27 18:25:23.976    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354323979
     01-27 18:25:23.976    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354323980
     01-27 18:25:23.976    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ viewWidth = 656, viewHeight = 1056
     01-27 18:25:23.979    8266-8266/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onDraw::1422354323984
     * @param view
     */
    private void measure2(final CustomView view){
        ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
        viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                int viewWidth = view.getMeasuredWidth();
                int viewHeight = view.getMeasuredHeight();
                Log.d("Xiao", "viewWidth = " + viewWidth + ", viewHeight = " + viewHeight);
                return true;
            }
        });

    }

    /**
     * 01-27 18:29:15.379    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onCreate执行完毕1422354555383
     01-27 18:29:15.386    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ MainActivity::onResume执行完毕1422354555388
     01-27 18:29:15.419    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354555424
     01-27 18:29:15.419    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354555424
     01-27 18:29:15.483    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ viewWidth = 656, viewHeight = 1056
     01-27 18:29:15.506    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354555511
     01-27 18:29:15.506    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onMeasure::1422354555511
     01-27 18:29:15.509    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ viewWidth = 656, viewHeight = 1056
     01-27 18:29:15.509    8491-8491/com.xiaogeas.measureviewdemo001 D/Xiao﹕ onDraw::1422354555514
     * @param view
     */
    private void measure3(final CustomView view){
        ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int viewWidth = view.getMeasuredWidth();
                int viewHeight = view.getMeasuredHeight();
                Log.d("Xiao", "viewWidth = " + viewWidth + ", viewHeight = " + viewHeight);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Xiao","MainActivity::onResume执行完毕" + System.currentTimeMillis());
    }
}

结论:

    可以看出,三种方式都没有办法在onCreate方法执行期间获取view的宽高,而第一种最不靠谱。第二种和第三种方法可以获取宽高,不过都是加入监听,待onResume执行后,才能获取正常的宽高。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值