Google 在 API 14 开始才新增了Switch 控件。

因此,我们可以选择自己封装一个Switch 。

效果如图:

View主要代码:

  1. public class SwitchView extends LinearLayout {
  2. private ImageView maskImage;              // 开关遮盖图片
  3. private boolean open;                     // 开关当前状态
  4. private boolean isAninFinish = true;      // 动画是否结束
  5. private float x;                          // 记录ACTION_DOWN时候的横坐标
  6. private boolean isChangedByTouch = false; // 是否在一次事件中已经切换过状态
  7. private OnSwitchChangeListener switchChangeListener; // 监控开关状态
  8. public interface OnSwitchChangeListener {
  9. void onSwitchChanged(boolean open);
  10. }
  11. public SwitchView(Context context, AttributeSet attrs) {
  12. super(context, attrs);
  13. init();
  14. }
  15. public SwitchView(Context context) {
  16. super(context);
  17. init();
  18. }
  19. private void init() {
  20. setBackgroundResource(R.drawable.switch_bg);
  21. maskImage = new ImageView(getContext());
  22. maskImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
  23. maskImage.setImageResource(R.drawable.switch_mask);
  24. addView(maskImage);
  25. }
  26. public boolean getSwitchStatus() {
  27. return open;
  28. }
  29. public void setSwitchStatus(boolean isOpen) {
  30. this.open = isOpen;
  31. if (isOpen) {
  32. setGravity(Gravity.RIGHT);
  33. } else {
  34. setGravity(Gravity.LEFT);
  35. }
  36. }
  37. @Override
  38. public boolean onTouchEvent(MotionEvent event) {
  39. switch (event.getAction()) {
  40. case MotionEvent.ACTION_DOWN: {
  41. x = event.getX();
  42. break;
  43. }
  44. case MotionEvent.ACTION_MOVE: {
  45. if (event.getX() - x > 5 && !open) { // 向右
  46. changeStatus();
  47. } else if (event.getX() - x < -5 && open) { // 向左
  48. changeStatus();
  49. }
  50. break;
  51. }
  52. case MotionEvent.ACTION_UP: {
  53. if (Math.abs(event.getX() - x) <= 5) {
  54. changeStatus();
  55. }
  56. isChangedByTouch = false;
  57. break;
  58. }
  59. case MotionEvent.ACTION_CANCEL: {
  60. isChangedByTouch = false;
  61. break;
  62. }
  63. }
  64. return true;
  65. }
  66. private void changeStatus() {
  67. if (isAninFinish && !isChangedByTouch) {
  68. isChangedByTouch = true;
  69. open = !open;
  70. isAninFinish = false;
  71. if (switchChangeListener != null) {
  72. switchChangeListener.onSwitchChanged(open);
  73. }
  74. changeOpenStatusWithAnim(open);
  75. }
  76. }
  77. private void changeOpenStatusWithAnim(boolean open) {
  78. if (open) {
  79. // 左到右
  80. Animation leftToRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
  81. Animation.ABSOLUTE, getWidth() - maskImage.getWidth(),
  82. Animation.RELATIVE_TO_SELF, 0,
  83. Animation.RELATIVE_TO_SELF, 0);
  84. leftToRight.setDuration(300);
  85. leftToRight.setAnimationListener(new AnimationListener() {
  86. @Override
  87. public void onAnimationStart(Animation animation) {
  88. }
  89. @Override
  90. public void onAnimationRepeat(Animation animation) {
  91. }
  92. @Override
  93. public void onAnimationEnd(Animation animation) {
  94. maskImage.clearAnimation();
  95. setGravity(Gravity.RIGHT);
  96. isAninFinish = true;
  97. }
  98. });
  99. maskImage.startAnimation(leftToRight);
  100. } else {
  101. // 右到左
  102. Animation rightToLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
  103. Animation.ABSOLUTE, maskImage.getWidth() - getWidth(),
  104. Animation.RELATIVE_TO_SELF, 0,
  105. Animation.RELATIVE_TO_SELF, 0);
  106. rightToLeft.setDuration(300);
  107. rightToLeft.setAnimationListener(new AnimationListener() {
  108. @Override
  109. public void onAnimationStart(Animation animation) {
  110. }
  111. @Override
  112. public void onAnimationRepeat(Animation animation) {
  113. }
  114. @Override
  115. public void onAnimationEnd(Animation animation) {
  116. maskImage.clearAnimation();
  117. setGravity(Gravity.LEFT);
  118. isAninFinish = true;
  119. }
  120. });
  121. maskImage.startAnimation(rightToLeft);
  122. }
  123. }
  124. public OnSwitchChangeListener getSwitchChangeListener() {
  125. return switchChangeListener;
  126. }
  127. public void setOnSwitchChangeListener(OnSwitchChangeListener switchChangeListener) {
  128. this.switchChangeListener = switchChangeListener;
  129. }
  130. }

测试用代码:

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. SwitchView switchView = (SwitchView) findViewById(R.id.switchview);
  7. switchView.setSwitchStatus(true);
  8. switchView.setOnSwitchChangeListener(new OnSwitchChangeListener() {
  9. @Override
  10. public void onSwitchChanged(boolean open) {
  11. Toast.makeText(MainActivity.this, "开关状态:" + open, Toast.LENGTH_SHORT).show();
  12. }
  13. });
  14. }
  15. }

测试用布局:

  1. <LinearLayout 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. android:padding="20dp"
  6. >
  7. <TextView
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:text="自定义开关状态:"
  11. />
  12. <com.fancyy.switchview.SwitchView
  13. android:layout_marginLeft="20dp"
  14. android:id="@+id/switchview"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content" />
  17. </LinearLayout>

测试代码下载:http://download.csdn.net/detail/a105865708/6800519

Android自定义控件(一)——开关控件的更多相关文章

  1. Android自定义控件之日历控件

      标签: android 控件 日历 应用 需求 2015年09月26日 22:21:54 25062人阅读 评论(109) 收藏 举报 分类: Android自定义控件系列(7) 版权声明:转载注 ...

  2. android自己定义开关控件

    近日在android项目要使用开关控件.可是android中自带的开关控件不太惬意,所以就打算通过自己定义View写一个开关控件 ios的开关控件当然就是我要仿照的目标. 先上图:   waterma ...

  3. Android自定义控件1--自定义控件介绍

    Android控件基本介绍 Android本身提供了很多控件比如我们常用的有文本控件TextView和EditText:按钮控件Button和ImageButton状态开关按钮ToggleButton ...

  4. Android - 自定义控件之圆形控件

    自定义控件 - 圈圈 Android L: Android Studio 效果:能够自定义圆圈半径和位置:设定点击效果:改变背景颜色 下面是demo图 点击前: 点击后: 自定义控件一般要继承View ...

  5. android 仿ios开关控件

    ios一些控件还是挺美丽的,可是对android程序猿来说可能比較苦逼,由于ios一些看起来简单的效果对android来说可能就没那么简单了,可是没办法非常多产品都是拿ios的一些控件叫android ...

  6. Android开发技巧——自定义控件之组合控件

    Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...

  7. Android常用酷炫控件(开源项目)github地址汇总

    转载一个很牛逼的控件收集帖... 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.Gri ...

  8. Android 常用炫酷控件(开源项目)git地址汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.P ...

  9. MaterialEditText——Android Material Design EditText控件

    MaterialEditText是Android Material Design EditText控件.可以定制浮动标签.主要颜色.默认的错误颜色等. 随着 Material Design 的到来, ...

  10. (转载)Android自定义标签列表控件LabelsView解析

    Android自定义标签列表控件LabelsView解析 作者 donkingliang 关注 2017.03.15 20:59* 字数 759 阅读 406评论 0喜欢 3 无论是在移动端的App, ...

随机推荐

  1. Mysql相关操作

    1. 如何更改系统环境变量PATH?vim /etc/profile  加入 PATH=$PATH:/usr/local/mysql/bin2. 默认mysql安装好后,并没有root密码,如何给ro ...

  2. Segment,Path,Ring和Polyline的区别

    这四者当中Segment是最小的单位,具体的构成路线可以分为两个条:Segment-Path-Ring(封闭的Path)Segment-Path-Polyline Segment 和 Path 可以说 ...

  3. How to start the Virtualbox VMs under terminal

    Since we have servral machine on my testbed(fedora), and if I need start some VMs on that, I have to ...

  4. CGRectInset CGRectoffset UIEdgeInsetsInsetRect 这三个函数的使用情况

    //CGRectInset 将原来的矩形放大或者缩小,正表示缩小,-表示放大. CGRect rect= CGRectMake(20, 50, 100, 80); CGRect rect1=CGRec ...

  5. (原)torch的训练过程

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6221622.html 参考网址: http://ju.outofmemory.cn/entry/284 ...

  6. 自定义 Preference Header 布局

    1. Preference Header 概述: 对于什么是 Preference Header,以及何时使用 Preference Header,请参考我的另一篇博文: 何时使用 Preferenc ...

  7. CSS阻止文本选择

    在日常运用中,经常遇到点击按钮/菜单的时候,选中了文本,为了避免这种情况,可以使用纯css来解决这个问题(IE10+),对于旧版本的就只能用js:onselectstart = 'return fal ...

  8. ios NSKeyedArchiver 保存对象与对象数组

    废话不说,直接上代码 // // CommunityTool.h // SmartCommunity // // Created by chenhuan on 15/9/2. // Copyright ...

  9. 复习css3的部分属性

    利用css3实现一个半月形的西瓜,利用queue实现吃西瓜的动画.练习例子 css3: 1.圆角 border-radius:100%; border-top-left-radius:5px; 2.变 ...

  10. php 之 类,对象(三)多态性,函数重载,克隆

    一.三大特性之三 多态性(在php中表象不明显)1.概念:当父类引用指向子类实例时,由于子类对父类函数进行了重写,导致我们在使用该引用去调用相应的方法显示出的不同.2.发生条件:1.必须有继承 2. ...