zoukankan      html  css  js  c++  java
  • 安卓自定义开关控件(带有滑动功能)

    我们都知道Android4.0以上才带有滑动开关Switch,那么在4.0以下呢,很多人会选择用CheckBox,放两张图片,但是这样子只 能点击,效果不太好,所以我就自定义了滑动开关WiperSwitch这么一个控件,下面先把截图贴上吧,这蹩脚的图片真戳啊,大家可以自己换三张图片

    1. package com.example.wiperswitch;  
    2.   
    3. import android.content.Context;  
    4. import android.graphics.Bitmap;  
    5. import android.graphics.BitmapFactory;  
    6. import android.graphics.Canvas;  
    7. import android.graphics.Matrix;  
    8. import android.graphics.Paint;  
    9. import android.util.AttributeSet;  
    10. import android.view.MotionEvent;  
    11. import android.view.View;  
    12. import android.view.View.OnTouchListener;  
    13.   
    14. /** 
    15.  *  
    16.  * @author xiaanming 
    17.  * 
    18.  */  
    19. public class WiperSwitch extends View implements OnTouchListener{  
    20.     private Bitmap bg_on, bg_off, slipper_btn;  
    21.     /** 
    22.      * 按下时的x和当前的x 
    23.      */  
    24.     private float downX, nowX;  
    25.       
    26.     /** 
    27.      * 记录用户是否在滑动 
    28.      */  
    29.     private boolean onSlip = false;  
    30.       
    31.     /** 
    32.      * 当前的状态 
    33.      */  
    34.     private boolean nowStatus = false;  
    35.       
    36.     /** 
    37.      * 监听接口 
    38.      */  
    39.     private OnChangedListener listener;  
    40.       
    41.       
    42.     public WiperSwitch(Context context) {  
    43.         super(context);  
    44.         init();  
    45.     }  
    46.   
    47.     public WiperSwitch(Context context, AttributeSet attrs) {  
    48.         super(context, attrs);  
    49.         init();  
    50.     }  
    51.       
    52.     public void init(){  
    53.         //载入图片资源  
    54.         bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.on_btn);  
    55.         bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.off_btn);  
    56.         slipper_btn = BitmapFactory.decodeResource(getResources(), R.drawable.white_btn);  
    57.           
    58.         setOnTouchListener(this);  
    59.     }  
    60.       
    61.     protected void onDraw(Canvas canvas) {  
    62.         super.onDraw(canvas);  
    63.         Matrix matrix = new Matrix();  
    64.         Paint paint = new Paint();  
    65.         float x = 0;  
    66.           
    67.         //根据nowX设置背景,开或者关状态  
    68.         if (nowX < (bg_on.getWidth()/2)){  
    69.             canvas.drawBitmap(bg_off, matrix, paint);//画出关闭时的背景  
    70.         }else{  
    71.             canvas.drawBitmap(bg_on, matrix, paint);//画出打开时的背景   
    72.         }  
    73.           
    74.         if (onSlip) {//是否是在滑动状态,    
    75.             if(nowX >= bg_on.getWidth())//是否划出指定范围,不能让滑块跑到外头,必须做这个判断  
    76.                 x = bg_on.getWidth() - slipper_btn.getWidth()/2;//减去滑块1/2的长度  
    77.             else  
    78.                 x = nowX - slipper_btn.getWidth()/2;  
    79.         }else {  
    80.             if(nowStatus){//根据当前的状态设置滑块的x值  
    81.                 x = bg_on.getWidth() - slipper_btn.getWidth();  
    82.             }else{  
    83.                 x = 0;  
    84.             }  
    85.         }  
    86.           
    87.         //对滑块滑动进行异常处理,不能让滑块出界  
    88.         if (x < 0 ){  
    89.             x = 0;  
    90.         }  
    91.         else if(x > bg_on.getWidth() - slipper_btn.getWidth()){  
    92.             x = bg_on.getWidth() - slipper_btn.getWidth();  
    93.         }  
    94.           
    95.         //画出滑块  
    96.         canvas.drawBitmap(slipper_btn, x , 0, paint);   
    97.     }  
    98.   
    99.     @Override  
    100.     public boolean onTouch(View v, MotionEvent event) {  
    101.         switch(event.getAction()){  
    102.         case MotionEvent.ACTION_DOWN:{  
    103.             if (event.getX() > bg_off.getWidth() || event.getY() > bg_off.getHeight()){  
    104.                 return false;  
    105.             }else{  
    106.                 onSlip = true;  
    107.                 downX = event.getX();  
    108.                 nowX = downX;  
    109.             }  
    110.             break;  
    111.         }  
    112.         case MotionEvent.ACTION_MOVE:{  
    113.             nowX = event.getX();  
    114.             break;  
    115.         }  
    116.         case MotionEvent.ACTION_UP:{  
    117.             onSlip = false;  
    118.             if(event.getX() >= (bg_on.getWidth()/2)){  
    119.                 nowStatus = true;  
    120.                 nowX = bg_on.getWidth() - slipper_btn.getWidth();  
    121.             }else{  
    122.                 nowStatus = false;  
    123.                 nowX = 0;  
    124.             }  
    125.               
    126.             if(listener != null){  
    127.                 listener.OnChanged(WiperSwitch.this, nowStatus);  
    128.             }  
    129.             break;  
    130.         }  
    131.         }  
    132.         //刷新界面  
    133.         invalidate();  
    134.         return true;  
    135.     }  
    136.       
    137.       
    138.       
    139.     /** 
    140.      * 为WiperSwitch设置一个监听,供外部调用的方法 
    141.      * @param listener 
    142.      */  
    143.     public void setOnChangedListener(OnChangedListener listener){  
    144.         this.listener = listener;  
    145.     }  
    146.       
    147.       
    148.     /** 
    149.      * 设置滑动开关的初始状态,供外部调用 
    150.      * @param checked 
    151.      */  
    152.     public void setChecked(boolean checked){  
    153.         if(checked){  
    154.             nowX = bg_off.getWidth();  
    155.         }else{  
    156.             nowX = 0;  
    157.         }  
    158.         nowStatus = checked;  
    159.     }  
    160.   
    161.       
    162.     /** 
    163.      * 回调接口 
    164.      * @author len 
    165.      * 
    166.      */  
    167.     public interface OnChangedListener {  
    168.         public void OnChanged(WiperSwitch wiperSwitch, boolean checkState);  
    169.     }  
    170.   
    171.   
    172. }  


    用法是,先定义XML文件

    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent" >  
    5.   
    6.     <com.example.wiperswitch.WiperSwitch  
    7.         android:id="@+id/wiperSwitch1"  
    8.         android:layout_width="wrap_content"  
    9.         android:layout_height="wrap_content" />  
    10.   
    11.   
    12. </RelativeLayout>  


    新建一个Activity

    1. package com.example.wiperswitch;  
    2.   
    3.   
    4. import android.app.Activity;  
    5. import android.os.Bundle;  
    6. import android.util.Log;  
    7.   
    8. import com.example.wiperswitch.WiperSwitch.OnChangedListener;  
    9.   
    10. public class MainActivity extends Activity implements OnChangedListener {  
    11.   
    12.     @Override  
    13.     public void onCreate(Bundle savedInstanceState) {  
    14.         super.onCreate(savedInstanceState);  
    15.         setContentView(R.layout.activity_main);  
    16.         //实例化WiperSwitch  
    17.         WiperSwitch wiperSwitch = (WiperSwitch)findViewById(R.id.wiperSwitch1);  
    18.           
    19.         //设置初始状态为false  
    20.         wiperSwitch.setChecked(false);  
    21.           
    22.         //设置监听  
    23.         wiperSwitch.setOnChangedListener(this);  
    24.     }  
    25.   
    26.   
    27.     @Override  
    28.     public void OnChanged(WiperSwitch wiperSwitch, boolean checkState) {  
    29.         Log.e("log", "" + checkState);  
    30.     }  
    31.   
    32.   
    33. }  

    代码全部上完了,写的不好的地方欢迎大牛指点!

    哦,忘记了还有三张蹩脚的图片没传

  • 相关阅读:
    【设计模式
    【设计模式
    【设计模式
    【设计模式
    【设计模式
    【设计模式
    实干猪
    Mysql 千万级快速查询|分页方案
    如何成为一名优秀的CTO(首席技术官)
    成为优秀程序员的10个有效方法
  • 原文地址:https://www.cnblogs.com/wangying222/p/5363911.html
Copyright © 2011-2022 走看看