自定义View - 13.为什么getMeasuredHeight拿不到大小

看下面一段代码.你觉得结果是什么?

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "ZSJ_TAG";
    private TextView mTvCenterLetter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTvCenterLetter = (TextView) findViewById(R.id.tvCenterLetter);
        Log.d(TAG, "MeasuredHeight 1  =" + mTvCenterLetter.getMeasuredHeight());
        mTvCenterLetter.post(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "MeasuredHeight 2  ="+mTvCenterLetter.getMeasuredHeight());
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "MeasuredHeight 3  =" +  mTvCenterLetter.getMeasuredHeight());
    }
}

答案:

07-01 14:50:10.158 14794-14794/? D/ZSJ_TAG: MeasuredHeight 1  =0
07-01 14:50:10.163 14794-14794/? D/ZSJ_TAG: MeasuredHeight 3  =0
07-01 14:50:10.213 14794-14794/? D/ZSJ_TAG: MeasuredHeight 2  =125

1为什么getMeasureHeight方法拿不到大小

1.1为什么setContentView()之后执行getMeasureHeight()拿不到大小?

之所以能拿到控件的宽高是因为调用的onMeasure指定控件的宽高.
而setContentView其实还没有调用onMeasure方法.setContentView 只是创建了DecorView并把我们的布局加载到DecorView.
所以拿不到大小。

那onMeasure方法在哪里调用的?

在ActivityThread.java

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
      //里面调用了Activity的onCreate
     Activity a = performLaunchActivity(r, customIntent);

    handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}

handleResumeActivity{
    r = performResumeActivity(token, clearHide, reason);
    //才开始把我们的DecorView加载到WindowManager,View的绘制流程在这个时候才开始.
    wm.addView(decor, l);
}

performResumeActivity{
    //通过反射调用Activity的onResume
     r.activity.performResume();
}

1.2为什么onResume()之后执行getMeasureHeight()拿不到大小?

由上面的源码分析看出.执行onResume并没有开始View的绘制流程.所以拿不到大小

1.3 为什么post方法中能拿到大小?

        mTvCenterLetter.post(new Runnable() {
            //只是把runnable保存到Queue中.会在dispatchAttachedToWindow中调用执行,而dispatchAttachedToWindow方法会在测量完毕执行.
            @Override
            public void run() {
                Log.d(TAG, "MeasuredHeight 2  ="+mTvCenterLetter.getMeasuredHeight());
            }
        });

所以MeasuredHeight在post方法能拿到大小.

你可能感兴趣的:(自定义View - 13.为什么getMeasuredHeight拿不到大小)