View與ViewGroup有什么區別?


百度知道:http://zhidao.baidu.com/link?url=B5MFOzDlww8soYqr5CL5FldH4sXD6eumS1XTRn8XEh8gu4mKjQdPkJSLIBt7u_xtf7jcrJRJEGWIQcWEq1Z-nq

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,AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton,
  ViewGroup派生出的直接子類有:AbsoluteLayout,AdapterView,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)
  DV6300-T的節目編輯就是自定義ViewGroup的使用
  關於自定義ViewGroup的知識,我們可以參考E:\JAVA\Android\資料\網絡資料\應用列表滑動總結\AppList測試代碼,會有更深刻的認識。
  給大家介紹下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)
  測試代碼:
  E:\JAVA\Android\資料\網絡資料\應用列表滑動總結\AppList
  E:\JAVA\Android\資料\網絡資料\View和ViewGroup\ViewGruop_ViewTest


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM