自定义开关view,仿苹果的开关
/**
* Created on 15/6/11.
* 一个view从创建到显示要经历的过程
* 1:构造函数 实例初始化
* 2:测量 onMeasure
* 3:如果当前view是ViewGroup 还要义务测量它孩子(子view)
* 4:指定控件的大小和位置 (onLayout)
* 如果当前view是ViewGroup 还要义务指定它孩子的大小和位置(子view)
* 5:绘制(就是画出来再屏幕上可见)onDraw(Canvas canvas)
*
* 点击事件包含点击和离开,而这个离开刚好和移动中的up事件一样
*/
public class MyToggleView extends View implements OnClickListener {
private Paint paint;
private Bitmap bg_bitmap;
private Bitmap sliding_bitmap;
private float slidingLeft = 0;
private float slidingMax;
private Handler hander;
public MyToggleView(Context context) {
super(context);
initView();
}
public MyToggleView(Context context,Handler handler) {
super(context);
this.hander=handler;
initView();
}
public MyToggleView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public MyToggleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
public MyToggleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void initView() {
paint = new Paint();
bg_bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_background);
sliding_bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.slide_button);
slidingMax = bg_bitmap.getWidth() - sliding_bitmap.getWidth();
setOnClickListener(this);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bg_bitmap, 0, 0, paint);
canvas.drawBitmap(sliding_bitmap, slidingLeft, 0, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/**
* 这是父类去测量子view的大小 而我们可以不要父类去测量
* 人为指定控件测量大小 (就是说没有测量)
*/
setMeasuredDimension(bg_bitmap.getWidth(), bg_bitmap.getHeight());
}
public boolean isOpened() {
return isOpened;
}
public boolean isOpened = false;
private boolean clickable = false;
@Override
public void onClick(View view) {
if (clickable) {
isOpened = !isOpened;
if (isOpened) {
hander.sendEmptyMessage(1);
slidingLeft = bg_bitmap.getWidth() - sliding_bitmap.getWidth();
} else {
hander.sendEmptyMessage(0);
slidingLeft = 0;
}
invalidate();
}
}
private float startX = 0;
private float lastX = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = startX = event.getX();
clickable = true;
break;
case MotionEvent.ACTION_MOVE:
float endX = event.getX();
int distanceX = (int) Math.abs(endX - lastX);
if (distanceX > 5) {
clickable = false;
}
refreshView(endX);
startX = event.getX();
break;
case MotionEvent.ACTION_UP:
if (slidingLeft > slidingMax / 2){
isOpened = true;
hander.sendEmptyMessage(1);
slidingLeft = slidingMax;
} else {
hander.sendEmptyMessage(0);
isOpened = false;
slidingLeft = 0;
}
invalidate();
break;
}
return true;
}
private void refreshView(float endX) {
float distance=endX-startX;
slidingLeft+=distance;
if(slidingLeft<0){
slidingLeft=0;
}
if(slidingLeft>slidingMax){
slidingLeft=slidingMax;
}
invalidate();
}
}
使用中,直接在activity中定义
MytoggleView toggleView=new MyToggleView(this,handler);
LinearLayout layout=findViewById(R.id.layout);
layout.addView(toggleView);
然后在handler中接收消息,判断开关状态
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
Toast.makeText(MainActivity.this,"开开开开开",Toast.LENGTH_SHORT).show();
break;
case 0:
Toast.makeText(MainActivity.this,"关关关关关",Toast.LENGTH_SHORT).show();
break;
}
}
};
PS:
有个问题没解决,就是如果直接在xml中定义开关,就没办法传handler了,哪有怎么才能监听开关的状态呢?
如果有大神知道,麻烦告诉我一下哈
转自:http://blog.csdn.net/coderinchina/article/details/46449145
我根据自己的想法稍微改了一下