【朝花夕拾】Android自定義View篇之(四)自定義View的三種實現方式及自定義屬性使用介紹


前言

       轉載請聲明,轉自【https://www.cnblogs.com/andy-songwei/p/10979161.html】,謝謝!

       盡管Android系統提供了不少控件,但是有很多酷炫效果仍然是系統原生控件無法實現的。好在Android允許自定義控件,來彌補原生控件的不足。但是在很多初學者看來,自定義View似乎很難掌握。其中有很大一部分原因是我們平時看到的自定義View使用中,有多種形式,有的寥寥數筆,有的邏輯很復雜,有的直接繼承View或ViewGroup,有的卻直接繼承系統的原生控件,有的可以直接使用系統定義的屬性,而有的卻自定義了自己的屬性......所以不明白使用規則的開發者,很容易被這只“紙老虎”嚇到。

       實際上實現自定義View的方式,從整體上看,只分為三種:組合控件,繼承控件,自繪控件。然后就是根據需要來添加自定義的屬性,就這么簡單。本文將會針對這4個方面進行詳細的講解。主要內容如下:

 

 

 

一、組合控件

       組合控件,顧名思義,就是將系統原有的控件進行組合,構成一個新的控件。這種方式下,不需要開發者自己去繪制圖上顯示的內容,也不需要開發者重寫onMeasure,onLayout,onDraw方法來實現測量、布局以及draw流程。所以,在實現自定義view的三種方式中,這一種相對比較簡單。

       實際開發中,標題欄就是一個比較常見的例子。因為在一個app的各個界面中,標題欄基本上是大同小異,復用率很高。所以經常會將標題欄單獨做成一個自定義view,在不同的界面直接引入即可,而不用每次都把標題欄布局一遍。本節就自定義一個標題欄,包含標題和返回按鈕兩個控件,來介紹這種組合控件的實現方式。

  1、定義標題欄布局文件

       定義標題欄的布局文件custom_title_view.xml,將返回按鈕和標題文本進行組合。這一步用於確定標題欄的樣子,代碼如下所示:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="wrap_content"
 5     android:background="@android:color/holo_orange_light">
 6     <Button
 7         android:id="@+id/btn_left"
 8         android:layout_width="wrap_content"
 9         android:layout_height="wrap_content"
10         android:layout_centerVertical="true"
11         android:layout_marginLeft="5dp"
12         android:text="Back"
13         android:textColor="@android:color/white" />
14 
15     <TextView
16         android:id="@+id/title_tv"
17         android:layout_width="wrap_content"
18         android:layout_height="wrap_content"
19         android:layout_centerInParent="true"
20         android:text="Title"
21         android:textColor="@android:color/white"
22         android:textSize="20sp" />
23 </RelativeLayout>

這個布局很簡單,就不多說了。

 

  2、根據給定布局實現自定義View

 1 public class CustomTitleView extends FrameLayout implements View.OnClickListener {
 2     private View.OnClickListener mLeftOnClickListener;
 3     private Button mBackBtn;
 4     private TextView mTittleView;
 5 
 6     public CustomTitleView(@NonNull Context context, @Nullable AttributeSet attrs) {
 7         super(context, attrs);
 8         LayoutInflater.from(context).inflate(R.layout.custom_title_view, this);
 9         mBackBtn = findViewById(R.id.btn_left);
10         mBackBtn.setOnClickListener(this);
11         mTittleView = findViewById(R.id.title_tv);
12     }
13 
14     @Override
15     public void onClick(View v) {
16         switch (v.getId()) {
17             case R.id.btn_left:
18                 if (mLeftOnClickListener != null) {
19                     mLeftOnClickListener.onClick(v);
20                 }
21                 break;
22         }
23     }
24 
25     public void setLeftOnClickListener(View.OnClickListener leftOnClickListener) {
26         mLeftOnClickListener = leftOnClickListener;
27     }
28 
29     public void setTittle(String title){
30         mTittleView.setText(title);
31     }
32 }

為了編譯理解和記憶,這里對該部分做一點說明:

    (1)代碼中對外提供了兩個接口,一是動態設置標題,二是使用者可以自定義返回按鈕的點擊事件。

    (2)CustomTitleView的構造函數,要選擇兩個參數的,選擇其它參數的構造函數會報錯。這一點是筆者開發機測試的結果,暫時不清楚是不是所有手機上都是這樣。

    (3)這里是繼承的FrameLayout,但是繼承LinearLayout,RelativeLayout等系統布局控件都可以。之所以要繼承這些系統現成的ViewGroup,是因為這樣可以不用再重寫onMeasure,onLayout等,這樣省事很多。由於這里是一個布局控件,要用LayoutInflater來填充,所以需要繼承ViewGroup,如果繼承View的直接子類,編譯會不通過。所以,CustomTitleView自己就是一個容器,完全可以當成容器使用,此時CustomTitleView自身的內容會和其作為父布局添加的子控件,效果會疊加,具體的疊加效果是根據繼承的容器特性決定的。

 

  3、在Activity的布局文件中添加CustomTitleView

       在Activity的布局文件activity_custom_view_compose_demo.xml中,像使用系統控件一樣使用CustomTitleView即可。前說了,CustomTitleView自己就是繼承的現成的系統布局,所以它們擁有的屬性特性,CustomTitleView一樣擁有。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5     <com.example.demos.customviewdemo.CustomTitleView
 6         android:id="@+id/customview_title"
 7         android:layout_width="match_parent"
 8         android:layout_height="wrap_content">
 9     </com.example.demos.customviewdemo.CustomTitleView>
10 </RelativeLayout>

 

  4、在Activity中操作CustomTitleView

 1 public class CustomViewComposeDemoActivity extends AppCompatActivity {
 2 
 3     private CustomTitleView mCustomTitleView;
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_custom_view_compose_demo);
 8         mCustomTitleView = findViewById(R.id.customview_title);
 9         mCustomTitleView.setTittle("This is Title");
10         mCustomTitleView.setLeftOnClickListener(new View.OnClickListener() {
11             @Override
12             public void onClick(View v) {
13                 finish();
14             }
15         });
16 
17     }
18 }

在第8行中,獲取到CustomTitleView實例,第9行設置標題文字,第10行自定義“Back”按鈕點擊事件。

 

  5、效果圖

       按照如上的4步,就通過組合控件完成了一個比較簡單的自定義標題欄。可見,這種方式是非常簡單的。

 

二、繼承控件

       通過繼承系統控件(View子類控件或ViewGroup子類控件)來完成自定義View,一般是希望在原有系統控件基礎上做一些修飾性的修改,而不會做大幅度的改動,如在TextView的文字下方添加下划線,在LinearLayout布局中加一個蒙板等。這種方式往往都會復用系統控件的onMeasure和onLayout方法,而只需要重寫onDraw方法,在其中繪制一些需要的內容。下面會分別繼承View類控件和ViewGroup類控件來舉例說明。

  1、繼承View類系統控件

       如下示例為在TextView文字下方顯示紅色下划線,其基本步驟如下:

    (1)繼承View控件,並重寫onDraw方法

 1 @SuppressLint("AppCompatCustomView")
 2 public class UnderlineTextView extends TextView{
 3     public UnderlineTextView(Context context, @Nullable AttributeSet attrs) {
 4         super(context, attrs);
 5     }
 6 
 7     @Override
 8     protected void onDraw(Canvas canvas) {
 9         super.onDraw(canvas);
10         Paint paint = new Paint();
11         paint.setColor(Color.RED);
12         paint.setStrokeWidth(5);
13         int width = getWidth();
14         int height = getBaseline();
15         canvas.drawLine(0,height,width,height,paint);
16     }
17 }

    (2)在布局文件中調用

       就像使用一個普通TextView一樣使用UnderlineTextView。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5     <com.example.demos.customviewdemo.UnderlineTextView
 6         android:layout_width="wrap_content"
 7         android:layout_height="wrap_content"
 8         android:textSize="50dp"
 9         android:layout_centerInParent="true"
10         android:text="Hello World!"/>
11 </RelativeLayout>

    (3)效果圖

    

 

  2、繼承ViewGroup類系統控件

       如下示例演示,在layout布局上添加一個淺紅色的半透明蒙板,這種需求在工作中也是非常常見的。

    (1)繼承ViewGroup類系統控件

 1 public class ForegroundLinearLayout extends LinearLayout{
 2     public ForegroundLinearLayout(Context context, @Nullable AttributeSet attrs) {
 3         super(context, attrs);
 4     }
 5 
 6     @Override
 7     protected void dispatchDraw(Canvas canvas) {
 8         super.dispatchDraw(canvas);
 9         canvas.drawColor(Color.parseColor("#50FF0000"));
10     }
11 }

     (2)在布局文件中調用

       對ForegroundLinearLayout的使用,就和使用其父類LinearLayout一樣。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">   
 5        <com.example.demos.customviewdemo.ForegroundLinearLayout
 6         android:layout_width="match_parent"
 7         android:layout_height="200dp"
 8         android:layout_centerInParent="true"
 9         android:gravity="center">
10 
11         <TextView
12             android:layout_width="wrap_content"
13             android:layout_height="wrap_content"
14             android:layout_centerInParent="true"
15             android:text="Hello World!"
16             android:textColor="@android:color/black"
17             android:textSize="50dp" />
18     </com.example.demos.customviewdemo.ForegroundLinearLayout>
19 </RelativeLayout>

     (3)效果圖

       在寬為全屏寬度,高為200dp的布局范圍內,繪制完子其子控件TextView后,在上面覆蓋了一層淺紅色的半透明蒙板。

 

        從上面兩個例子可見,繼承系統原有的控件來實現自定義View,步驟非常簡單,比組合控件簡單多了。但是這一節需要對Canvas,paint等繪制方面的知識有一定的了解,且還需要對ViewGroup的中內容的繪制順序有一定的了解,才能在原生控件的基礎上做出想要的效果來。

 

三、自繪控件

       這三種方法中,自繪控件是最復雜的,因為所有的繪制邏輯和流程都需要自己完成。采用自繪控件這種方式時,如果自定義View為最終的葉子控件,那么需要直接繼承View;而不過自定義View為容器類控件,則需要直接繼承ViewGroup。這里依然針對直接繼承View和ViewGroup分別舉例進行說明。

  1、自繪葉子View控件

       這里通過畫一個直方圖來展示自繪View控件的實現。

    (1)直接繼承View類

       自繪葉子View控件時,最主要工作就是繪制出豐富的內容,這一過程是在重寫的onDraw方法中實現的。由於是葉子view,它沒有子控件了,所以重寫onLayout沒有意義。onMeasure的方法可以根據自己的需要來決定是否需要重寫,很多情況下,不重寫該方法並不影響正常的繪制。

 1 public class HistogramView extends View{
 2 
 3     private Paint mPaint;
 4     private Path mPath;
 5 
 6     public HistogramView(Context context, @Nullable AttributeSet attrs) {
 7         super(context, attrs);
 8         mPaint = new Paint();
 9         mPath = new Path();
10     }
11 
12     @Override
13     protected void onDraw(Canvas canvas) {
14         super.onDraw(canvas);
15         //繪制坐標軸
16         mPaint.reset();
17         mPath.reset();
18         mPaint.setColor(Color.BLACK);
19         mPaint.setStyle(Paint.Style.STROKE);
20         mPath.moveTo(100,100);
21         mPath.rLineTo(0,402);
22         mPath.rLineTo(800,0);
23         canvas.drawPath(mPath,mPaint);
24         //繪制文字
25         mPaint.reset();
26         mPaint.setTextSize(30);
27         mPaint.setStyle(Paint.Style.FILL);
28         canvas.drawText("Froyo",160,540,mPaint);
29         canvas.drawText("CB",280,540,mPaint);
30         canvas.drawText("ICS",380,540,mPaint);
31         canvas.drawText("J",480,540,mPaint);
32         canvas.drawText("KitKat",560,540,mPaint);
33         canvas.drawText("L",690,540,mPaint);
34         canvas.drawText("M",790,540,mPaint);
35         //繪制直方圖,柱形圖是用較粗的直線來實現的
36         mPaint.reset();
37         mPaint.setColor(Color.GREEN);
38         mPaint.setStrokeWidth(80);
39         float[] lines3={
40                 200,500,200,495,
41                 300,500,300,480,
42                 400,500,400,480,
43                 500,500,500,300,
44                 600,500,600,200,
45                 700,500,700,150,
46                 800,500,800,350,
47         };
48         canvas.drawLines(lines3,mPaint);
49     }
50 }

     (2)在Activity界面的布局文件中引入

       和其它自定義控件一樣,直接在布局文件中引入即可。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <com.example.demos.customviewdemo.HistogramView
 7         android:layout_width="match_parent"
 8         android:layout_height="wrap_content"/>
 9 
10 </RelativeLayout>

     (3)效果圖

 

  2、自繪ViewGroup控件

       這里通過自定義一個父布局控件,並添加一個子view來作為例子講解該方法的實現。

    (1)直接繼承ViewGroup類

       自繪ViewGroup控件,需要直接繼承ViewGroup,在該系列第一篇文章中將繪制流程的時候就講過,onLayout是ViewGroup中的抽象方法,其直接繼承者必須實現該方法。所以這里,onLayout方法必須要實現的,如果這里面的方法體為空,那該控件的子view就無法顯示了。要想准確測量,onMeasure方法也是要重寫的。下面例子中,只演示了第一個子view的測量和布局,onLayout方法中的child.layout,就完成了對子view的布局。

 1 public class CustomLayout extends ViewGroup {
 2     public CustomLayout(Context context, AttributeSet attrs) {
 3         super(context, attrs);
 4     }
 5 
 6     @Override
 7     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 8         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 9         if (getChildCount() > 0) {
10             //只測量第一個child
11             View child = getChildAt(0);
12             measureChild(child, widthMeasureSpec, heightMeasureSpec);
13         }
14     }
15 
16     @Override
17     protected void onLayout(boolean changed, int l, int t, int r, int b) {
18         if (getChildCount() > 0) {
19             //只布局第一個child
20             View child = getChildAt(0);
21             child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
22         }
23     }
24 }

     (2)在布局文件中和普通父布局一樣被引入

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <com.example.demos.customviewdemo.CustomLayout
 7         android:layout_width="match_parent"
 8         android:layout_centerInParent="true"
 9         android:layout_height="wrap_content">
10         <TextView
11             android:layout_width="wrap_content"
12             android:layout_height="wrap_content"
13             android:text="Hello World!"
14             android:textSize="50dp"/>
15 
16     </com.example.demos.customviewdemo.CustomLayout>
17 
18 </RelativeLayout>

    (3)效果圖

       上述代碼中第8行沒有起效,從布局上看TextView應該是處於屏幕的正中央,但是實際結果卻還是在左上方顯示。這是因為CustomLayout控件,並沒有實現“android:layout_centerInParent”這個屬性,所以是無效的。關於屬性的問題,正是下一節要介紹的內容。

 

四、在自定義View中使用自定義屬性

       我們在使用Android原生控件的時候,經常可以看到在布局文件中可以設置很多的屬性值,如

1 <TextView
2         android:id="@+id/title_tv"
3         android:layout_width="wrap_content"
4         android:layout_height="wrap_content"
5         android:layout_centerInParent="true"
6         android:text="Title"
7         android:textColor="@android:color/white"
8         android:textSize="20sp" />

這里可以根據需要隨時設置TextView要顯示的文字,文字顏色,文字大小等各種屬性,給使用者帶來了極大的方便。我們在使用自定義View的時候,也非常希望能夠像TextView等系統原生控件一樣通過設置屬性值來個性化自定義View。本節咱們在上一節自定義直方圖的基礎上,來介紹自定義屬性的基本使用流程。

 

  1、在values中編寫需要的屬性

       在res/values/下新建資源文件,這里咱們命名為attrs.xml,在其中編寫所需要的屬性

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     <declare-styleable name="HistogramView">
4         <attr name="textColor" format="color"/>
5         <attr name="histogramColor" format="color"/>
6     </declare-styleable>
7 </resources>

這里<declare-styleable>中的name是自行命名的,可以理解為這個自定義屬性集合的名稱。代碼中包含了兩個自定義屬性,名稱分別為“textColor”和“histogramColor”,這里用來設置直方圖中文字的顏色和直方圖的顏色。format表示的是屬性的格式,這里均設置為“color”,表示對應的屬性是用來設置顏色值的。對於“format”,后面還會詳細講到。其它的就是固定的格式了,直接套用就行。

 

  2、在自定義View中引入屬性

 1 public class HistogramView extends View{
 2 
 3     private Paint mPaint;
 4     private Path mPath;
 5     private int mTextColor,mHistogramColor;
 6 
 7     public HistogramView(Context context, @Nullable AttributeSet attrs) {
 8         super(context, attrs);
 9         mPaint = new Paint();
10         mPath = new Path();
11         initAttrs(context,attrs);
12     }
13 
14 
15     private void initAttrs(Context context, AttributeSet attrs){
16         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HistogramView);
17         mTextColor = typedArray.getColor(R.styleable.HistogramView_textColor,Color.BLACK);
18         mHistogramColor = typedArray.getColor(R.styleable.HistogramView_histogramColor,Color.GREEN);
19         typedArray.recycle();
20     }
21 
22     @Override
23     protected void onDraw(Canvas canvas) {
24         super.onDraw(canvas);
25         //繪制坐標軸
26         mPaint.reset();
27         mPath.reset();
28         mPaint.setColor(Color.BLACK);
29         mPaint.setStyle(Paint.Style.STROKE);
30         mPath.moveTo(100,100);
31         mPath.rLineTo(0,402);
32         mPath.rLineTo(800,0);
33         canvas.drawPath(mPath,mPaint);
34         //繪制文字
35         mPaint.reset();
36         mPaint.setTextSize(30);
37         mPaint.setColor(mTextColor);
38         mPaint.setStyle(Paint.Style.FILL);
39         canvas.drawText("Froyo",160,540,mPaint);
40         canvas.drawText("CB",280,540,mPaint);
41         canvas.drawText("ICS",380,540,mPaint);
42         canvas.drawText("J",480,540,mPaint);
43         canvas.drawText("KitKat",560,540,mPaint);
44         canvas.drawText("L",690,540,mPaint);
45         canvas.drawText("M",790,540,mPaint);
46         //繪制直方圖,柱形圖是用較粗的直線來實現的
47         mPaint.reset();
48         mPaint.setColor(mHistogramColor);
49         mPaint.setStrokeWidth(80);
50         float[] lines3={
51                 200,500,200,495,
52                 300,500,300,480,
53                 400,500,400,480,
54                 500,500,500,300,
55                 600,500,600,200,
56                 700,500,700,150,
57                 800,500,800,350,
58         };
59         canvas.drawLines(lines3,mPaint);
60     }
61 }

       將上述代碼和前面第三節中自繪直方圖代碼對比,紅色部分是修改或新增的代碼。第15~20行代碼就是初始化屬性的地方,這個過程需要在構造函數中完成。其中,第16行是和自定義屬性集建立聯系,第17和18行是獲取開發者在布局文件中使用時設置的相應屬性值,如果沒有設置,則會使用默認設置的顏色,分別為Color.BLACK和Color.GREEN。這里注意第19行,用完后一定要回收資源。這樣就初始化了文字顏色mTextColor值和mHistogramColor值,在后面onDraw中就使用該值來繪制對應的部分。

  

  3、在布局文件中設置屬性值

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent">
 6 
 7     <com.example.demos.customviewdemo.HistogramView
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         app:textColor="@android:color/holo_red_light"
11         app:histogramColor="@android:color/holo_blue_bright"/>
12 
13 </RelativeLayout>

這段代碼中,第3,10,11行和以往的布局文件有些不一樣,這是使用自定義屬性時的固定格式。第3行中,如果布局文件中沒有這一句,一定要加上,這句是聲明命名空間,只有聲明了命名空間才能使用自定義屬性。“app”是該命名空間的名稱,這里是自行命名的,不一定非要用“app”。第10行和11行,“app:attrName”表示用的是自定義的屬性,固定用法,前面mTextColor和mHistogramColor值就是從這里獲取的。

       還記得上一節結尾處說“android:layout_centerInParent”沒有起效嗎?現在我們知道,這里設置的屬性,是在自定義View代碼中獲取該值,根據該值來確定顯示效果的。“android:layout_centerInParent”的值在View的源碼中沒有被使用,所以設置后也就無效了。“android:layout_width”和“android:layout_height”屬性是必須要有的,所有的View的實現都要用到這兩個屬性來確定寬高。現在,咱們應該明白,設置控件屬性值是如何起作用的了吧。

 

  4、效果圖

      

五、自定義屬性格式匯總

       在上面一節中,僅僅只是對文字顏色和直方圖顏色的屬性值做了設置,是為了演示自定義屬性的使用步驟。在實際開發中,完全可以定義更多類型的屬性,如顯示文字的內容,文字的大小,直方圖的寬度等。format也不只限定於“color”,還有“String”,“Integer”等,多種多樣。本節就匯總一下平時比較常用的一些屬性format。

       本節主要參考了如下文章:【Android自定義View全解

   1、常用的11種format類型

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3     <declare-styleable name="SelfAttr">
 4         <!--1.reference:參考某一資源ID-->
 5         <attr name="background" format="reference" />
 6         <!--2. color:顏色值-->
 7         <attr name = "textColor" format = "color" />
 8         <!--3.boolean:布爾值-->
 9         <attr name = "focusable" format = "boolean" />
10         <!--4.dimension:尺寸值-->
11         <attr name = "layout_width" format = "dimension" />
12         <!--5. float:浮點值-->
13         <attr name = "fromAlpha" format = "float" />
14         <!--6.integer:整型值-->
15         <attr name = "lines" format="integer" />
16         <!--7.string:字符串-->
17         <attr name = "text" format = "string" />
18         <!--8.fraction:百分數-->
19         <attr name = "pivotX" format = "fraction" />
20         <!--9.enum:枚舉值。屬性值只能選擇枚舉值中的一個-->
21         <attr name="orientation">
22             <enum name="horizontal" value="0" />
23             <enum name="vertical" value="1" />
24         </attr>
25         <!--10.flag:位或運算。屬性值可以選擇其中多個值-->
26         <attr name="gravity">
27             <flag name="top" value="0x01" />
28             <flag name="bottom" value="0x02" />
29             <flag name="left" value="0x04" />
30             <flag name="right" value="0x08" />
31             <flag name="center_vertical" value="0x16" />
32             ...
33         </attr>
34         <!--11.混合類型:屬性定義時可以指定多種類型值-->
35         <attr name = "background_2" format = "reference|color" />
36     </declare-styleable>
37 </resources>

如上列出了平時工作中在常見的11種類型的格式,說是11種,但最后一種是前面10種的組合而已。看到上述的屬性名稱應該很熟悉吧,都是系統原生控件的屬性名稱。

  

  2、使用舉例

       如下對上述屬性的使用一一舉例演示,可以對照着來理解,都是平時常用的系統控件。

 1 <!--1.reference:參考某一資源ID-->
 2     <ImageView android:background = "@drawable/圖片ID"/>
 3     <!--2. color:顏色值-->
 4     <TextView android:textColor = "#00FF00"/>
 5     <!--3.boolean:布爾值-->
 6     <Button android:focusable = "true"/>
 7     <!--4.dimension:尺寸值-->
 8     <Button android:layout_width = "42dp"/>
 9     <!--5. float:浮點值-->
10     <alpha android:fromAlpha = "1.0"/>
11     <!--6.integer:整型值-->
12     <TextView android:lines="1"/>
13     <!--7.string:字符串-->
14     <TextView android:text = "我是文本"/>
15     <!--8.fraction:百分數-->
16     <rotate android:pivotX = "200%"/>
17     <!--9.enum:枚舉值-->
18     <LinearLayout
19         android:orientation = "vertical">
20     </LinearLayout>
21     <!--10.flag:位或運算-->
22     <TextView android:gravity="bottom|left"/>
23     <!--11.混合類型:屬性定義時可以指定多種類型值-->
24     <ImageView android:background = "@drawable/圖片ID" />
25     <!--或者-->
26     <ImageView android:background = "#00FF00" />

 

結語

       關於自定義View的3中實現方式以及自定義屬性的使用,這里就講完了。讀完后,是不是發現基本的實現流程其實非常簡單呢?當然,本文為了說明實現流程,所以舉的例子都比較簡單,但不是說繪制內容也一樣簡單。就好像辦理入學手續很簡單,但讀書這件事卻不那么容易一樣。要完成一些酷炫的自定義View,還需要好好地掌握Canvas,Paint,Path等工具的使用,以及View的繪制流程原理。當然,本文肯定有很多描述不妥或不准確的地方,歡迎來拍磚。


免責聲明!

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



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