安卓自定义开关控件

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

[java] view plain copy

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

用法是,先定义XML文件

[html] view plain copy

  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. <com.example.wiperswitch.WiperSwitch
  6. android:id="@+id/wiperSwitch1"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content" />
  9. </RelativeLayout>

新建一个Activity

[java] view plain copy

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

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

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

时间: 2024-08-17 23:02:12

安卓自定义开关控件的相关文章

小米3系统计算器自定义开关控件-MySwitchView

1.前言 在android4.0以后,有switch控件,类似于iPhone上面滑块的效果,但是只能用在4.0以后的系统中,之前的平台,就无法使用这种控件.近段时间,看到了小米3手机上自带的计算器app,有这样的效果,上面的一个控件,觉得很漂亮,并且与iPhone上的效果略有不同,于是自己动手编写了一下这个功能,在编写的过程中,参考过网上的一些demo,运行后,在控件滑动的时候,感觉动画不平滑,有卡顿的现象,反复修改,最后还是有一些问题,感觉是在滑动中的状态,没有合理的控制好.无奈只能参考Goo

安卓自定义日历控件

尊重作者劳动成果,转载请注明出处:http://blog.csdn.net/baiyuliang2013/article/details/37732149 最近,因工作需要,需要实现自定义日历控件功能,主要应用于软件中的酒店入住时间选择功能,进入日历后,可选择入住时间,及离开时间,选择完成后,再次进入日历时,会显示上次选中的结果,默认选择日期是在距当前日期三个月内,三个月以外的均以灰色显示,且不可点击.本篇实现的效果是高仿某软件的界面效果: 某软件界面效果: 本篇实现的效果: 另外,对于日期选择

android自定义开关控件

近日在android项目要使用开关控件,但是android中自带的开关控件不太满意,所以就打算通过自定义View写一个开关控件 ios的开关控件当然就是我要仿照的目标. 先上图:    分析: 开关控件,中包含了两个部分,一个是一个圆,一个是圆角矩形,好了那我们只要通过view来进行绘制这两部分就可以了 直接上代码: package com.example.widget; import com.example.switchbutton_master.R; import android.conte

安卓自定义组合控件--toolbar

最近在学习安卓APP的开发,用到了toolbar这个控件, 最开始使用时include layout这种方法,不过感觉封装性不好,就又改成了自定义组合控件的方式. 使用的工具为android studio 2.2,简称AS吧 1.首先创建一个新的自定义控件,如下图.AS会创建3个文件,  一个java文件,一个layout中的xml文件(这个是布局文件),一个values中的xml文件(这个是属性文件) 2. 修改布局文件,代码如下.这里使用了RelativeLayout,  并且宽度和高度都选

安卓自定义日期控件(仿QQ,IOS7)

还记得上篇:高大上的安卓日期时间选择器,本篇是根据上篇修改而来,先看下qq中日期选择的效果: 鉴于目前还没有相似的开源日期控件,因此本人花费了一些时间修改了下之前的日期控件,效果如图: 虽说相似度不是百分之百,但相对其它日期控件是不是更加高大上了许多,哈哈~代码就不在往上贴了,如果感觉不错可以下载源码,并修改成更加符合你的效果. 源码地址:http://download.csdn.net/detail/baiyuliang2013/8692313

安卓自定义日期控件(仿QQ,IOS7)续

本篇是在原来的基础上修改了界面效果,使其更加接近ios7,qq等日期选择控件,看图: 源码地址:http://download.csdn.net/detail/baiyuliang2013/8760159

安卓自定义组合控件实现标题栏

public class TitleView extends FrameLayout {          private Button leftButton;          private TextView titleText;          public TitleView(Context context, AttributeSet attrs) {           super(context, attrs);           LayoutInflater.from(cont

Ext 6.5.3 classic版本,自定义实现togglefield开关控件

1,在Ext 6.5.3的classic版中没有提供开关控件,参照modern版中 togglefield开关的实现,继承滑动器(sliderfield),自定义一个开关按钮.支持value绑定和点击切换状态以及表单提交. 2,完成后效果如图: 3, js代码如下: //基于滑动器自定义开关控件, by xxx Ext.define('ux.slider.Toggle', { extend: 'Ext.slider.Single', alias: 'widget.uxSliderToggle',

Android 自定义SwitchButton开关控件

SwitchButton开关控件早已经非常流行.有各种各样的样式,SwitchButton开关控件一般用于app软件设置那里,控制缓存.声音.提示.下载等等.是具有很好的UI体验以及用户的习惯性.那么再下面介绍一个SwitchButton开关控件.并附上源码. 源码下载:点击 一.看实现的效果图 二.自定义SwitchButton 这是一个继承CheckBox的SwitchButton类.来实现做这些动画效果的,首先准备好这些图片,然后canvas绘制控件 的边框.背景.以及按钮.绘制时候加上相