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

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>


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



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值