zoukankan      html  css  js  c++  java
  • 自定义控件1_切换按钮

    1.自定义属性values/attrs.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>

    2.view的java文件:

    package zdl.switchbutton.view;
    
    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 ToggleView extends View {
    
        private Bitmap switchBackgroupBitmap; // 背景图片
        private Bitmap slideButtonBitmap; // 滑块图片
        private Paint paint; // 画笔
        private boolean mSwitchState = false; // 开关状态, 默认false
        private float currentX;
    
        /**
         * 用于代码创建控件
         *
         * @param context
         */
        public ToggleView(Context context) {
            super(context);
            init();
        }
    
        /**
         * 用于在xml里使用, 可指定自定义属性
         *
         * @param context
         * @param attrs
         */
        public ToggleView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
            // 获取配置的自定义属性
            String namespace = "http://toly.android.com/apk/res/zdl.switchbutton.view.ToggleView";
            int switchBackgroundResource = attrs.getAttributeResourceValue(namespace, "switch_background", -1);
            int slideButtonResource = attrs.getAttributeResourceValue(namespace, "slide_button", -1);
    
            mSwitchState = attrs.getAttributeBooleanValue(namespace, "switch_state", false);
            setSwitchBackgroundResource(switchBackgroundResource);
            setSlideButtonResource(slideButtonResource);
        }
    
        /**
         * 用于在xml里使用, 可指定自定义属性, 如果指定了样式, 则走此构造函数
         *F:AndroidSwitchButtonappsrcmainjavazdlswitchbuttonviewToggleView.java
         * zdl.switchbutton.view.ToggleView
         * @param context
         * @param attrs
         * @param defStyle
         */
        public ToggleView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init() {
            paint = new Paint();
        }
    
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(switchBackgroupBitmap.getWidth(), switchBackgroupBitmap.getHeight());
        }
    
        // Canvas 画布, 画板. 在上边绘制的内容都会显示到界面上.
        @Override
        protected void onDraw(Canvas canvas) {
            // 1. 绘制背景
            canvas.drawBitmap(switchBackgroupBitmap, 0, 0, paint);
    
            // 2. 绘制滑块
    
            if (isTouchMode) {
                // 根据当前用户触摸到的位置画滑块
    
                // 让滑块向左移动自身一半大小的位置
                float newLeft = currentX - slideButtonBitmap.getWidth() / 2.0f;
    
                int maxLeft = switchBackgroupBitmap.getWidth() - slideButtonBitmap.getWidth();
    
                // 限定滑块范围
                if (newLeft < 0) {
                    newLeft = 0; // 左边范围
                } else if (newLeft > maxLeft) {
                    newLeft = maxLeft; // 右边范围
                }
    
                canvas.drawBitmap(slideButtonBitmap, newLeft, 0, paint);
            } else {
                // 根据开关状态boolean, 直接设置图片位置
                if (mSwitchState) {// 开
                    int newLeft = switchBackgroupBitmap.getWidth() - slideButtonBitmap.getWidth();
                    canvas.drawBitmap(slideButtonBitmap, newLeft, 0, paint);
                } else {// 关
                    canvas.drawBitmap(slideButtonBitmap, 0, 0, paint);
                }
            }
    
        }
    
        boolean isTouchMode = false;
        private OnSwitchListener onSwitchListener;
    
        // 重写触摸事件, 响应用户的触摸.
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    isTouchMode = true;
                    System.out.println("event: ACTION_DOWN: " + event.getX());
                    currentX = event.getX();
                    break;
                case MotionEvent.ACTION_MOVE:
                    System.out.println("event: ACTION_MOVE: " + event.getX());
                    currentX = event.getX();
                    break;
                case MotionEvent.ACTION_UP:
                    isTouchMode = false;
                    System.out.println("event: ACTION_UP: " + event.getX());
                    currentX = event.getX();
    
                    float center = switchBackgroupBitmap.getWidth() / 2.0f;
    
                    // 根据当前按下的位置, 和控件中心的位置进行比较.
                    boolean state = currentX > center;
    
                    // 如果开关状态变化了, 通知界面. 里边开关状态更新了.
                    if (state != mSwitchState && onSwitchListener != null) {
                        // 把最新的boolean, 状态传出去了
                        onSwitchListener.onStateUpdate(state);
                    }
    
                    mSwitchState = state;
                    break;
    
                default:
                    break;
            }
    
            // 重绘界面
            invalidate(); // 会引发onDraw()被调用, 里边的变量会重新生效.界面会更新
    
            return true; // 消费了用户的触摸事件, 才可以收到其他的事件.
        }
    
        /**
         * 设置背景图
         *
         * @param switchBackground
         */
        public void setSwitchBackgroundResource(int switchBackground) {
            switchBackgroupBitmap = BitmapFactory.decodeResource(getResources(), switchBackground);
        }
    
        /**
         * 设置滑块图片资源
         *
         * @param slideButton
         */
        public void setSlideButtonResource(int slideButton) {
            slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideButton);
        }
    
        /**
         * 设置开关状态
         */
        public void setSwitchState(boolean mSwitchState) {
            this.mSwitchState = mSwitchState;
        }
    
        public interface OnSwitchListener {
            // 状态回调, 把当前状态传出去
            void onStateUpdate(boolean state);
        }
    
        public void setOnSwitchListener(OnSwitchListener onSwitchListener) {
            this.onSwitchListener = onSwitchListener;
        }
    
    }
    
    


    3.layout中使用

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:toly="http://toly.android.com/apk/res/zdl.switchbutton.view.ToggleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    <zdl.switchbutton.view.ToggleView
        android:id="@+id/toggleView"
        toly:switch_background="@drawable/switch_background"
        toly:slide_button="@drawable/slide_button"
        toly:switch_state="false"
        android:layout_width="20dp"
        android:layout_height="wrap_content"/>
    </LinearLayout>

    4.MainActivity.java中:

    package zdl.switchbutton;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Toast;
    
    import zdl.switchbutton.view.ToggleView;
    
    public class MainActivity extends AppCompatActivity {
    
        private Toolbar mTb;
        private ToggleView toggleView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            toggleView = (ToggleView) findViewById(R.id.toggleView);
            // 设置开关更新监听
            toggleView.setOnSwitchListener(new ToggleView.OnSwitchListener(){
    
                @Override
                public void onStateUpdate(boolean state) {
                    Toast.makeText(getApplicationContext(), "state: " + state, 0).show();
                }
    
            });
    
    
    }
    


  • 相关阅读:
    数组用法
    前端,面试常见问题总结
    webAPP如何实现移动端拍照上传(Vue组件示例)?
    某某某家前端面试
    腾讯地图前端面试经验
    京东2017校招前端主观题汇总
    计算机领域相关期刊会议及排名
    深度学习入门一周,我都做了些什么
    windows7 64位安装tensorflow 1.4.0 CPU版本
    ThreeJS的特效合成器和后期处理通道
  • 原文地址:https://www.cnblogs.com/toly-top/p/9782039.html
Copyright © 2011-2022 走看看