View和ViewGroup常用方法
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
Android的UI界面都是由View和ViewGroup及其派生類組合而成的。
其中,View是所有UI組件的基類,而 ViewGroup是容納這些組件的容器,其本身也是從View派生出來的.
?View對(duì)象是Android平臺(tái)中用戶界面體現(xiàn)的基礎(chǔ)單位。
View類是它稱為“widgets(工具)”的子類的基礎(chǔ),它們提供了諸如文本輸入框和按鈕之類的UI對(duì)象的完整實(shí)現(xiàn)。
ViewGroup類同樣為其被稱為“Layouts(布局)”的子類奠定了基礎(chǔ),它們提供了象流式布局、表格布局以及相對(duì)布局之類的布局架構(gòu)。
?一般來說,開發(fā)Android應(yīng)用程序的UI界面都不會(huì)直接使用View和ViewGroup,而是使用這兩大基類的派生類。
View派生出的直接子類有:AnalogClock,ImageView,KeyboardView, ProgressBar,SurfaceView, TextView,ViewGroup,ViewStub
View派生出的間接子類有:AbsListView,AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView<T?extends?Adapter>,AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton,
ViewGroup派生出的直接子類有:AbsoluteLayout,AdapterView<T?extends?Adapter>,FragmentBreadCrumbs,FrameLayout, LinearLayout,RelativeLayout,SlidingDrawer
ViewGroup派生出的間接子類有:AbsListView,AbsSpinner, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, CalendarView, DatePicker, DialerFilter, ExpandableListView, Gallery, GestureOverlayView,GridView,HorizontalScrollView, ImageSwitcher,ListView,
?這里特別指出,ImageView是布局具有圖片效果的UI常用的類,SurfaceView是用來進(jìn)行游戲開發(fā)的與一般View相比較為特殊的非常重要的類,而AbsoluteLayout、 FrameLayout,LinearLayout, RelativeLayout這幾個(gè)ViewGroup的直接子類是Android UI布局中最基本的布局元素。
?自定義控件(自定義View和ViewGroup)
給大家介紹下View和ViewGroup最重要的幾個(gè)方法——
protected void onDraw(Canvas canvas):View類中用于重繪的方法,這個(gè)方法是所有View、ViewGroup及其派生類都具有的方法,也是Android UI繪制最重要的方法。開發(fā)者可重載該方法,并在重載的方法內(nèi)部基于參數(shù)canvas繪制自己的各種圖形、圖像效果。
protected void onLayout(boolean changed, int left, int top, int right, int bottom):View類中布局發(fā)生改變時(shí)會(huì)調(diào)用的方法,這個(gè)方法是所有View、ViewGroup及其派生類都具有的方法,重載該類可以在布局發(fā)生改變時(shí)作定制處理,這在實(shí)現(xiàn)一些特效時(shí)非常有用。
protected void dispatchDraw(Canvas canvas):ViewGroup類及其派生類具有的方法,這個(gè)方法主要用于控制子View的繪制分發(fā),重載該方法可改變子View的繪制,進(jìn)而實(shí)現(xiàn)一些復(fù)雜的視效,典型的例子可參見Launcher模塊Workspace的dispatchDraw重載。
protected boolean drawChild(Canvas canvas, View child, long drawingTime)):ViewGroup類及其派生類具有的方法,這個(gè)方法直接控制繪制某局具體的子view,重載該方法可控制具體某個(gè)具體子View。
addView方法這個(gè)方法是用來向View容器中添加組件用的。我們可以使用這個(gè)方法向這個(gè)ViewGroup中添加組件。
getChildAt方法?這個(gè)方法用來返回指定位置的View。
注意:ViewGroup中的View是從0開始計(jì)數(shù)的。
View在屏幕上顯示出來要先經(jīng)過measure(計(jì)算)和layout(布局).
onMeasure(int, int) View會(huì)調(diào)用此方法,來確認(rèn)自己及所有子對(duì)象的大小
onLayout(boolean, int, int, int, int, int, int) 當(dāng)View要為所有子對(duì)象分配大小和位置時(shí),調(diào)用此方法
onSizeChanged(int, int, int, int) 當(dāng)View大小改變時(shí),調(diào)用此方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)介紹:
onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數(shù)值,而是將模式和尺寸組合在一起的數(shù)值。
一般是根據(jù)xml文件中定義得到的,我們可以根據(jù)這2個(gè)參數(shù)知道模式和size。
我們需要通過int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,
用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
mode共有三種情況,取值分別為MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。
對(duì)應(yīng)關(guān)系:
-2147483648----xml文件中的wrap_content----MeasureSpec.AT_MOST
1073741824----xml文件中的fill_parent-----MeasureSpec.EXACTLY
0-----MeasureSpec.UNSPECIFIED?
一般ViewGroup,我們是這樣實(shí)現(xiàn)的:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
?????? super.onMeasure(widthMeasureSpec, heightMeasureSpec);
?????? final int width = MeasureSpec.getSize(widthMeasureSpec);
?????? final int widthMode = MeasureSpec.getMode(widthMeasureSpec);??
?????? final int count = getChildCount();
?????? for (int i = 0; i < count; i++) {
?????????? //其實(shí),對(duì)于我們自己寫的應(yīng)用來說,最好的辦法是去掉框架里的該方法,直接調(diào)用view.measure(),如下:?
?????????? //一般我們?cè)O(shè)定ViewGroup的XML布局是wrap_content,這樣2個(gè)參數(shù)就是-2147483648,那么我們?nèi)缦抡{(diào)用就是???????
?????????? ?//讓子組件自己適配大小??
?????????? getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
????????? //還有下面的方法
?????????? //整個(gè)measure()過程就是個(gè)遞歸過程???
?????????? //該方法只是一個(gè)過濾器,最后會(huì)調(diào)用measure()過程?;或者?measureChild(child?,?h,?i)方法???
?????????? ?//measureChildWithMargins(getChildAt(i).?,?h,?i)?;?
?????? }??
?????? scrollTo(mControl.getCurScreen() * width, 0);
??? }
當(dāng)然我們也可以調(diào)用setMeasuredDimension(h?,?l)?;?來設(shè)定ViewGroup的大小。
至于View的onMeasure實(shí)現(xiàn),我們其實(shí)一般都不覆寫該方法,覆寫的話也簡(jiǎn)單,根據(jù)需要,和上面一樣,根據(jù)傳入的2個(gè)參數(shù)獲取當(dāng)前的模式和大小。
當(dāng)然我們也可以自己計(jì)算大小,調(diào)用setMeasuredDimension設(shè)定。
ViewGroup的onLayout實(shí)現(xiàn):
protected void onLayout(boolean changed, int l, int t, int r, int b) {
??? int childLeft = 0;
??? // 獲取所有的子View的個(gè)數(shù)
????final int childCount = getChildCount();
??? for (int i = 0; i < childCount; i++) {
????? ?final View childView = getChildAt(i);
????? ?final int childWidth = childView.getMeasuredWidth();
????? ?final int childHeight = childView.getMeasuredHeight();
???? ?childView.layout(childLeft, 0, childLeft + childWidth,childHeight);
???? // 下一個(gè)VIew的左邊左邊+一個(gè)
???? ?childLeft += childWidth;
???}
?}
實(shí)際上很簡(jiǎn)單,就是調(diào)用layout方法來設(shè)定View在畫布上的位置,可以超出屏幕寬度,然后我們可以滾動(dòng)顯示。當(dāng)然我們也可以調(diào)用layout傳入相關(guān)坐標(biāo)來設(shè)定View顯示位置(已驗(yàn)證OK)
轉(zhuǎn)載于:https://my.oschina.net/kangchunhui/blog/64457
總結(jié)
以上是生活随笔為你收集整理的View和ViewGroup常用方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【iOS-cocos2d-X 游戏开发之
- 下一篇: 利用SNMP4J实现Snmp Trap