Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android自定義View入門(一),androidview

Android自定義View入門(一),androidview

編輯:關於android開發

Android自定義View入門(一),androidview


最近在寫一個關於音樂播放的應用,寫到播放界面UI時,就想自己實現的一個播放界面。那麼如何實現自定義View呢?通過查看他人博客和Android官方開發文檔,初步了解了一些淺顯的內容。在此記錄,已供需要的朋友參考。

自定義視圖的官方參考文檔:http://developer.android.com/training/custom-views/create-view.html

當我們使用XML布局文件進行UI編寫時,通過增加xml tag我們可以加入自己想要的任何view組件,例如下面的布局文件(只是個例子,刪除了其他不重要布局元素):

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     <TextView
6         android:layout_width="match_parent"
7         android:layout_height="match_parent" />
8 </RelativeLayout>

用過<RelativeLayout 引入RelativeLayout,通過<TextView引入TextView。然後在對應便簽了加入了各種屬性(如:android:layout_width、android:layout_heignt),編譯程序在編譯時會解析xml文件,把對應的tag生成相應的view對象。

那麼自己定義的view如何通過上面那種方式使用呢?這就要說到xmlns(XML namespace)了。了解XML的朋友都知道,XML為了傳輸數據設計的可拓展標記語言,它不同於HTML有預定義的各種便簽,它的便簽是用戶自定義的。在哪定義呢?xmlns!

不知道你注意到沒,我們的布局文件中總是用這樣一行代碼:

xmlns:android="http://schemas.android.com/apk/res/android"

這就是引入命名空間。更過關於XML知識,請查看:XML介紹。簡單來說通過在頂級tag中引入命名空間,整個個xml都可以用命名空間中定義的內容了,如android:id等。那麼怎麼為我們的自己寫的view添加命名空間呢?

下面我們來創建自己的命名空間文件:首先在res->values目錄下新建attrs資源文件,如下圖:

在attrs中定義裡需要表述的屬性:

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     <declare-styleable name="Circle">
4         <attr name="radius" format="dimension"/>
5         <attr name="background_color" format="color"/>
6     </declare-styleable>
7 </resources>

其中declare-styeable節點的name屬性值一般是你寫的view的名字,如這裡我自己寫的view叫Cirecle。接下來定義可以在xml中定義的組件屬性,這裡可以指定兩個,radius和background。其中format屬性指定可接受值的類型,多個類型用“|”分隔。

更多關於怎麼寫attrs可以參考Android sdk目錄下的platforms\android-xxx\data\res\values\attrs.xml文件,哪裡為自帶的所有空間聲明了命名空間。

寫好的命名空間如何使用呢?下面給出布局文件:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:custom="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     android:paddingBottom="@dimen/activity_vertical_margin"
 8     android:paddingLeft="@dimen/activity_horizontal_margin"
 9     android:paddingRight="@dimen/activity_horizontal_margin"
10     android:paddingTop="@dimen/activity_vertical_margin"
11     tools:context="com.github.fallblank.myapplication.MainActivity">
12     <!--引入自定義View,並設置屬性-->
13     <com.github.fallblank.myapplication.Circle
14         android:id="@+id/circle"
15         android:layout_width="wrap_content"
16         android:layout_height="wrap_content"
17         custom:background_color="#ff0000"
18         custom:radius="100dp" />
19   <!--下面兩個按鈕是為了改變View使其重繪-->
20     <Button
21         android:id="@+id/btn_larger"
22         android:layout_width="wrap_content"
23         android:layout_height="wrap_content"
24         android:layout_alignParentBottom="true"
25         android:text="Larger" />
26 
27     <Button
28         android:id="@+id/btn_smaller"
29         android:layout_width="wrap_content"
30         android:layout_height="wrap_content"
31         android:layout_toRightOf="@id/btn_larger"
32         android:layout_alignParentBottom="true"
33         android:text="Smaller" />
34 </RelativeLayout>

注意這行代碼:

xmlns:custom="http://schemas.android.com/apk/res-auto"

這裡就是引入自定義的命名空間,有了這行代碼後面就可以使用我們之前定義的內容custom:radius和custom:backgroud_color了。需要注意的是這裡引入的方式適合於gradle編譯,對應ant編譯,xmlns定義如下:

xmlns:custom="http://schemas.android.com/apk/res/自定義view的包名

 接下來就是如何獲取在xml指定屬性的值了,下面給出自定義view的代碼:

 1 package com.github.fallblank.myapplication;
 2 
 3 import android.content.Context;
 4 import android.content.res.TypedArray;
 5 import android.graphics.Canvas;
 6 import android.graphics.Paint;
 7 import android.util.AttributeSet;
 8 import android.view.View;
 9 import android.widget.Toast;
10 
11 /**
12  * Created by fallb on 2015/11/24.
13  */
14 public class Circle extends View {
15 
16     private int mColor;
17     private Context mContext;
18     private float mRadius;
19 
20     public Circle(Context context, AttributeSet attrs) {
21         super(context, attrs);
22         mContext = context;
23         TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.Circle,0,0);
24         try {
25             //
26             mColor = a.getColor(R.styleable.Circle_line_color,0x000000);
27             mRadius = a.getDimension(R.styleable.Circle_side,16);
28         }finally {
29             a.recycle();
30         }
31     }
32 
33     public void addSide() {
34         mRadius+=5.0;
35         invalidate();
36         requestLayout();
37     }
38 
39     public void subSide(){
40         if (mRadius>=5.0){
41             mRadius-=5.0;
42             invalidate();
43             requestLayout();
44         }else {
45             Toast.makeText(mContext,"smaller enough!",Toast.LENGTH_LONG).show();
46         }
47     }
48 
49     @Override
50     protected void onDraw(Canvas canvas) {
51         super.onDraw(canvas);
52         Paint paint = new Paint();
53         paint.setColor(mColor);
54         canvas.drawCircle(0,0,mRadius,paint);
55     }
56 }

上面標紅的代碼就是獲取定義在xml中的屬性的方法(為什麼不用AttributeSet直接獲取屬性?官方文檔有介紹,需要了解的朋友可以去看看)

獲取到屬性後就是實現自己的繪圖方法,重載onDraw()實現繪制。對應怎麼使用Pait、canvas,我會在後面介紹。

 

說了這麼多,來總結一下。

  • 自定義視圖為了能在xml布局文件中同Android定義視圖一樣使用,需要創建attrs布局文件。
  • 在View實現代碼中通過上面的方式獲取定義在xml中的屬性,然後實現繪制。
  • xml布局文件為了能使用自定義view需要引入用戶定義的命名空間。

 

為了不空放嘴炮,最後給出效果圖和代碼:

樣例代碼:https://github.com/fallblank/CustomView

 

現在遇到一個疑問:我定義的View在xml中的默認大小是充滿這個父控件,指定寬度為wrap_content也沒用。應該是哪裡沒設置,知道的朋友請告之!小弟大榭!

 

僅此拋磚引玉!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved