zoukankan      html  css  js  c++  java
  • 自定义控件ToggleButton滑动开关

    ---恢复内容开始---

    滑动开关--------
    自定义控件步骤:
    测量:onMeasure 设置自己显示在屏幕上的宽高
    布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
    绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)

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

    然后要想你设计这个控件能够有哪些功能?

    1.设置滑动开关的背景图片,

    2.设置滑动开关的滑块图片,

    3.设置滑动开关的状态,

    然后有了这些功能需求就可以进行代码的编写,

    这次我们要自定义一个view,所以要继承view,实现它的构造方法,然后要实现设置图片的两个方法,和设置开关状态的方法,这里开关状态用了枚举类型。

    因为绘制的时候只能绘制bitmap类型,所以要进行转化

        /**
         * 选择框的背景
         * 
         * @param icLauncher
         */
        public void setSwitchBackgroundResource(int icLauncher) {
            switchBg = BitmapFactory.decodeResource(getResources(), icLauncher);
    
        }
    
        /**
         * 滑动按钮背景
         * 
         * @param icLauncher
         */
        public void setSlideBackgroundResouce(int icLauncher) {
            slideBg = BitmapFactory.decodeResource(getResources(), icLauncher);
        }
    
        /**
         * 设置开关的初始状态
         * 
         * @param state
         */
        public void setSlideStare(ToggleState state) {
            togglestate = state;
        }

    然后要重写测量方法,就是背景图片的宽高

    /**
         * 设置当前控件显示在屏幕上的宽高
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
        }

    测量之后要进行绘制

    首先绘制分为两种,

    一种是滑动中绘制,

    还有一种是不滑动根据设置的状态进行绘制

    滑动中绘制:这个主要就是通过Touch事件来改变滑块距离左侧的值来进行绘制

    @Override
        public boolean onTouchEvent(MotionEvent event) {
            //改变的值
         currentX
    = (int) event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; // 松开的时候看当前X的值在哪里 case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; } // 由它来调用ondraw方法 invalidate(); return true; }

    绘制方法

        /*
                 * 设置在正中间
                 */
                int left = currentX - slideBg.getWidth() / 2;
                if (left < 0) {
                    left = 0;
                } else if (left >= (switchBg.getWidth() - slideBg.getWidth())) {
                    left = switchBg.getWidth() - slideBg.getWidth();
                }

    另外一种就是不滑动根据状态绘制。首先要规定出状态,状态布尔值默认是false,然后当down变成true,当up时候重新变成false

    // 绘制滑块
                // 判断滑块的状态
                // 打开
                if (togglestate == ToggleState.Open) {
                    canvas.drawBitmap(slideBg,
                            switchBg.getWidth() - slideBg.getWidth(), 0, null);
                    // 关闭
                } else {
                    canvas.drawBitmap(slideBg, 0, 0, null);
                }

    完整代码

    package com.example.tbtn.view;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class ToggleButton extends View {
        // 设置的状态
        private ToggleState togglestate = ToggleState.Open;
        // 选择背景
        private Bitmap switchBg;
        // 滑动按钮背景
        private Bitmap slideBg;
        // 点击的X值
        private int currentX = 0;
        // 是否滑动
        private boolean isSliding = false;
    
        // 枚举类型
        public enum ToggleState {
            Open, Close
        }
    
        /**
         * 布局文件引用调用
         * 
         * @param context
         * @param attrs
         */
        public ToggleButton(Context context, AttributeSet attrs) {
            super(context, attrs);
    
        }
    
        /**
         * 代码使用调用
         * 
         * @param context
         */
        public ToggleButton(Context context) {
            super(context);
    
        }
    
        /**
         * 选择框的背景
         * 
         * @param icLauncher
         */
        public void setSwitchBackgroundResource(int icLauncher) {
            switchBg = BitmapFactory.decodeResource(getResources(), icLauncher);
    
        }
    
        /**
         * 滑动按钮背景
         * 
         * @param icLauncher
         */
        public void setSlideBackgroundResouce(int icLauncher) {
            slideBg = BitmapFactory.decodeResource(getResources(), icLauncher);
        }
    
        /**
         * 设置开关的初始状态
         * 
         * @param state
         */
        public void setSlideStare(ToggleState state) {
            togglestate = state;
        }
    
        /**
         * 设置当前控件显示在屏幕上的宽高
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // TODO Auto-generated method stub
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
        }
    
        /**
         * 绘制
         */
        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
            // left 距图片左侧 top 距图片上部
            canvas.drawBitmap(switchBg, 0, 0, null);
    
            if (isSliding) {
                /*
                 * 设置按在正中间
                 */
                int left = currentX - slideBg.getWidth() / 2;
                if (left < 0) {
                    left = 0;
                } else if (left >= (switchBg.getWidth() - slideBg.getWidth())) {
                    left = switchBg.getWidth() - slideBg.getWidth();
                }
                canvas.drawBitmap(slideBg, left, 0, null);
            } else {
                // 绘制滑块
                // 判断滑块的状态
                // 打开
                if (togglestate == ToggleState.Open) {
                    canvas.drawBitmap(slideBg,
                            switchBg.getWidth() - slideBg.getWidth(), 0, null);
                    // 关闭
                } else {
                    canvas.drawBitmap(slideBg, 0, 0, null);
                }
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            currentX = (int) event.getX();
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isSliding = true;
                break;
            // 松开的时候看当前X的值在哪里
            case MotionEvent.ACTION_UP:
                isSliding = false;
                // 图片中心点
                int centerX = switchBg.getWidth() / 2;
                // 打开
                if (currentX > centerX) {
                    // 判断当前状态是否真的改变(就是滑动一半回去了)
                    if (togglestate != ToggleState.Open) {
                        togglestate = ToggleState.Open;
                        // 设置回调借口
                        if (lisern != null) {
                            lisern.onToggleChange(togglestate);
                        }
                    }
                    // 关闭
                } else {
                    if (togglestate != ToggleState.Close) {
                        togglestate = ToggleState.Close;
                        // 设置回调借口
                        if (lisern != null) {
                            lisern.onToggleChange(togglestate);
                        }
                    }
                }
    
                break;
            case MotionEvent.ACTION_MOVE:
    
                break;
            }
            // 由它来调用ondraw方法
            invalidate();
            return true;
        }
    
        private OnToggleChangeLisern lisern;
    
        public void setOnToggleChangeLisern(OnToggleChangeLisern lisern) {
            this.lisern = lisern;
        }
    
        // 回调接口
        public interface OnToggleChangeLisern {
            void onToggleChange(ToggleState state);
        }
    
    }

     Activity中使用

    package com.example.tbtn;
    
    import com.example.tbtn.view.ToggleButton;
    import com.example.tbtn.view.ToggleButton.OnToggleChangeLisern;
    import com.example.tbtn.view.ToggleButton.ToggleState;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Toast;
    
    
    public class MainActivity extends Activity {
        private ToggleButton tBtn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tBtn = (ToggleButton) findViewById(R.id.tbtn);
            tBtn.setSwitchBackgroundResource(R.drawable.togglebtn);
            tBtn.setSlideBackgroundResouce(R.drawable.ic_launcher);
            tBtn.setSlideStare(ToggleState.Open);
            tBtn.setOnToggleChangeLisern(new OnToggleChangeLisern() {
                
                @Override
                public void onToggleChange(ToggleState state) {
                    if(state==ToggleState.Open){
                        Toast.makeText(MainActivity.this,"打开", 0).show();
                    }else{
                        Toast.makeText(MainActivity.this,"关闭", 0).show();
                    }
                    
                }
            });
        }
    
    }
  • 相关阅读:
    IaaS、PaaS、SaaS
    hyper-V 配置
    解决linux下创建用户时出现Creating mailbox file: File exists
    iframe层级关系调用
    js,jq新增元素 ,on绑定事件无效
    js中!和!!的区别与用法
    form表单禁止button 提交
    Thinkphp5终端创建控制器和模型
    TP5的目录常量和路径
    sublime安装package controlller
  • 原文地址:https://www.cnblogs.com/84126858jmz/p/5175625.html
Copyright © 2011-2022 走看看