1. 程式人生 > >Android學習(十)—— Android自定義控制元件

Android學習(十)—— Android自定義控制元件

Android自定義控制元件

安卓在使用中大多數使用已有的一些控制元件,用法比較簡單,還有一部分是比較複雜的、使用者自己想的控制元件,這些就需要進行自定義控制元件,今天就來簡單說一下自定義控制元件。

1、繪製過程

  • 建立一個類,繼承View類
  • onMeasure()方法,測量計算檢視的大小
  • onLayout()方法,設定檢視在螢幕中顯示的位置
  • onDraw()方法,繪製檢視

以上就是自定義控制元件的繪製過程。

2、主要內容解釋

  • measure操作

  用於計算檢視的大小,即檢視的寬度和長度。在view中定義為final型別,要求子類不能修改。measure()函式中又會呼叫下面的函式:

     (1)onMeasure(),確定檢視大小,也就是說measure只是對onMeasure的一個包裝,子類可以覆寫onMeasure()方法實現自己的計算檢視大小的方式,並通過setMeasuredDimension(width, height)儲存計算結果。

  (2)關於MeasureSpec:

     UPSPECIFIED:父容器對於子容器沒有任何限制,子容器想要多大就多大.

     EXACTLY:父容器已經為子容器設定了尺寸,子容器應當服從這些邊界,不論子容器想要多大的空間.

     AT_MOST:

子容器可以是宣告大小內的任意大小.

  • layout操作 

       用於設定檢視在螢幕中顯示的位置。在view中定義為final型別,要求子類不能修改。layout()函式中有兩個基本操作:

     (1)setFrame(l,t,r,b),l,t,r,b即子檢視在父檢視中的具體位置,該函式用於將這些引數儲存起來;

     (2)onLayout(),在View中這個函式什麼都不會做,提供該函式主要是為viewGroup型別佈局子檢視用的;

  • draw操作

       利用前兩部得到的引數,將檢視顯示在螢幕上,到這裡也就完成了整個的檢視繪製工作。其內部定義了繪圖的基本操作:

     (1)繪製背景;

     (2)如果要檢視顯示漸變框,這裡會做一些前期工作;

     (3)繪製檢視本身,即呼叫onDraw()函式。在view中onDraw()是個空函式,也就是說具體的檢視都要覆寫該函式來實現自己的顯示。

     (4)繪製子檢視,即dispatchDraw()函式。在view中這是個空函式,具體的檢視不需要實現該方法,它是專門為容器類準備的,也就是容器類必須實現該方法;

     (5)應用程式呼叫了setVerticalFadingEdge或者setHorizontalFadingEdge,如果需要可以開始繪製漸變框;

     (6)繪製滾動條;

從上面可以看出自定義View需要最少覆寫onMeasure()和onDraw()兩個方法。

  • 自定義View的方法
  1. onFinishInflate(): 回撥方法,當應用從XML載入該元件並用它構建介面之後呼叫的方法
  2. onMeasure():檢測View元件及其子元件的大小
  3. onLayout(): 當該元件需要分配其子元件的位置、大小時
  4. onSizeChange():當該元件的大小被改變時
  5. onDraw(): 當元件將要繪製它的內容時
  6. onKeyDown: 當按下某個鍵盤時
  7. onKeyUp:  當鬆開某個鍵盤時
  8. onTrackballEvent: 當發生軌跡球事件時
  9. onTouchEvent: 當發生觸屏事件時
  10. onWindowFocusChanged(boolean):當該元件得到、失去焦點時
  11. onAtrrachedToWindow():當把該元件放入到某個視窗時
  12. onDetachedFromWindow():當把該元件從某個視窗上分離時觸發的方法
  13. onWindowVisibilityChanged(int):當包含該元件的視窗的可見性發生改變時觸發的方法

 3、效果圖展示

4、程式碼展示

在java程式碼中我加了很多註釋,方便進行理解、學習。

佈局檔案

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:id="@+id/container"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6 
 7     <sample.sdk.qy.com.androiddemo.Customize
 8         android:layout_width="match_parent"
 9         android:layout_height="match_parent"
10         android:layout_margin="20dp"
11         />
12 
13 </LinearLayout>

自定義控制元件類

 1 public class Customize extends View {
 2     private final static String TAG = Customize.class.getSimpleName();
 3     private Paint mPaint;
 4     private RectF oval;
 5 
 6     public Customize(Context context) {
 7         super(context);
 8         init();
 9     }
10 
11     public Customize(Context context, AttributeSet attrs) {
12         super(context, attrs);
13         init();
14     }
15 
16     public Customize(Context context, AttributeSet attrs, int defStyleAttr) {
17         super(context, attrs, defStyleAttr);
18         init();
19     }
20 
21     private void init(){
22         mPaint = new Paint();
23         mPaint.setAntiAlias(true);
24         oval=new RectF();
25     }
26     @Override
27     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
28         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
29         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
30         int widthSize = MeasureSpec.getSize(widthMeasureSpec);
31         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
32         int heightSize = MeasureSpec.getSize(heightMeasureSpec);
33         switch (widthMode) {
34             case MeasureSpec.EXACTLY:
35                 break;
36             case MeasureSpec.AT_MOST:
37                 break;
38             case MeasureSpec.UNSPECIFIED:
39                 break;
40         }
41     }
42 
43     @Override
44     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
45         super.onLayout(changed, left, top, right, bottom);
46 
47     }
48 
49     @Override
50     protected void onDraw(Canvas canvas) {
51         super.onDraw(canvas);
52         //設定演顏色
53         mPaint.setColor(Color.GREEN);
54         // FILL填充, STROKE描邊,FILL_AND_STROKE填充和描邊
55         mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
56         //獲取控制元件的寬度和高度
57         int with = getWidth();
58         int height = getHeight();
59         //設定圓的半徑
60         float radius = with / 4;
61         //畫圓,設定顏色
62         canvas.drawCircle(with / 2, with / 2, radius, mPaint);
63         mPaint.setColor(Color.BLUE);
64         //用於定義的圓弧的形狀和大小的界限
65         oval.set(with / 2 - radius, with / 2 - radius, with / 2
66                 + radius, with / 2 + radius);
67         //根據進度畫圓弧
68         canvas.drawArc(oval, 270, 90, true, mPaint);
69         //畫出另一個圓弧
70         mPaint.setColor(Color.YELLOW);
71         canvas.drawArc(oval, 360, 120, true, mPaint);
72     }
73 }

MainActivity類

 1 public class MainActivity extends Activity {
 2 
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_main);
 7 
 8     }
 9 
10 }