码迷,mamicode.com
首页 > 其他好文 > 详细

开关案例

时间:2019-01-26 12:39:56      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:state   attr   nullable   prot   Dimension   content   bre   oid   移动   

开关案例

  • 代码实现步骤 
  • [1]先在构造方法里面获取2张背景图片的宽和高
    public ToggleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        tbg = BitmapFactory.decodeResource(getResources(), R.drawable.toogle_background);
        sbg = BitmapFactory.decodeResource(getResources(), R.drawable.toogle_slidebg);
        slideMax = tbg.getWidth() - sbg.getWidth();
        String namespace = "http://schemas.android.com/apk/res-auto";
        boolean isOpen = attrs.getAttributeBooleanValue(namespace, "state", false);
        setOpenState(isOpen);
        if (state) {
            toLeft = slideMax;
        } else {
            toLeft = 0;
        }
    }

 

[2]重写onMeasure方法对当前view进行测量 当前view的宽高和toogleBg 一样

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(tbg.getWidth(), tbg.getHeight());
    }

 

[3]重写onDraw方法往当前的view上画内容 其实就是画图片

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(tbg, 0, 0, null);
        canvas.drawBitmap(sbg, toLeft, 0, null);
        if (isUp) {
            isUp = false;
            boolean isOpenTemp = toLeft > 0;
            if (isOpenTemp != state && listener != null) {
                listener.setState(isOpenTemp);
                state = isOpenTemp;
            }
        }
    }

 

[4]给开关定义监听事件 具体什么时候出发回调事件:

    public void setOnStateListener(OnStateListener listener) {
        this.listener = listener;
    }

    public interface OnStateListener {
        void setState(boolean isOpen);
    }

 

[5]处理滑动块滑动的逻辑 重写onTouchEvent方法 处理手指按下和移动的逻辑

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //按下的距离
                downX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                endX = event.getX();
                moveX = endX - downX;
                toLeft = toLeft + moveX;
                if (toLeft <= 0) {
                    toLeft = 0;
                }
                if (toLeft >= slideMax) {
                    toLeft = slideMax;
                }
                downX = endX;
                break;
            case MotionEvent.ACTION_UP:
                isUp = true;
                float tHalf = tbg.getWidth() / 2;
                float sHalf = toLeft + sbg.getWidth() / 2;
                if (tHalf > sHalf) {
                    toLeft = 0;
                } else {
                    toLeft = slideMax;
                }
                break;
        }
        invalidate();
        return true;
    }

 

[6]处理手指抬起的业务逻辑

            case MotionEvent.ACTION_UP:
                isUp = true;
                float tHalf = tbg.getWidth() / 2;
                float sHalf = toLeft + sbg.getWidth() / 2;
                if (tHalf > sHalf) {
                    toLeft = 0;
                } else {
                    toLeft = slideMax;
                }
                break;

 

[7]实现开关的功能.

        if (isUp) {
            isUp = false;
            boolean isOpenTemp = toLeft > 0;
            if (isOpenTemp != state && listener != null) {
                listener.setState(isOpenTemp);
                state = isOpenTemp;
            }
        }

 

[8]自定义开关的属性

8.1)在res下定义一个attrs文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ToggleView">
        <attr name="state" format="boolean" />
    </declare-styleable>
</resources>

 

8.2)自己声明一个命名空间.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:toogle="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ngyb.choose.ToggleView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        toogle:state="true" />
</LinearLayout>

 

8.3)在构造方法里面获取我们声明的属性值

        String namespace = "http://schemas.android.com/apk/res-auto";
        boolean isOpen = attrs.getAttributeBooleanValue(namespace, "state", false);

 

 

 8.4)更新开关的状态

    public void setOpenState(boolean openState) {
        isUp = true;
        this.state = openState;
    }

https://github.com/nangongyibin7219/Android_OnOff

开关案例

标签:state   attr   nullable   prot   Dimension   content   bre   oid   移动   

原文地址:https://www.cnblogs.com/nangongyibin/p/10322973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!