码迷,mamicode.com
首页 > 移动开发 > 详细

安卓自定义开关控件

时间:2016-04-07 15:56:49      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:

我们都知道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. }  

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

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

安卓自定义开关控件

标签:

原文地址:http://www.cnblogs.com/wangying222/p/5363911.html

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