Android自訂滑動開關按鈕

來源:互聯網
上載者:User

標籤:android   style   blog   http   color   使用   io   for   檔案   

一、

二、主要技術點

  1.自訂View

  2.自訂屬性

三、自訂控制項的步驟

  1.自訂類繼承自View或View的子類;

  2.重寫構造方法

    (1)MyView(Context);  // 在代碼中new 對象時調用此方法 

    (2)MyView(Context,AttributeSet);  // 在XML布局檔案中聲明此View,建立對象時,由系統自動調用

    (3)MyView(Context,AttributeSet,int);  // 與方法2用法一樣,只是多了一個參數:預設樣式

  3.重寫相關方法,實現我們的需求,一般要重寫的方法:

    (1)onMeasure(int,int);  // 系統測量控制項大小時調用該方法 

    (2)onLayout(boolean,int,int,int,int);  // 系統為該view 指定位置時調用此方法,子view的位置,自身只有建議權,決定權在父view的手中。一般不需要重寫。

    (3)onDraw(Canvas);  // 為本view繪製內容時,調用該方法。

四、為新控制項添加自訂屬性的步驟:

  1.在attrs.xml檔案中聲明屬性,有屬性名稱(name)和格式(format)。如 

<?xml version="1.0" encoding="utf-8"?><resources>    <!-- 聲明屬性集的名稱 -->    <declare-styleable name="MyToggleBtn">        <!-- 聲名一個屬性  name是my_background   類型為 參考型別      引用資源ID -->        <attr name="my_background" format="reference" />        <!-- 聲名一個屬性  name是my_slide_btn   類型為 參考型別      引用資源ID -->        <attr name="my_slide_btn" format="reference" />        <!-- 聲名一個屬性  name是curr_state   類型為 boolean 類型 -->        <attr name="curr_state" format="boolean" />    </declare-styleable></resources>

 

  2.在布局檔案中使用新屬性,使用之前必須先聲明命名空間,如xmlns:gnnuit="http://schemas.android.com/apk/res/com.gnnuit.togglebutton",其中“http://schemas.android.com/apk/res/”為Android固定的格式,“com.gnnuit.togglebutton”為應用程式的包名,與AndroidManifest.xml聲明的包名一樣。

<com.gnnuit.togglebutton.MyToggleButton        android:layout_width="wrap_content"        android:layout_height="wrap_content"        gnnuit:curr_state="true"        gnnuit:my_background="@drawable/switch_background"        gnnuit:my_slide_btn="@drawable/slide_button" />

 

  3.在自訂View的構造方法中,通過解析AttributeSet對象,獲得所需要的屬性值。

四。核心代碼

package com.gnnuit.togglebutton;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;public class MyToggleButton extends View implements android.view.View.OnClickListener {    private Bitmap backgroundBitmap;// 背景圖片    private Bitmap slideButtonBitmap;// 滑動按鈕圖片    private Paint paint;    private boolean currentState = false;// 目前狀態    private float left_slide;// 滑動按鈕的左邊界位置    private float startX, lastX;// 記錄滑動按鈕滑動時的開始和結束位置    private boolean isSlide = false;// 記錄是否移動滑動按鈕    private float dist;    /**     * 在布局檔案中聲明此View,建立時由系統自動調用該構造方法     *      * @param context     * @param attrs     */    public MyToggleButton(Context context, AttributeSet attrs) {        super(context, attrs);        // 擷取自訂屬性        currentState = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "curr_state", false);                int backgroundResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "my_background", -1);        if (backgroundResourceId == -1) {            throw new RuntimeException("請設定背景圖片");        }        backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundResourceId);                int slideBtnResourceId = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/com.gnnuit.togglebutton", "my_slide_btn", -1);        if (slideBtnResourceId == -1) {            throw new RuntimeException("請設定背景圖片");        }        slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideBtnResourceId);        if (currentState) {            left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth();        }        initView();// 初始化    }    /**     * 初始化     */    private void initView() {        // 初始化圖片        // backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);        // slideButtonBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);        // 初始化畫筆        paint = new Paint();        paint.setAntiAlias(true);// 設定消除鋸齒        // 設定點擊事件        setOnClickListener(this);    }    @Override    /**     * 測量尺寸的回調方法     */    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(backgroundBitmap.getWidth(), backgroundBitmap.getHeight());// 設定控制項的寬和高,單位是像素    }    @Override    /**     * 繪製當前View的內容     */    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(backgroundBitmap, 0, 0, paint);        canvas.drawBitmap(slideButtonBitmap, left_slide, 0, paint);    }    @Override    public void onClick(View v) {        if (!isSlide) {            currentState = !currentState;            flushState();// 重新整理介面        }    }    /**     * 重新整理目前狀態     */    private void flushState() {        if (currentState) {            left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth();        } else {            left_slide = 0;        }        invalidate();    }    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            isSlide = false;            startX = lastX = event.getX();            break;        case MotionEvent.ACTION_MOVE:            lastX = event.getX();            dist = lastX - startX;            if (Math.abs(dist) > 5) {                isSlide = true;                left_slide += dist;                flushShow();                startX = event.getX();            }            break;        case MotionEvent.ACTION_UP:            if (isSlide) {                if (left_slide > (backgroundBitmap.getWidth() - slideButtonBitmap.getWidth()) / 2) {                    left_slide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth();                    currentState = true;                } else {                    left_slide = 0;                    currentState = false;                }                flushShow();            }            break;        }        return true;    }    /**     * 重新整理當前View     */    private void flushShow() {        int maxLeftSlide = backgroundBitmap.getWidth() - slideButtonBitmap.getWidth();        // left_slide的範圍為0=<left_slide<=maxLeftSlide        if (left_slide > maxLeftSlide) {            left_slide = maxLeftSlide;            currentState = true;        } else if (left_slide < 0) {            left_slide = 0;            currentState = false;        }        invalidate();    }}

 

Android自訂滑動開關按鈕

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.