Android自定义控件(一)——开关控件

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

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

效果如图:

View主要代码:

 

[java] view plaincopy
 
  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.   
  9.     public interface OnSwitchChangeListener {  
  10.         void onSwitchChanged(boolean open);  
  11.     }  
  12.   
  13.     public SwitchView(Context context, AttributeSet attrs) {  
  14.         super(context, attrs);  
  15.         init();  
  16.     }  
  17.   
  18.     public SwitchView(Context context) {  
  19.         super(context);  
  20.         init();  
  21.     }  
  22.   
  23.     private void init() {  
  24.         setBackgroundResource(R.drawable.switch_bg);  
  25.         maskImage = new ImageView(getContext());  
  26.         maskImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  27.         maskImage.setImageResource(R.drawable.switch_mask);  
  28.         addView(maskImage);  
  29.     }  
  30.   
  31.     public boolean getSwitchStatus() {  
  32.         return open;  
  33.     }  
  34.   
  35.     public void setSwitchStatus(boolean isOpen) {  
  36.         this.open = isOpen;  
  37.         if (isOpen) {  
  38.             setGravity(Gravity.RIGHT);  
  39.         } else {  
  40.             setGravity(Gravity.LEFT);  
  41.         }  
  42.     }  
  43.       
  44.     @Override  
  45.     public boolean onTouchEvent(MotionEvent event) {  
  46.         switch (event.getAction()) {  
  47.         case MotionEvent.ACTION_DOWN: {  
  48.             x = event.getX();  
  49.             break;  
  50.         }  
  51.         case MotionEvent.ACTION_MOVE: {  
  52.             if (event.getX() - x > 5 && !open) { // 向右  
  53.                 changeStatus();  
  54.             } else if (event.getX() - x < -5 && open) { // 向左  
  55.                 changeStatus();  
  56.             }  
  57.             break;  
  58.         }  
  59.         case MotionEvent.ACTION_UP: {  
  60.             if (Math.abs(event.getX() - x) <= 5) {  
  61.                 changeStatus();  
  62.             }  
  63.             isChangedByTouch = false;  
  64.             break;  
  65.         }  
  66.         case MotionEvent.ACTION_CANCEL: {  
  67.             isChangedByTouch = false;  
  68.             break;  
  69.         }  
  70.         }  
  71.         return true;  
  72.     }  
  73.       
  74.     private void changeStatus() {  
  75.         if (isAninFinish && !isChangedByTouch) {  
  76.             isChangedByTouch = true;  
  77.             open = !open;  
  78.             isAninFinish = false;  
  79.             if (switchChangeListener != null) {  
  80.                 switchChangeListener.onSwitchChanged(open);  
  81.             }  
  82.             changeOpenStatusWithAnim(open);  
  83.         }  
  84.     }  
  85.   
  86.     private void changeOpenStatusWithAnim(boolean open) {  
  87.         if (open) {  
  88.             // 左到右  
  89.             Animation leftToRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,   
  90.                     Animation.ABSOLUTE, getWidth() - maskImage.getWidth(),   
  91.                     Animation.RELATIVE_TO_SELF, 0,   
  92.                     Animation.RELATIVE_TO_SELF, 0);  
  93.             leftToRight.setDuration(300);  
  94.             leftToRight.setAnimationListener(new AnimationListener() {  
  95.                 @Override  
  96.                 public void onAnimationStart(Animation animation) {  
  97.                 }  
  98.   
  99.                 @Override  
  100.                 public void onAnimationRepeat(Animation animation) {  
  101.                 }  
  102.   
  103.                 @Override  
  104.                 public void onAnimationEnd(Animation animation) {  
  105.                     maskImage.clearAnimation();  
  106.                     setGravity(Gravity.RIGHT);  
  107.                     isAninFinish = true;  
  108.                 }  
  109.             });  
  110.             maskImage.startAnimation(leftToRight);  
  111.         } else {  
  112.             // 右到左  
  113.             Animation rightToLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,  
  114.                     Animation.ABSOLUTE, maskImage.getWidth() - getWidth(),   
  115.                     Animation.RELATIVE_TO_SELF, 0,   
  116.                     Animation.RELATIVE_TO_SELF, 0);  
  117.             rightToLeft.setDuration(300);  
  118.             rightToLeft.setAnimationListener(new AnimationListener() {  
  119.                 @Override  
  120.                 public void onAnimationStart(Animation animation) {  
  121.                 }  
  122.   
  123.                 @Override  
  124.                 public void onAnimationRepeat(Animation animation) {  
  125.                 }  
  126.   
  127.                 @Override  
  128.                 public void onAnimationEnd(Animation animation) {  
  129.                     maskImage.clearAnimation();  
  130.                     setGravity(Gravity.LEFT);  
  131.                     isAninFinish = true;  
  132.                 }  
  133.             });  
  134.             maskImage.startAnimation(rightToLeft);  
  135.         }  
  136.     }  
  137.   
  138.     public OnSwitchChangeListener getSwitchChangeListener() {  
  139.         return switchChangeListener;  
  140.     }  
  141.   
  142.     public void setOnSwitchChangeListener(OnSwitchChangeListener switchChangeListener) {  
  143.         this.switchChangeListener = switchChangeListener;  
  144.     }  
  145.       
  146. }  


测试用代码:

 

 

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


测试用布局:

 

 

[html] view plaincopy
 
  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.   
  18. </LinearLayout>  

 

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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。