• 自定义控件


    自定义控件一般的几个步骤:
    1.初始化相关背景图片,布局文件,自定义属性
    2.设置控件宽高OnMeasure()
    3.布局或者排版OnLayout()
    4.绘制控件OnDraw()
    5.处理触摸事件OnTouchEvent()
      1 public class SwitchView extends View implements View.OnTouchListener {
      2 
      3     //开关状态图片
      4     private Bitmap mSwitch_on, mSwitch_off, mSwitch_circle;
      5 
      6     //开关状态 默认关闭
      7     private boolean mCurrentState = false;
      8 
      9     //开关切换回调接口
     10     private OnSwitchChangedListener mOnSwitchChangedListener;
     11 
     12     //X轴按下坐标
     13     private int downX;
     14     //X轴移动时触点坐标
     15     private int moveX;
     16     //X轴偏移量
     17     private int left = 0;
     18     //最大可移动距离
     19     private int max;
     20 
     21     public SwitchView(Context context) {
     22         super(context);
     23         init();
     24     }
     25 
     26     public SwitchView(Context context, AttributeSet attrs) {
     27         super(context, attrs);
     28         init();
     29     }
     30 
     31     public SwitchView(Context context, AttributeSet attrs, int defStyle) {
     32         super(context, attrs, defStyle);
     33         init();
     34     }
     35 
     36     //1 初始化图片(加载)
     37     private void init() {
     38         Resources resr = getResources();
     39         mSwitch_on = BitmapFactory.decodeResource(resr, R.mipmap.switch_on);
     40         mSwitch_off = BitmapFactory.decodeResource(resr, R.mipmap.switch_off);
     41         mSwitch_circle = BitmapFactory.decodeResource(resr, R.mipmap.switch_circle);
     42         setOnTouchListener(this);
     43     }
     44 
     45     //2 设置控件宽高(测量)
     46     @Override
     47     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     48         int widthSize = mSwitch_off.getWidth();
     49         int heightSize = mSwitch_off.getHeight();
     50         max = mSwitch_off.getWidth() - mSwitch_circle.getWidth();
     51         setMeasuredDimension(widthSize, heightSize);
     52     }
     53 
     54     //3 布局(排版)
     55     @Override
     56     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
     57         super.onLayout(changed, left, top, right, bottom);
     58     }
     59 
     60     //4 最后绘制控件
     61     @Override
     62     protected void onDraw(Canvas canvas) {
     63         super.onDraw(canvas);
     64         Matrix m = new Matrix();
     65         Paint p = new Paint();
     66         if (mCurrentState) {
     67             canvas.drawBitmap(mSwitch_on, m, p);
     68         } else {
     69             canvas.drawBitmap(mSwitch_off, m, p);
     70         }
     71         canvas.drawBitmap(mSwitch_circle, left, 0, p);
     72     }
     73 
     74     //5 触摸事件
     75     @Override
     76     public boolean onTouch(View v, MotionEvent event) {
     77         switch (event.getAction()) {
     78             case MotionEvent.ACTION_DOWN:
     79                 downX = (int) event.getX();//初始X轴按下坐标
     80                 break;
     81             case MotionEvent.ACTION_MOVE:
     82                 moveX = (int) event.getX();
     83                 left = moveX - downX;
     84                 if (!mCurrentState) {
     85                     //关闭状态边界处理
     86                     if (left < 0) {
     87                         left = 0;
     88                     } else if (left > max) {
     89                         left = max;
     90                     }
     91                 } else {
     92                     //开启状态边界处理
     93                     left = moveX - downX;
     94                     if (left > 0) {//向右滑
     95                         left = max;
     96                     } else if (Math.abs(left) > max) {
     97                         left = 0;
     98                     } else {
     99                         left = max - Math.abs(left);
    100                     }
    101                 }
    102                 break;
    103             case MotionEvent.ACTION_UP:
    104             case MotionEvent.ACTION_CANCEL://抬起时的判断
    105                 int upX = (int) event.getX();
    106                 boolean state = false; //滑动是否成功
    107                 //1 关闭状态
    108                 if (!mCurrentState) {
    109                     //滑动是否成功
    110                     //a 移动距离超过 1/2 的滑动宽度
    111                     //b 触摸点在滑动区域,开启按钮
    112                     state = (moveX - downX) >= max / 2 || upX >= max;
    113                     if (state) {
    114                         left = max;
    115                         mCurrentState = true;
    116                     } else {
    117                         left = 0;
    118                     }
    119                 } else {
    120                     //2 开启状态,判断滑动是否成功
    121                     //a 移动距离超过 1/2 的滑动宽度
    122                     //b 触摸点在滑动区域,关闭按钮
    123                     state = (downX - moveX) >= max / 2 || upX <= max;
    124                     if (state) {
    125                         left = 0;
    126                         mCurrentState = false;
    127                     } else {
    128                         left = max;
    129                     }
    130                 }
    131                 //滑动成功 且 回调接口不能空 触发回调方法
    132                 if (state && null != mOnSwitchChangedListener) {
    133                     mOnSwitchChangedListener.onSwitchChanged(mCurrentState);
    134                 }
    135                 break;
    136         }
    137         invalidate();
    138         return true;
    139     }
    140 
    141     //开关切换回调接口
    142     public interface OnSwitchChangedListener {
    143         void onSwitchChanged(boolean isOpen);
    144     }
    145 
    146     public void setOnSwitchChangedListener(OnSwitchChangedListener listener) {
    147         this.mOnSwitchChangedListener = listener;
    148     }
    149 
    150     public void setCurrentState(boolean isOpen) {
    151         mCurrentState = isOpen;
    152         left = isOpen ? max : 0;
    153         invalidate();
    154     }
    155 
    156 }
  • 相关阅读:
    第八场 hdu 6136 Death Podracing(dfs+思维)
    第九场 hdu 6162 Ch’s gift(树链剖分+线段树)
    树链剖分 模板
    CodeForces
    第十场 hdu 6172 Array Challenge(矩阵快速幂)
    第十场 hdu 6171 Admiral(双向bfs找交点)
    CodeForces
    第十场 hdu 6178 (bfs)
    第十场 hdu 6180 Schedule (multiset)/(思维)
    第八场 hdu 6143 Killer Names(思维题)
  • 原文地址:https://www.cnblogs.com/suiyilaile/p/9014152.html
Copyright © 2020-2023  润新知