Android自定义View—滑动开关

MainActivity如下:

package cc.testview3;

import cc.testview3.SwitchView.SwitchChangedListener;
import android.os.Bundle;
import android.widget.Toast;
import android.app.Activity;
/**
 * Demo描述:
 * 自定义View实现滑动开关
 * 
 * 测试设备:
 * 分辨率为480x854
 */
public class MainActivity extends Activity {
    private SwitchView mSwitchView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
	}
    private void init(){
    	mSwitchView=(SwitchView) findViewById(R.id.switchView);
    	mSwitchView.initSwitchStatus(true);
    	mSwitchView.setOnSwitchChangedListener(new SwitchChangedListenerImpl());
    }
    
    private class SwitchChangedListenerImpl implements SwitchChangedListener{
		@Override
		public void OnChanged(boolean currentStatus) {
			Toast.makeText(MainActivity.this, "currentIsOff?-->"+currentStatus, Toast.LENGTH_SHORT).show();
		}
    	
    }
	
}


SwitchView如下:

package cc.testview3;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class SwitchView extends View  {
	private Bitmap mOnBitmap;
	private Bitmap mOffBitmap;
	private Bitmap mDotBitmap;
	private float currentX;
	private boolean currentIsSlipping=false;
	private boolean currentIsOff;
	private SwitchChangedListener mSwitchChangedListener;
    private int dotWidth;
    private int switchWidth;
	public SwitchView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initSwitchView();
	}

	public SwitchView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initSwitchView();
	}

	public SwitchView(Context context) {
		super(context);
		initSwitchView();
	}
	
	private void initSwitchView(){
		mOnBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.on);
		mOffBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.off);
		mDotBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.dot);
		dotWidth=mDotBitmap.getWidth();
		switchWidth=mOnBitmap.getWidth();
		this.setOnTouchListener(new TouchListenerImpl());
	}
	
	public void initSwitchStatus(boolean isOff){
		if (isOff) {
			currentX=switchWidth;
		} else {
			currentX=0;
		}
		currentIsOff=isOff;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	
	
	@Override
	protected void onLayout(boolean changed, int left, int top, int right,int bottom) {
		super.onLayout(changed, left, top, right, bottom);
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Matrix matrix=new Matrix();
		Paint paint=new Paint();
		
		//先画出开关的背景(关/开)
		if (currentIsOff) {
			canvas.drawBitmap(mOffBitmap, matrix, paint);
		} else {
			canvas.drawBitmap(mOnBitmap, matrix, paint);
		}
		
		//再画出滑块
		//1 在滑动中(if),滑块的left就是不断变化的currentX
		//2 手指抬起后(else)停止滑动时.此时的开关应该在左右
		//  其中一侧处于开或者关的状态
		if (currentIsSlipping) {
			canvas.drawBitmap(mDotBitmap, currentX, 17, paint);
		} else {
			if (currentIsOff) {
				canvas.drawBitmap(mDotBitmap, currentX-dotWidth, 17, paint); 
			}else{
				canvas.drawBitmap(mDotBitmap, currentX, 17, paint); 
			}
		}
	}
	
	private class TouchListenerImpl implements OnTouchListener{
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				
				break;
			case MotionEvent.ACTION_MOVE:
				currentIsSlipping=true;
				currentX = event.getX();
				if (currentX>switchWidth/2) {
					currentIsOff=true;
				}else {
					currentIsOff=false;
				}
				
				//防止向右边滑动时越界
				if (event.getX()>switchWidth-dotWidth) {
					currentX = switchWidth-dotWidth;
					currentIsOff=true;
				}
				//防止向左边滑动时越界
				if (event.getX()<0) {
					currentX=0;
					currentIsOff=false;
				}
				//重绘!!!
				invalidate();
				break;
			case MotionEvent.ACTION_UP:
				currentIsSlipping=false;
				currentX = event.getX();
				//抬起时若(if)已经超过开关一般的长度,则让其处于关闭的状态
				//否则(else)让其处于打开的状态
				if (currentX >= switchWidth / 2) {
					currentX = switchWidth;
					currentIsOff=true;
				} else {
					currentX = 0;
					currentIsOff=false;
				}
				if (mSwitchChangedListener != null) {
					mSwitchChangedListener.OnChanged(currentIsOff);
				}
				// 重绘!!!
				invalidate();
				break;

			default:
				break;
			}

			return true;
		}
		
	}

	// 接口
	public interface SwitchChangedListener {
		public void OnChanged(boolean currentIsOff);
	}
	
	public void setOnSwitchChangedListener(SwitchChangedListener switchChangedListener) {
		this.mSwitchChangedListener = switchChangedListener;
	}

}

main.xml如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    
    <cc.testview3.SwitchView
        android:id="@+id/switchView"
        android:layout_width="wrap_content"
        android:layout_height="60dip"
        android:layout_marginTop="200dip"
        android:layout_marginLeft="30dip"
    />
    
</RelativeLayout>


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