Android自定义View示例(二)—滑动开关

简介: MainActivity如下: package cc.testview3;import cc.testview3.SwitchView.SwitchChangedListener;import android.

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>


相关文章
|
13天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
47 1
|
3月前
|
存储 算法 开发工具
OpenCV 安卓编程示例:1~6 全
OpenCV 安卓编程示例:1~6 全
50 0
|
3月前
|
Android开发 容器
Android UI设计: 什么是View和ViewGroup?
Android UI设计: 什么是View和ViewGroup?
35 0
|
17天前
|
Android开发
Android 开发 pickerview 自定义选择器
Android 开发 pickerview 自定义选择器
10 0
|
4月前
|
XML API Android开发
Android 自定义View 之 Dialog弹窗
Android 自定义View 之 Dialog弹窗
|
4月前
|
XML API Android开发
Android 自定义View 之 饼状进度条
Android 自定义View 之 饼状进度条
|
XML Android开发 数据格式
Android自定义View示例(零)—很简单的自定义View
MainActivity如下:package cn.com; import android.app.Activity; import android.
996 0
|
XML Android开发 数据格式
Android自定义View示例(四)—带有动画的Dialog
MainActivity如下: package cc.testview1; import android.os.Bundle; import android.
812 0
|
Android开发 数据格式 XML
Android自定义View示例(三)—滑动控件
MainActivity如下: package cc.testview4; import cc.testview4.SlideView.SwitchChangedListener; import android.
874 0
|
17天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0