1.View生命周期
-
1.1android:visibilty="gone"
03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.934: D/yyyyy(11493): construct 2 parameters .
03-25 19:56:55.934: E/yyyyy(11493): onFinishInflate
03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.934: D/yyyyy(11493): onVisibilityChanged--------=====
03-25 19:56:55.944: D/yyyyy(11493): onRtlPropertiesChanged--------=====
03-25 19:56:55.954: D/yyyyy(11493): onRtlPropertiesChanged--------=====
03-25 19:56:55.954: E/yyyyy(11493): onAttachedToWindow
03-25 19:56:55.954: D/yyyyy(11493): onWindowVisibilityChanged--------=====
03-25 19:56:55.974: D/yyyyy(11493): onWindowFocusChanged--------===== 1.2android:visibilty="invisible"
03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.204: D/yyyyy(11694): construct 2 parameters .
03-25 19:57:38.204: E/yyyyy(11694): onFinishInflate
03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.204: D/yyyyy(11694): onVisibilityChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onRtlPropertiesChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onRtlPropertiesChanged--------=====
03-25 19:57:38.224: E/yyyyy(11694): onAttachedToWindow
03-25 19:57:38.224: D/yyyyy(11694): onWindowVisibilityChanged--------=====
03-25 19:57:38.224: D/yyyyy(11694): onMeasure , width : 1080 ; height: 1557
03-25 19:57:38.224: D/yyyyy(11694): onMeasure , width : 144 ; height: 1500
03-25 19:57:38.234: D/yyyyy(11694): onSizeChanged
03-25 19:57:38.234: I/yyyyy(11694): onLayout --> l: 0 ; r : 144 ; t: 57 ; b: 201 : changed :true
03-25 19:57:38.254: D/yyyyy(11694): onMeasure , width : 1080 ; height: 1557
03-25 19:57:38.254: D/yyyyy(11694): onMeasure , width : 144 ; height: 1500
03-25 19:57:38.254: I/yyyyy(11694): onLayout --> l: 0 ; r : 144 ; t: 57 ; b: 201 : changed :false
03-25 19:57:38.264: D/yyyyy(11694): onWindowFocusChanged--------=====
- 1.3android:visibilty="visible"
03-25 19:55:15.434: D/yyyyy(11304): construct 2 parameters .
03-25 19:55:15.434: E/yyyyy(11304): onFinishInflate
03-25 19:55:15.434: D/yyyyy(11304): onVisibilityChanged--------=====
03-25 19:55:15.434: D/yyyyy(11304): onVisibilityChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onRtlPropertiesChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onRtlPropertiesChanged--------=====
03-25 19:55:15.454: E/yyyyy(11304): onAttachedToWindow
03-25 19:55:15.454: D/yyyyy(11304): onWindowVisibilityChanged--------=====
03-25 19:55:15.454: D/yyyyy(11304): onMeasure , width : 1080 ; height: 1557
03-25 19:55:15.454: D/yyyyy(11304): onMeasure , width : 144 ; height: 1500
03-25 19:55:15.464: D/yyyyy(11304): onSizeChanged
03-25 19:55:15.464: I/yyyyy(11304): onLayout --> l: 0 ; r : 144 ; t: 57 ; b: 201 : changed :true
03-25 19:55:15.474: D/yyyyy(11304): onMeasure , width : 1080 ; height: 1557
03-25 19:55:15.474: D/yyyyy(11304): onMeasure , width : 144 ; height: 1500
03-25 19:55:15.474: I/yyyyy(11304): onLayout --> l: 0 ; r : 144 ; t: 57 ; b: 201 : changed :false
03-25 19:55:15.474: D/yyyyy(11304): onDraw--------=====
03-25 19:55:15.484: D/yyyyy(11304): onWindowFocusChanged--------=====
1、從中不難看到view 默認(rèn)為可見的 烘豌, 不是默認(rèn)值時先調(diào)用 onVisibilityChanged 载庭, 但是此時該view 的任何位置信息都不知道。
2廊佩、可見性改變后才是調(diào)用帶有兩個參數(shù)的構(gòu)造函數(shù)
3囚聚、從xml 文件中 inflate 完成
4、將view 加到 window 中 ( View 是gone 的 标锄,那么View創(chuàng)建生命周期也就結(jié)束 )
5顽铸、測量view的長寬 ( onMeasure )
6、定位View 在父View中的位置 ( onLayout )-->(View 是invisible 料皇, View 創(chuàng)建生命周期結(jié)束)
7谓松、onDraw ( 只有可見的 View 才在 window 中繪制 )
在代碼中構(gòu)造View:setContentView(new CusView(this))輸入日志信息如下:
03-25 20:37:51.284: E/yyyyy(12530): construct 1 parameter
03-25 20:37:51.294: D/yyyyy(12530): onVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onRtlPropertiesChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onRtlPropertiesChanged--------=====
03-25 20:37:51.314: E/yyyyy(12530): onAttachedToWindow
03-25 20:37:51.314: D/yyyyy(12530): onWindowVisibilityChanged--------=====
03-25 20:37:51.314: D/yyyyy(12530): onMeasure , width : 1080 ; height: 1557
03-25 20:37:51.314: D/yyyyy(12530): onSizeChanged
03-25 20:37:51.324: I/yyyyy(12530): onLayout --> l: 0 ; r : 1080 ; t: 0 ; b: 1557 : changed :true
03-25 20:37:51.324: D/yyyyy(12530): onMeasure , width : 1080 ; height: 1557
03-25 20:37:51.324: I/yyyyy(12530): onLayout --> l: 0 ; r : 1080 ; t: 0 ; b: 1557 : changed :false
03-25 20:37:51.324: D/yyyyy(12530): onDraw--------=====
03-25 20:37:51.344: D/yyyyy(12530): onWindowFocusChanged--------=====
從測試結(jié)果來看,默認(rèn)情況下view的長和寬默認(rèn)和父 view 的長和寬一致 践剂。
為什么我指定了LayoutParameters鬼譬,卻沒有效果?
在不恰當(dāng)?shù)纳芷谥兄付↙ayoutParameters逊脯,會被忽略掉优质,比如如下代碼:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); view = new CusView(this); view.setImageResource(R.drawable.ic_launcher); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(70, 70); view.setLayoutParams(params); setContentView(view); }
正確的方法應(yīng)該是放到 onWindowFocusChanged 方法獲取到焦點后再指定LayoutParameters,如下代碼:
@Override public void onWindowFocusChanged(boolean hasFocus) { // TODO Auto-generated method stub super.onWindowFocusChanged(hasFocus); if (hasFocus) { view.setImageResource(R.drawable.ic_launcher); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(70, 70); view.setLayoutParams(params); } }
2 接下來我們看三份銷毀 View 的日志:
- 2.1android:visibility=visible
03-25 21:15:35.404: D/yyyyy(14589): onWindowFocusChanged--------=====
03-25 21:15:35.484: D/yyyyy(14589): onWindowVisibilityChanged--------=====
03-25 21:15:35.504: D/yyyyy(14589): onDetachedFromWindow--------=====
- 2.2android:visibility=gone
03-25 21:16:09.964: D/yyyyy(14736): onWindowFocusChanged--------=====
03-25 21:16:10.054: D/yyyyy(14736): onWindowVisibilityChanged--------=====
03-25 21:16:10.064: D/yyyyy(14736): onDetachedFromWindow--------=====
- 2.3android:visibility=invisible
03-25 21:16:42.534: D/yyyyy(14860): onWindowFocusChanged--------=====
03-25 21:16:42.594: D/yyyyy(14860): onWindowVisibilityChanged--------=====
03-25 21:16:42.614: D/yyyyy(14860): onDetachedFromWindow--------=====
從以上內(nèi)容可以看到军洼,visibility屬性對view的銷毀流程沒有影響巩螃。
<b>綜上所述:View 的關(guān)鍵生命周期為 [改變可見性] --> 構(gòu)造View --> onFinishInflate --> onAttachedToWindow --> onMeasure --> onSizeChanged --> onLayout --> onDraw --> onDetackedFromWindow</b>
3 RecyclerView中Item可見/不可見
- 3.1 從可見到不可見(滑動)
會回調(diào)View的onWindowVisibilityChanged()方法以及onDetachedFromWindow()方法 - 3.1 從不可見到可見(滑動)
會回調(diào)View的onAttachedToWindow()、onWindowVisibilityChanged()匕争、onVisibilityChanged()避乏、onMeasure()、onLayout() - 3.2 RecyclerView頂部嵌套輪播圖甘桑,輪播圖滑動到不可見再到可見后拍皮,不能自動播放問題歹叮。
代碼中使用Handler發(fā)送延時請求執(zhí)行Runnable中的定時方法,可是當(dāng)輪播圖從不可見狀態(tài)到可見狀態(tài)春缕,定時方法不執(zhí)行盗胀。
原因:未知ing
解決辦法:在onAttachedToWindow()方法,使用Handler發(fā)送延時請求去調(diào)用開始輪播的方法startImageCycle()锄贼,并且設(shè)置的延時時間目前和自動輪播的間隔時間一致票灰。當(dāng)把延時時間改小后,問題依然復(fù)現(xiàn)宅荤。
思考:1.問題出現(xiàn)的原因屑迂?
2.可見后重新調(diào)用startImageCycle()的方法是不是可以放在onWindowVisibilityChanged()或者onVisibilityChanged()生命周期中去?
3.目前的解決辦法中冯键,使用Handler發(fā)送延時調(diào)用startImageCycle()的延時時長問題?