自定義View一共分為兩大類,具體如下圖:
創(chuàng)新互聯(lián)是一家專業(yè)提供武鄉(xiāng)企業(yè)網站建設,專注與網站制作、網站建設、H5響應式網站、小程序制作等業(yè)務。10年已為武鄉(xiāng)眾多企業(yè)、政府機構等服務。創(chuàng)新互聯(lián)專業(yè)網絡公司優(yōu)惠進行中。
對于自定義View的類型介紹及使用場景如下圖:
在使用自定義View時有很多注意點(坑),希望大家要非常留意:
View的內部本身提供了post系列的方法,完全可以替代Handler的作用,使用起來更加方便、直接。
主要針對View中含有線程或動畫的情況: 當View退出或不可見時,記得及時停止該View包含的線程和動畫,否則會造成內存泄露問題 。
當View帶有滑動嵌套情況時,必須要處理好滑動沖突,否則會嚴重影響View的顯示效果。
接下來,我將用自定義View中最常用的 繼承View 來說明自定義View的具體應用和需要注意的點
在下面的例子中,我將講解:
下面我將逐個步驟進行說明:
步驟1:創(chuàng)建自定義View類(繼承View類)
特別注意:
步驟2:在布局文件中添加自定義View類的組件及顯示
至此,一個基本的自定義View已經實現了,運行效果如下圖。
接下來繼續(xù)看自定義View關于屬性自定義的問題:
先來看wrap_content match_parent屬性的區(qū)別
如果不手動設置支持 wrap_content 屬性,那么 wrap_content 屬性是不會生效(顯示效果同 match_parent )
padding 屬性:用于設置控件內容相對控件邊緣的邊距;
如果不手動設置支持padding屬性,那么padding屬性在自定義View中是不會生效的。
繪制時考慮傳入的padding屬性值(四個方向)。
除了常見的以android:開頭的系統(tǒng)屬性(如下所示),很多場景下自定義View還需要系統(tǒng)所沒有的屬性,即自定義屬性。
實現自定義屬性的步驟如下:
下面我將對每個步驟進行具體介紹
對于自定義屬性類型 格式如下:
至此,一個較為規(guī)范的自定義View已經完成了。
Carson_Ho的github: 自定義View的具體應用
不定期分享關于 安卓開發(fā) 的干貨,追求 短、平、快 ,但 卻不缺深度 。
為什么view.post()能保證獲取到view的寬高?
View.post()的原理: 以Handler為基礎,View.post() 將傳入任務添加到 View繪制任務所在的消息隊列尾部,從而保證View.post() 任務的執(zhí)行時機是在View 繪制任務完成之后的。 其中,幾個關鍵點:
所以:
具體源碼分析請看: Android:為什么view.post()能保證獲取到view的寬高?
為什么onCreate()使用view.post()無法立刻執(zhí)行任務(如獲取寬高),需要在onResume()后才可獲?。?/p>
在onCreate()時,AttachInfo還沒被賦值(為null)(是在view.dispatchAttachedToWindow()才被賦值),所以會走下述源碼的過程2;通過上面分析,此過程的作用僅是:保存了通過post()添加的任務,并沒執(zhí)行。
若只是創(chuàng)建一個 View 調用它的post(),那么post的任務會不會被執(zhí)行?
不會。主要原因是:
每個View中post() 需執(zhí)行的任務,必須得添加到窗口視圖-執(zhí)行繪制流程 - 任務才會被post到消息隊列里去等待執(zhí)行,即依賴于dispatchAttachedToWindow ();
若View未添加到窗口視圖,那么就不會走繪制流程,post() 添加的任務最終不會被post到消息隊列里,即得不到執(zhí)行。(但會保存到HandlerAction數組里)
上述例子,因為它沒有被添加到窗口視圖,所以不會走繪制流程,所以該任務最終不會被post到消息隊列里 執(zhí)行
此時只需要添加將View添加到窗口,那么post()的任務即可被執(zhí)行
view.pos()傳入的任務被執(zhí)行的有效期是多久?
在整個 Activity 的生命周期內都可以正常使用 View.post() 任務
任務被執(zhí)行是構造AttachInfo,所以任務釋放即時釋放AttachInfo (置為null)。而AttachInfo 的釋放操作(置為null)是在 Activity 生命周期 onDestory 方法之后
下面,我們將分析,什么時候調用上述入口,即DecorView.dispatchDetachedFromWindow();
此時需從 將DecorView從WindowManager中移除 開始講起:移除 Window 窗口任務是通過 ActivityThread.handleDestoryActivity()完成。
View.post() 任務被執(zhí)行的有效期是在 Activity 生命周期 onDestory()后。本質是追蹤AttachInfo的釋放過程(置為null)
AttachInfo的釋放過程是在 將DecorView從WindowManager中移除時:回調DecorView.dispatchDetachedFromWindow(),其具體行為是:
而上述過程是在ActivityThread.handleDestoryActivity()中回調 Activity.onDestory()之后。
至此,關于view.post()的四大常見疑問 (坑)內容講解完畢。
不定期分享關于 安卓開發(fā) 的干貨,追求 短、平、快 ,但 卻不缺深度 。
即不同的組件(如 Activity、Service )都可獲得 Application 對象且都是同一個對象
Application 對象的生命周期是整個程序中最長的,即等于 Android App 的生命周期
那么,該 Application 類有什么作用呢?下面,我將介紹 Application 類的方法使用
典型的應用場景有兩個:
特別注意: onTrimMemory() 中的 TRIM_MEMORY_UI_HIDDEN 與 onStop() 的關系
調用時刻:應用程序結束時調用
從 Applicaiton 類的方法可以看出, Applicaiton 類的應用場景有:(已按優(yōu)先級排序)
即繼承 Application 類
在 Manifest.xml 文件中 application 標簽里進行配置
Manifest.xml
至此,關于 Applicaiton 類已經講解完畢。
下面我將繼續(xù)對 Android 中的知識進行深入講解 ,感興趣的同學可以繼續(xù)關注 Carson_Ho 的
不定期分享關于 安卓開發(fā) 的干貨,追求 短、平、快 ,但 卻不缺深度 。