Android 自定义滑动开关ToggleButton

来源:互联网 发布:dash windows版 编辑:程序博客网 时间:2024/05/18 12:31

不得不说,在做自定义滑动开关过程中,学习到了很多东西。跟大家分享分享!

1、自定义控件步骤

测量:onMeasure  设置自己显示在屏幕上的宽高

布局:onLayout   设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到,需要设置子view的位置)

绘制:onDraw     控制显示在屏幕上的样子(自定义viewgroup时不需要这个,绘制单个view的样子)


所以我们在自定义一个控件之前,要明白自定义的是一个view,还是一个viewgroup,如:本篇中自定义的ToggleButton

只是一个简单view,本人是这样理解的:view相当于button,textview之类的小控件,而viewgroup相当于RelativeLayout

之类的布局。大家可以提出个人的见解让他人可以更好的理解view与viewgroup的差别!

View和ViewGroup的区别
1.他们都需要进行测量操作
2.ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
  View没有子view,所以不需要onLayout方法,但是必须实现onDraw

3、废话有点多,先贴出ToggleButton效果图:


4、源码:xml中很简单:

<com.chenshi.mytogglebutton.ToggleButton    android:id="@+id/toggleBtn"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_centerInParent="true" />
最后一句是使view居于父控件居中!
5、MainActivity中:
toggleButton.setSildeBackgroundResource(R.drawable.slide_bg);toggleButton.setSwitchOnBackgroundResource(R.drawable.switch_on);toggleButton.setSwitchOffBackgroundResource(R.drawable.switch_off);//设置开关状态,默认为OPENtoggleButton.setToggleState(ToggleButton.ToggleState.CLOSE);toggleButton.setOnStateChangeListeren(new ToggleButton.OnToggleStateChangeListeren() {    @Override    public void onToggleStateChangeListeren(ToggleButton.ToggleState toggleState) {        Toast.makeText(MainActivity.this, toggleState == ToggleButton.ToggleState.CLOSE ? "关" : "开"
Toast.LENGTH_SHORT).show();    }});
为什么要先贴出MainActivity中源码呢,因为我们通过set知道我们自定中需要哪里方法,如:
toggleButton.setSildeBackgroundResource(R.drawable.slide_bg);
对应于自定类ToggleButton中就要有
/** * 设置滑块的背景图片 * * @param slide_bg */public void setSildeBackgroundResource(int slide_bg) {    slideBg = BitmapFactory.decodeResource(getResources(), slide_bg);}
此方法!这是一种思路!并不是盲目的自定义方法!
6、自定类源码:注释的挺详细的,大家耐心点看!

public class ToggleButton extends View {    private Bitmap slideBg;//滑块的背景图    private Bitmap switchOn;//滑动开关开的背景图    private Bitmap switchOff;//滑动开关关的背景图    private ToggleState state = ToggleState.OPEN;//滑动开关的状态,默认为OPEN;    //手指触摸在view上的坐标,这个是相对于view的坐标    private int currentX;    //是否在滑动    private boolean isSliding = true;    /**     * 如果自定的控件需要在Java中实例化,重写该构造方法     *     * @param context     */    public ToggleButton(Context context) {        super(context);    }    /**     * 如果自定义控件需要在xml文件使用,重写该构造方法     *     * @param context     * @param attrs     */    public ToggleButton(Context context, AttributeSet attrs) {        super(context, attrs);    }    /**     * 设置滑块的背景图片     *     * @param slide_bg     */    public void setSildeBackgroundResource(int slide_bg) {        slideBg = BitmapFactory.decodeResource(getResources(), slide_bg);    }    /**     * 设置滑动开关开的背景图     *     * @param switch_on     */    public void setSwitchOnBackgroundResource(int switch_on) {        switchOn = BitmapFactory.decodeResource(getResources(), switch_on);    }    /**     * 设置滑动开关关的背景图     *     * @param switch_off     */    public void setSwitchOffBackgroundResource(int switch_off) {        switchOff = BitmapFactory.decodeResource(getResources(), switch_off);    }    public void setToggleState(ToggleState toggleState) {        this.state = toggleState;    }    public enum ToggleState {        OPEN, CLOSE    }    /**     * 绘制view的宽与高,以滑动开关的宽高绘制     *     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(switchOn.getWidth(), switchOn.getHeight());    }    /**     * 画view     *     * @param canvas     */    @Override    protected void onDraw(Canvas canvas) {        int left = currentX - slideBg.getWidth() / 2;        // (left > (switchOn.getWidth() / 2)) ? ((state = ToggleState.OPEN)) : ((state = ToggleState.CLOSE));        //当触摸点超过整view的一半时,就切换开关背景;        super.onDraw(canvas);        /**         * (@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint)         * left:图片左边的x坐标         * top:图片顶部的y坐标         */        if (isSliding) {            if (state == ToggleState.OPEN) {                //绘制开关图片                canvas.drawBitmap(switchOn, 0, 0, null);                //绘制滑块图片                if (left > (switchOn.getWidth() - slideBg.getWidth()))                    left = switchOn.getWidth() - slideBg.getWidth();                canvas.drawBitmap(slideBg, left, 0, null);            } else {                //绘制开关图片                canvas.drawBitmap(switchOff, 0, 0, null);                //绘制滑块图片                if (left < 0) left = 0;                canvas.drawBitmap(slideBg, left, 0, null);            }        } else {            if (state == ToggleState.OPEN) {                //绘制开关图片                canvas.drawBitmap(switchOn, 0, 0, null);                canvas.drawBitmap(slideBg, switchOn.getWidth() - slideBg.getWidth(), 0, null);            } else {                //绘制开关图片                canvas.drawBitmap(switchOff, 0, 0, null);                canvas.drawBitmap(slideBg, 0, 0, null);            }        }    }    /**     * 定义滑动     *     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        currentX = (int) event.getX();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                isSliding = true;                break;            case MotionEvent.ACTION_MOVE:                break;            case MotionEvent.ACTION_UP:                isSliding = false;                break;        }       //在滑动的过程中状态改变也进行监听,触摸结束后也监听状态改变,未改变就无需其他动作         if (currentX > switchOn.getWidth() / 2) {             if (state != ToggleState.OPEN) {                 state = ToggleState.OPEN;                 if (stateChangeListeren != null) {                     stateChangeListeren.onToggleStateChangeListeren(state);                 }             }        } else {             //CLOSE             if (state != ToggleState.CLOSE) {                 state = ToggleState.CLOSE;                 if (stateChangeListeren != null) {                     stateChangeListeren.onToggleStateChangeListeren(state);                 }             }        }        //调用此方法,间接调用OnD        invalidate();        return true;    }    /**     * 开放状态改变接口     */    private OnToggleStateChangeListeren stateChangeListeren;    public void setOnStateChangeListeren(OnToggleStateChangeListeren stateChangeListeren) {        this.stateChangeListeren = stateChangeListeren;    }    public interface OnToggleStateChangeListeren {        void onToggleStateChangeListeren(ToggleState state);    }}


免费下载链接:Android自定义滑动开关demo下载链接
1 0
原创粉丝点击