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