在Activity的onCreate方法中,能夠經過setContentView()方法來設置此Activity要顯示的界面。在xml中的佈局文件須要先解析成View樹才能加載顯示,經過View的onMeasure,onLayout,onDraw方法完成View的測量大小,佈局以及View自身的繪製。在此想說一下Activity生命週期的onCreate,onStart,onResume方法和View自身的測量,佈局等方法的調用順序問題。
java
先重寫Activity的這幾個方法並打印logide
public class FlowActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("onCreate", "onCreate"); setContentView(R.layout.flow); } @Override protected void onResume() { Log.e("onResume", "onResume"); super.onResume(); } @Override protected void onStart() { Log.e("onStart", "onStart"); super.onStart(); } }
在重寫ViewGroup方法FlowLayout函數
public class FlowLayout extends ViewGroup { public FlowLayout(Context context) { super(context); } public FlowLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public FlowLayout(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.e("onMeasure", "onMeasure"); setMeasuredDimension(totalWidth, resolveSize(totalHeight, heightMeasureSpec)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Log.e("onSizeChanged", "onSizeChanged"); super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.e("onLayout", "onLayout"); } @Override protected void onFinishInflate() { Log.e("onFinishInflate", "onFinishInflate"); super.onFinishInflate(); } }
打印Log能夠看出Activity生命週期的函數和View的測量,佈局等函數的調用順序。
佈局
所以,咱們一般在onCreate方法裏面是獲取不到某個View測量的寬高值,獲取的值爲0.
spa
只有當Activity的onResume方法調用完畢以後,當前的窗口將要顯示可見,纔會去測量,繪製View樹。setContentView方法只是把xml文件解析爲View樹的過程,並無發起繪製View樹。當解析完畢以後會調用OnFinishInflate方法,完成解析。code
當View的「大小」發生改變的時候會調用onSizeChanged方法,這個大小,我的理解爲佈局大小,並不是測量大小。是在onMeasure以後,onLayout以前調用的方法。xml
理解了這些調用順序,咱們能夠知道在什麼時候去獲取或設置一些值。生命週期