自訂View及ViewGroup

來源:互聯網
上載者:User

View類是ViewGroup的父類,ViewGroup具有View的所有特性,ViewGroup主要用來充當View的容器,將其中的View作為自己孩子,並對其進行管理,當然孩子也可以是ViewGroup類型。 View類一般用於繪圖操作,重寫它的onDraw方法,但它不可以包含其他組件,沒有addView(View view)方法。 ViewGroup是一個組件容器,它可以包含任何組件,但必須重寫onLayout(boolean changed,int l,int t,int r,int b)和onMesure(int widthMesureSpec,int heightMesureSpec)方法. 否則ViewGroup中添加組件是不會顯示的。  <strong><span style="font-family:FangSong_GB2312;font-size:14px;">package com.example.testrefreshview;    import android.app.Activity;  import android.content.Context;  import android.os.Bundle;  import android.view.ViewGroup;  import android.widget.Button;  import android.widget.TextView;    public class MainActivity extends Activity {        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(new MyViewGroup(this));        }        public class MyViewGroup extends ViewGroup {            public MyViewGroup(Context context) {              super(context);              Button button1 = new Button(context);              button1.setText("button1");                Button button2 = new Button(context);              button2.setText("button2");                TextView textView = new TextView(context);              textView.setText("textView");                addView(button1);              addView(button2);              addView(textView);          }            @Override          protected void onLayout(boolean arg0, int arg1, int arg2, int arg3,                  int arg4) {                        }      }  }</span></strong>  View的layout(int left,int top,int right,int bottom)方法負責把該view放在參數指定位置,所以如果我們在自訂的ViewGroup::onLayout中遍曆每一個子view並用view.layout()指定其位置,每一個子View又會調用onLayout,這就構成了一個遞迴調用的過程 如果在ViewGroup中重寫onDraw方法,需要在構造方法中調用this.setWillNoDraw(flase); 此時,系統才會調用重寫過的onDraw(Canvas cancas)方法,否則系統不會調用onDraw(Canvas canvas)方法. 將上面代碼修改一下,就可以顯示出來。  <strong><span style="font-family:FangSong_GB2312;font-size:14px;">package com.example.testrefreshview;    import android.app.Activity;  import android.content.Context;  import android.os.Bundle;  import android.view.View;  import android.view.ViewGroup;  import android.widget.Button;  import android.widget.TextView;    public class MainActivity extends Activity {        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(new MyViewGroup(this));        }        public class MyViewGroup extends ViewGroup {            public MyViewGroup(Context context) {              super(context);              Button button1 = new Button(context);              button1.setText("button1");                Button button2 = new Button(context);              button2.setText("button2");                TextView textView = new TextView(context);              textView.setText("textView");                addView(button1);              addView(button2);              addView(textView);          }            @Override          protected void onLayout(boolean arg0, int arg1, int arg2, int arg3,                  int arg4) {              int childCount = getChildCount();              int left = 0;              int top = 10;              for (int i = 0; i < childCount; i++) {                  View child = getChildAt(i);                  child.layout(left, top, left + 60, top + 60);                  top += 70;              }          }      }  }</span></strong>  再看一段代碼:  <strong><span style="font-family:FangSong_GB2312;font-size:14px;">@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {                int childCount = getChildCount();    //設定該ViewGroup的大小        int specSize_width = MeasureSpec.getSize(widthMeasureSpec);        int specSize_height = MeasureSpec.getSize(heightMeasureSpec);         setMeasuredDimension(specSize_width, specSize_height);                for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            childView.measure(80, 80);        }    }  </span></strong>  通過重寫onMeasure方法不但可以為ViewGroup指定大小,還可以通過遍曆為每一個子View指定大小,在自訂ViewGroup中添加上面代碼為ViewGroup中的每一個子View分配了顯示的寬高。 下面我們讓子View動起來吧,添加代碼如下: <strong><span style="font-family:FangSong_GB2312;font-size:14px;">public boolean onTouchEvent(MotionEvent ev) {      final float y = ev.getY();      switch(ev.getAction()) {      case MotionEvent.ACTION_DOWN:          mLastMotionY = y;          break;       case MotionEvent.ACTION_MOVE:          int detaY = (int)(mLastMotionY - y);          mLastMotionY = y;          scrollBy(0, detaY);          break;       case MotionEvent.ACTION_UP:          break;      }      return true;  }</span></strong>  在上面用到了一個scrollBy方法,開啟官方API可以看到View類有如下兩個方法:   這兩個函數貌似都是行動裝置檢視的,那麼它們有什麼區別呢?帶著這個疑問我們向下看 首先 ,我們必須明白在Android View視圖是沒有邊界的,Canvas是沒有邊界的,只不過我們通過繪製特定的View時對 Canvas對象進行了一定的操作,例如 : translate(平移)、clipRect(剪下)等,以便達到我們的對該Canvas對象繪製的要求 ,我們可以將這種無邊界的視圖稱為“視圖座標”-----它不受物理螢幕限制。通常我們所理解的一個Layout布局檔案只是該視圖的顯示地區,超過了這個顯示地區將不能顯示到父視圖的地區中 ,對應的,我們可以將這種有邊界的視圖稱為“布局座標”------ 父視圖給子視圖分配的布局(layout)大小。而且, 一個視圖的在螢幕的起始座標位於視圖座標起始處,如所示。 由於布局座標只能顯示特定的一塊內容,所以我們只有移動布局座標的座標原點就可以將視圖座標的任何位置顯示出來。<strong><span style="font-family:FangSong_GB2312;font-size:14px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="fill_parent"      android:layout_height="fill_parent"      android:orientation="vertical"      android:background="#888888">    <TextView      android:id="@+id/txt"      android:layout_width="300dip"      android:layout_height="120dip"      android:background="#cccccc"      android:text="textview" />    <Button      android:id="@+id/btn"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="button" />  </LinearLayout></span></strong>  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.