View的相關面試題(待補充)

1 常用組件的使用:ListView、RecyclerView及Adapter的使用

2 View之間的繼承關係

3 Invalidate與postInvalidate的區別

前者是在UI線程自身中使用,而後者在非UI線程中使用。

怎麼說呢?Android提供了Invalidate方法實現界面刷新,但是Invalidate不能直接在線程中調用,因爲他是違背了單線程模型:Android UI操作並不是線程安全的,並且這些操作必須在UI線程中調用。 鑑於此,如果要使用invalidate的刷新,那我們就得配合handler的使用,使異步非ui線程轉到ui線程中調用,如果要在非ui線程中直接使用就調用postInvalidate方法即可,這樣就省去使用handler的煩惱。

4 自定義view的實現方式(根據項目經驗詢問相關組件)。

5 onMeasure/onLayout/onDraw的作用

http://blog.csdn.net/zhaoweixing1989/article/details/46009889

(1)onMeasure:

onMeasure(int widthMeasureSpec,int heightMeasureSpec)  

1、調用時間:當控件的父元素放置該控件時,用於告訴父元素該控件需要的大小。

2、傳入參數:widthMeasureSpec,heightMeasureSpec。這兩個傳入參數由高32位和低16位組成,高32位保存的值叫specMode,可以通過MeasureSpec.getMode()獲取;低16位爲specSize可以由MeasureSpec.getSize()獲取。這兩個值是由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同決定。權值weight也是尤其需要考慮的因素,有它的存在情況可能會稍微複雜點。

specMode可以取三個值:MeasureSpec.EXACTLY ,MeasureSpec.AT_MOST,MeasureSpec.UNSPECIFIED;

specMode與layout_的對應關係如下:

match_parent - MeasureSpec.EXACTLY:當layout_爲match_parent或者爲某一具體值的時候specMode爲EXACTLY代表精確的值;

wrap_content - MeasureSpec.AT_MOST:表示能獲得的最大尺寸;

當無法確定尺寸的時候則是 MeasureSpec.UNSPECIFIED,這時候specSize會爲最小值(即0);

3、可以在onMeasure()中來計算控件的尺寸,然後根據setMeasuredDimension(mWidth,mHeight);方法來告訴父控件此控件需要的尺寸,onMeasure()方法中必須調用此方法。

4、值得注意的是:
1)specSize和傳入setMeasuredDimension()方法中的值的單位都是px(dp*density就是px)。
2)match_parent並不是填充整個父容器,而是在不覆蓋已經加入父容器的控件的情況下填充父容器.

(2)onLayout:

onLayout(boolean changed, int left, int top,int right,int bottom);

父容器的onLayout()調用子類的onLayout()來確定子view在viewGroup中的位置,如:onLayout(10,10,100,100)表示子容器在父容器中(10,10)位置顯示,長、寬都是90。結合onMeasure()方法使用可以確定子view的佈局。

(3)onDraw:

 onDraw(Canvas canvas)

自定義view的關鍵方法,用於繪製界面,可以重寫此方法以繪製自定義View。

小結:

    一般來說,在自定義View時,需要重寫onMeasure()和onDraw()  
             自定義ViewGroup時需要重寫,onMeasure() 和onLayout()

6 Paint、Matrix、Shader等繪製相關類的方法作用

(1)Paint(畫筆):

(2)Canvas(畫布):

(3)Path(路徑):

(4)Matrix(矩陣):

參考: 深入理解 Android 中的 Matrix

(5)Shader(着色器):

參考:Android中Canvas繪圖之Shader使用圖文詳解

7 詳細描述事件分發機制

源碼解釋1:
Android事件分發機制完全解析,帶你從源碼的角度徹底理解(上)
Android事件分發機制完全解析,帶你從源碼的角度徹底理解(下)
畫圖解釋:圖解 Android 事件分發機制

  1. onTouch和onTouchEvent有什麼區別,又該如何使用?

從源碼中可以看出,這兩個方法都是在View的dispatchTouchEvent中調用的,onTouch優先於onTouchEvent執行。如果在onTouch方法中通過返回true將事件消費掉,onTouchEvent將不會再執行。

另外需要注意的是,onTouch能夠得到執行需要兩個前提條件,第一mOnTouchListener的值不能爲空,第二當前點擊的控件必須是enable的。因此如果你有一個控件是非enable的,那麼給它註冊onTouch事件將永遠得不到執行。對於這一類控件,如果我們想要監聽它的touch事件,就必須通過在該控件中重寫onTouchEvent方法來實現。

  1. 爲什麼給ListView引入了一個滑動菜單的功能,ListView就不能滾動了?

如果你閱讀了Android滑動框架完全解析,教你如何一分鐘實現滑動菜單特效 這篇文章,你應該會知道滑動菜單的功能是通過給ListView註冊了一個touch事件來實現的。如果你在onTouch方法裏處理完了滑動邏輯後返回true,那麼ListView本身的滾動事件就被屏蔽了,自然也就無法滑動(原理同前面例子中按鈕不能點擊),因此解決辦法就是在onTouch方法裏返回false。

  1. 爲什麼圖片輪播器裏的圖片使用Button而不用ImageView?

提這個問題的朋友是看過了Android實現圖片滾動控件,含頁籤功能,讓你的應用像淘寶一樣炫起來 這篇文章。當時我在圖片輪播器裏使用Button,主要就是因爲Button是可點擊的,而ImageView是不可點擊的。如果想要使用ImageView,可以有兩種改法。第一,在ImageView的onTouch方法裏返回true,這樣可以保證ACTION_DOWN之後的其它action都能得到執行,才能實現圖片滾動的效果。第二,在佈局文件裏面給ImageView增加一個android:clickable=”true”的屬性,這樣ImageView變成可點擊的之後,即使在onTouch裏返回了false,ACTION_DOWN之後的其它action也是可以得到執行的。

今天的講解就到這裏了,相信大家現在對Android事件分發機制又有了進一步的認識,在後面的文章中我會再帶大家一起探究Android中ViewGroup的事件分發機制,感興趣的朋友請繼續閱讀 Android事件分發機制完全解析,帶你從源碼的角度徹底理解(下) 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章