天天看點

【自定義視圖控件】入門篇----繼承View以及主要的函數

菜鳥日記:

看别人家寫的開關按鈕控件有滑動效果,感覺很炫酷。在網上找了下其實在SDK4.0版本及其以上,可以通過樣式檔案可以給switck...等标簽配置樣式屬性可以達到相近的效果。SDK 4.0一下也可以通過代碼自定視圖控件實作---就是繼承View及其子類來自定義一個屬于自己的控件。是以自己去網上GitHub找了一個Demo《SwitchButton 實作了類似 IOS上的 SwitchButton 支援滑動和動畫》。真心感覺别人家的東西就是好。是以在空閑的時間自己也學着些這編博文了(高手勿噴^_^)。之是以寫出來:為己用也便于同樣困惑的朋友一起學習。

聲明:全部内容摘自網際網路

/**
 * 完全自定義視圖控件
 * 
 * 建立自定義視圖元件的一個概要性的總體描述:
 * 1.擴充一個現有的視圖類然後子類化它。 (繼承View類或其子類)
 * 2.重寫父類中的一些方法。這些方法以“on”開始,比如onDraw(), onMeasure(),和 onKeyDown()。
 * 這和活動或清單活動中為生命周期和其他功能鈎子重寫on…事件類似。
 * 提示: 同樣,你也可以重寫父類的一些功能性的方法
 * 3.使用你的新擴充類。這些完成後,你的擴充類就可以替代那個基礎視圖了。
 * 
 * @author xxx Zhang
           
* 參考博文:
 * http://ming-fanglin.iteye.com/blog/1396723
 * http://blog.csdn.net/iefreer/article/details/4598932
 * http://blog.csdn.net/qinjuning/article/details/6936783
 */
           

第一步:建立一個類(mView01) 繼承  View

public class mView01 extends View {
    //編譯器會提示:必須寫一個構造器方法
    }
           

android.view類是其他視圖控件(TextView,Botton...)的父類。他們同樣也繼承了View的一些函數方法。

第二步:實作構造器

編譯器會提示必須建立構造器方法。為了便于以後的使用我們就幹脆把這三個不同的參數的構造器都建立了。每個不同的構造器有不同的使用用途:

<span style="white-space:pre">	</span>/**構造器*/
    public mView01(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);//調用父類的構造器
        //接收構造參數  
        this.context=context; 
        //initView(context);//資源初始化方法
    }
    /**在XML布局檔案中實列化這個構造器*/
    public mView01(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.checkboxStyle);
    }
    /**在代碼中調用這個實列的構造器*/
    public mView01(Context context) {
        this(context, null);
    }
           

注:關于構造器你自己也可以根據自己的需求添加。但是必須要調用父類的構造器對象。之是以說是必須:我想同樣View類在定義的時候也繼承或實作了一些别的類

第三步:重寫父類(View)中的一些方法

父類中有一些OnXX的方法是必須要重寫的,比如:

1>onMeasure(int widthMeasureSpec, int heightMeasureSpec) 

Measure:英文是測量的意思。

這方法主要是提供繪制一個視圖的大小尺寸函數。在這個函數裡你要告訴父類視圖/控件要加載自定義的的尺寸-----setMeasuredDimension(measuredHeight, measuredWidth);

需要注意的:onMeasure()的參數是系統預設提供一個100*100的尺寸。在實際開發中你可以重新設定H*W

2>onDraw(Canvas canvas)

Draw:英文是繪制的意思。

這個方法執行畫筆功能,參數是畫布對象。你可以在畫布上繪制你需要的内容,可以是:圖形、位圖、文字...比如:

@Override  
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);  
        /* 畫布(圖層),有點類似Ps畫圖工具的意思,預設設定系統系統預設的*/
        canvas.drawColor(Color.GRAY);//灰色
        
        /*畫一個Circle(空心圓形)*/
        canvas.drawCircle(40, 40, 30, mPaint);//x,y,半徑,畫筆
    } 
           

根據你自定義的需求用參數 canvas就可以繪制你的需求。你可以檢視文檔看看:Canvas類android.graphics.Canvas 

Canvas使用詳情:http://blog.csdn.net/qinjuning/article/details/6936783

繪制2D圖形:http://www.cnblogs.com/stulife/archive/2010/08/19/1803313.html

如果你自定義的内容比較複雜,有多個圖層需要疊加。那麼你需要設定 Paint:畫筆

//處理兩張圖層的處理模式:
           
//參考:http://trylovecatch.iteye.com/blog/1189452
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
           

-------------------------------------------------------------------------------------

如果你以及根據自定義的需求繪制了一個你需要的圖層内容。那麼在這裡你需要了解關于:畫布的儲存和復原事務 參考百度

/*為了友善一些轉換操作,Canvas提供了儲存和復原屬性的方法(save和restore)*/
           

是以你最好是在繪制具體内容是:

@Override  
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        
        /*為了友善一些轉換操作,Canvas提供了儲存和復原屬性的方法(save和restore)*/
        canvas.save();
        
        /*
        //畫布(圖層),有點類似Ps畫圖工具的意思,預設設定系統系統預設的
        canvas.drawColor(Color.GRAY);//灰色
        //畫一個Circle(空心圓形)
        canvas.drawCircle(40, 40, 30, mPaint);//x,y,半徑,畫筆
        */
        
        //復原:回到上一個save調用之前的狀态,如果restore調用的次數大于save方法,會出錯。
        canvas.restore();
    }  
           

重構了上面父類onXX()函數基本上你可以調用這個自定義的視圖控件了。如果你希望對這個控件添加一些監聽事件那麼你可以繼續重些父類的一些onXX()函數:

onKeyDown(int, KeyEvent) :當一個新的按鍵事件發生時,調用此方法 

onKeyUp(int, KeyEvent) :當一個按鍵釋放事件發生時,調用此方法 

onMotionEvent(MotionEvent): 當一個動作事件(如觸摸)發生時,調用此方法

onTouchEvent(MotionEvent event):當一個觸屏事件發生時,調用此方法。比如:按下/松開螢幕和滑動螢幕

@Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "//onKeyDown");
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //螢幕獲得焦點(按下)
            mPaint.setColor(Color.GREEN);//綠色
            break;
        case MotionEvent.ACTION_MOVE:
            //螢幕焦點移動(滑動)
            break;
        case MotionEvent.ACTION_UP:
            //螢幕失去焦點(松開)
            mPaint.setColor(Color.RED);
            break;
        }
        
        invalidate();//請求重繪View樹,即onDraw()過程
        return super.onTouchEvent(event);
    }
           

至此,對完全自定義視圖控件有一個簡單的了解。

---------------------------------------

擷取你在糾結怎麼去實作這個自定義的視圖控件類:

public class ViewA01 extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater inflate = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        LinearLayout layout = (LinearLayout)inflate.inflate(R.layout.activity_view, null);//加載xml
        setContentView(layout);//ACTIVITY加載視圖層次結構
        

        /*自定義視圖控件實列化,方式1:用标簽實作用代碼建立視圖控件*/
        mView01 mTextView =  new mView01(this);
        layout.addView(mTextView);//在布局檔案中添加這個視圖控件
    }
}
           
<!-- 自定義視圖控件實列化,方式2:用标簽實作 -->

    <com.my.view.util.mView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"  />
           

百度下載下傳