Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [Android] 自定義控件詳解

[Android] 自定義控件詳解

編輯:關於Android編程

在android應用開發過程中,固定的一些控件和屬性可能滿足不了開發的需求,所以在一些特殊情況下,我們需要自定義控件與屬性。

一、實現步驟

  1. 繼承View類或其子類 

  2. 復寫view中的一些函數

 3.為自定義View類增加屬性(兩種方式)

 4.繪制控件(導入布局)

 5.響應用戶事件

 6.定義回調函數(根據自己需求來選擇)

二、哪些方法需要被重寫

onDraw()

  view中onDraw()是個空函數,也就是說具體的視圖都要覆寫該函數來實現自己的繪制。對於ViewGroup則不需要實現該函數,因為作為容器是“沒有內容“的(但必須實現dispatchDraw()函數,告訴子view繪制自己)。

onLayout()

  主要是為viewGroup類型布局子視圖用的,在View中這個函數為空函數。

onMeasure()

  用於計算視圖大小(即長和寬)的方式,並通過setMeasuredDimension(width, height)保存計算結果。

onTouchEvent

  定義觸屏事件來響應用戶操作。
  

還有一些不常用的方法:

  onKeyDown 當按下某個鍵盤時  

  onKeyUp 當松開某個鍵盤時  
  
  onTrackballEvent 當發生軌跡球事件時  
  
  onSizeChange() 當該組件的大小被改變時  
  
  onFinishInflate() 回調方法,當應用從XML加載該組件並用它構建界面之後調用的方法  
  
  onWindowFocusChanged(boolean) 當該組件得到、失去焦點時  
  onAttachedToWindow() 當把該組件放入到某個窗口時  
  
  onDetachedFromWindow() 當把該組件從某個窗口上分離時觸發的方法  
  
  onWindowVisibilityChanged(int): 當包含該組件的窗口的可見性發生改變時觸發的方法  

三.自定義控件的三種方式

1. 繼承已有的控件

  當要實現的控件和已有的控件在很多方面比較類似, 通過對已有控件的擴展來滿足要求。

2. 繼承一個布局文件

  一般用於自定義組合控件,在構造函數中通過inflater和addView()方法加載自定義控件的布局文件形成圖形界面(不需要onDraw方法)。

3.繼承view

  通過onDraw方法來繪制出組件界面。

四.自定義屬性的兩種方法

  1.在布局文件中直接加入屬性,在構造函數中去獲得。

布局文件:


     

獲取屬性值:

public myView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
int textId = attrs.getAttributeResourceValue(null, "Text", 0);
String text = context.getResources().getText(textId).toString();
    }

2.在res/values/ 下建立一個attrs.xml 來聲明自定義view的屬性。

可以定義的屬性有:

 
//參考某一資源ID (name可以隨便命名)
 
//顏色值 
 
//布爾值
 
//尺寸值 
 
//浮點值 
 
//整型值 
 
//字符串 
 
//百分數 
 

//枚舉值 
 
 
 
 

//位或運算 
 
 
 
 

//多類型
 
 

attrs.xml進行屬性聲明



    
        
        
    

添加到布局文件


     

這裡注意命名空間:
xmlns:前綴=”http://schemas.android.com/apk/res/包名(或res-auto)”,

前綴:TextColor 使用屬性。

在構造函數中獲取屬性值

public myView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.myView); 
        String text = a.getString(R.styleable.myView_text); 
        int textColor = a.getColor(R.styleable.myView_textColor, Color.WHITE); 

        a.recycle();
    }

 或者:

    public myView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.myView); 
        int n = a.getIndexCount();
        for(int i=0;i

五. 自定義隨手指移動的小球(小例子)

實現上面的效果我們大致需要分成這幾步

在res/values/ 下建立一個attrs.xml 來聲明自定義view的屬性 一個繼承View並復寫部分函數的自定義view的類 一個展示自定義view 的容器界面

1.自定義view命名為myView,它有一個屬性值,格式為color、



    
        
            

2.在構造函數獲取獲得view的屬性配置和復寫onDraw和onTouchEvent函數實現繪制界面和用戶事件響應。

public class myView extends View{
    //定義畫筆和初始位置
    Paint p = new Paint();
    public float currentX = 50;
    public float currentY = 50;
    public int textColor;

    public myView(Context context, AttributeSet attrs) {
        super(context, attrs);
        //獲取資源文件裡面的屬性,由於這裡只有一個屬性值,不用遍歷數組,直接通過R文件拿出color值
        //把屬性放在資源文件裡,方便設置和復用
        TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.myView);
        textColor = array.getColor(R.styleable.myView_TextColor,Color.BLACK);
        array.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //畫一個藍色的圓形
        p.setColor(Color.BLUE);
        canvas.drawCircle(currentX,currentY,30,p);
        //設置文字和顏色,這裡的顏色是資源文件values裡面的值
        p.setColor(textColor);
        canvas.drawText("BY finch",currentX-30,currentY+50,p);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {


        currentX = event.getX();
        currentY = event.getY();
        invalidate();//重新繪制圖形
        return true;
    }
}

  這裡通過不斷的更新當前位置坐標和重新繪制圖形實現效果,要注意的是使用TypedArray後一定要記得recycle(). 否則會對下次調用產生影響。
  這裡寫圖片描述 

3.把myView加入到activity_main.xml布局裡面





    

4.最後是MainActivity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
具體的view要根據具體的需求來,比如我們要側滑刪除的listview我們可以繼承listview,監聽側滑事件,顯示刪除按鈕實現功能。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved