自定义View之Switch

思路:
定义类继承view,重写几个用到的方法
1.三个构造方法
2. onMeasure测量
onLayout布局
onDrow绘图
3.onTouchEvent触摸事件方法
invalidate();可以高频度的调用onDraw()
定义一个外部接口,将开关状态传出去
添加设置接口对象的方法,外部进行调用

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;

/**
 * Created by maker_huige on 2016/12/26.
 */

public class ToggleView extends View {
    boolean isTouchMode = false;
    Bitmap bitmap_switch_background;
    Bitmap bitmap_slide_button;
    boolean mSwitchState = true;
    float currentX;
    private OnSwitchStateUpdateListener onSwitchStateUpdateListener;

    public ToggleView(Context context) {
        super(context);
        init(null);
    }

    public ToggleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public ToggleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        String namespace = "http://schemas.android.com/apk/res-auto";
        int switch_background = attrs.getAttributeResourceValue(namespace, "switch_background", -1);
        int slide_button = attrs.getAttributeResourceValue(namespace, "slide_button", -1);
        mSwitchState =attrs.getAttributeBooleanValue(namespace,"switch_state",false);
        setSwitchBackgroundResource(switch_background);
        setSlideButtonResource(slide_button);
    }
    /**
     * 自定义组件的三个方法,执行onResum后执行
     * onMeasure测量
     * onLayout布局
     * onDrow绘图
     * view需要两个
     * viewGrowp需要三个
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(bitmap_switch_background.getWidth(),bitmap_switch_background.getHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        canvas.drawBitmap(bitmap_switch_background,0,0,paint);

        if(isTouchMode){
            //当用户触摸到位置画滑块
            float newLeft = currentX;
            newLeft = currentX -bitmap_slide_button.getWidth() / 2.0f;
            float maxLeft = bitmap_switch_background.getWidth()-bitmap_slide_button.getWidth();
            if(newLeft < 0){
                newLeft = 0;
            }else {
                newLeft = maxLeft;
            }
            canvas.drawBitmap(bitmap_slide_button,newLeft,0,paint);
        }else {
            if(mSwitchState){
                canvas.drawBitmap(bitmap_slide_button,
                        bitmap_switch_background.getWidth()-bitmap_slide_button.getWidth(),
                        0,paint);
            }else{
                canvas.drawBitmap(bitmap_slide_button,0,0,paint);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
                currentX = event.getX();
                break;
            case MotionEvent.ACTION_DOWN:
                isTouchMode = true;
                currentX = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                currentX = event.getX();
                isTouchMode = false;
                boolean state = currentX > bitmap_switch_background.getWidth() / 2.0f;
                if(state != mSwitchState && onSwitchStateUpdateListener !=null){
                    onSwitchStateUpdateListener.onStateUpdate(state);
                }
                mSwitchState = state;
                break;
            }
        invalidate();
        return true;
    }

    //    声明接口对象
    public interface OnSwitchStateUpdateListener{

        void onStateUpdate(boolean state);
    }
//    添加设置接口对象的方法,外部进行调用
    public void setOnSwitchStateUpdateListener(OnSwitchStateUpdateListener onSwitchStateUpdateListener) {
        this.onSwitchStateUpdateListener = onSwitchStateUpdateListener;
    }

    public void setSwitchBackgroundResource(int switch_background) {
        bitmap_switch_background = BitmapFactory.decodeResource(getResources(), switch_background);
    }

    public void setSlideButtonResource(int slide_button) {
        bitmap_slide_button = BitmapFactory.decodeResource(getResources(), slide_button);
    }
}

在Activity中设置事件监听器,通过匿名内部类的方式并将state状态打印出来

public class ToggleActivity extends Activity {
    ToggleView toggleView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toggle);
        initUI();
        toggleView.setOnSwitchStateUpdateListener(new ToggleView.OnSwitchStateUpdateListener() {
            @Override
            public void onStateUpdate(boolean state) {
                Toast.makeText(getApplicationContext(),"state:" + state,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initUI() {
        toggleView = (ToggleView) findViewById(R.id.toggleview);
        //用自定义属替代了
        /*toggleView.setSwitchBackgroundResource(R.mipmap.switch_background);
        toggleView.setSlideButtonResource(R.mipmap.slide_button);*/

    }

}

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:itheima="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <com.maker_huige.ui.ToggleView
        itheima:switch_background="@mipmap/switch_background"
        itheima:slide_button="@mipmap/slide_button"
        itheima:switch_state="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:id="@+id/toggleview"
        />
</RelativeLayout>

自定义属性的xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ToggleView">
        <attr name="switch_background" format="reference"/>
        <attr name="slide_button" format="reference"/>
        <attr name="switch_state" format="boolean"/>
    </declare-styleable>
</resources>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值