Google 在 API 14 开始才新增了Switch 控件。
因此,我们可以选择自己封装一个Switch 。
效果如图:
View主要代码:
- public class SwitchView extends LinearLayout {
- private ImageView maskImage; // 开关遮盖图片
- private boolean open; // 开关当前状态
- private boolean isAninFinish = true; // 动画是否结束
- private float x; // 记录ACTION_DOWN时候的横坐标
- private boolean isChangedByTouch = false; // 是否在一次事件中已经切换过状态
- private OnSwitchChangeListener switchChangeListener; // 监控开关状态
- public interface OnSwitchChangeListener {
- void onSwitchChanged(boolean open);
- }
- public SwitchView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
- public SwitchView(Context context) {
- super(context);
- init();
- }
- private void init() {
- setBackgroundResource(R.drawable.switch_bg);
- maskImage = new ImageView(getContext());
- maskImage.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
- maskImage.setImageResource(R.drawable.switch_mask);
- addView(maskImage);
- }
- public boolean getSwitchStatus() {
- return open;
- }
- public void setSwitchStatus(boolean isOpen) {
- this.open = isOpen;
- if (isOpen) {
- setGravity(Gravity.RIGHT);
- } else {
- setGravity(Gravity.LEFT);
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- x = event.getX();
- break;
- }
- case MotionEvent.ACTION_MOVE: {
- if (event.getX() - x > 5 && !open) { // 向右
- changeStatus();
- } else if (event.getX() - x < -5 && open) { // 向左
- changeStatus();
- }
- break;
- }
- case MotionEvent.ACTION_UP: {
- if (Math.abs(event.getX() - x) <= 5) {
- changeStatus();
- }
- isChangedByTouch = false;
- break;
- }
- case MotionEvent.ACTION_CANCEL: {
- isChangedByTouch = false;
- break;
- }
- }
- return true;
- }
- private void changeStatus() {
- if (isAninFinish && !isChangedByTouch) {
- isChangedByTouch = true;
- open = !open;
- isAninFinish = false;
- if (switchChangeListener != null) {
- switchChangeListener.onSwitchChanged(open);
- }
- changeOpenStatusWithAnim(open);
- }
- }
- private void changeOpenStatusWithAnim(boolean open) {
- if (open) {
- // 左到右
- Animation leftToRight = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
- Animation.ABSOLUTE, getWidth() - maskImage.getWidth(),
- Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 0);
- leftToRight.setDuration(300);
- leftToRight.setAnimationListener(new AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- maskImage.clearAnimation();
- setGravity(Gravity.RIGHT);
- isAninFinish = true;
- }
- });
- maskImage.startAnimation(leftToRight);
- } else {
- // 右到左
- Animation rightToLeft = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
- Animation.ABSOLUTE, maskImage.getWidth() - getWidth(),
- Animation.RELATIVE_TO_SELF, 0,
- Animation.RELATIVE_TO_SELF, 0);
- rightToLeft.setDuration(300);
- rightToLeft.setAnimationListener(new AnimationListener() {
- @Override
- public void onAnimationStart(Animation animation) {
- }
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- @Override
- public void onAnimationEnd(Animation animation) {
- maskImage.clearAnimation();
- setGravity(Gravity.LEFT);
- isAninFinish = true;
- }
- });
- maskImage.startAnimation(rightToLeft);
- }
- }
- public OnSwitchChangeListener getSwitchChangeListener() {
- return switchChangeListener;
- }
- public void setOnSwitchChangeListener(OnSwitchChangeListener switchChangeListener) {
- this.switchChangeListener = switchChangeListener;
- }
- }
测试用代码:
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- SwitchView switchView = (SwitchView) findViewById(R.id.switchview);
- switchView.setSwitchStatus(true);
- switchView.setOnSwitchChangeListener(new OnSwitchChangeListener() {
- @Override
- public void onSwitchChanged(boolean open) {
- Toast.makeText(MainActivity.this, "开关状态:" + open, Toast.LENGTH_SHORT).show();
- }
- });
- }
- }
测试用布局:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="20dp"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="自定义开关状态:"
- />
- <com.fancyy.switchview.SwitchView
- android:layout_marginLeft="20dp"
- android:id="@+id/switchview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- </LinearLayout>