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>


相关文章
|
10天前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
26 3
|
3天前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
16 0
|
3天前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
28天前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
52 10
|
Android开发
Android 开关按钮 ToggleButton 与 Switch 的使用
Android 开关按钮 ToggleButton 与 Switch 的使用
224 0
|
Android开发
Android Studio 开关按钮Switch
本文目录 1. 功能 2. 界面 3. 获取开关情况 4. 监听开关状态
568 0
Android Studio 开关按钮Switch
|
Android开发 iOS开发
Android 开关按钮切换,类似于iphone 效果,view实现
1、实现的效果            gitHub :  https://github.com/zcweng/ToggleButton
2132 0
|
前端开发 Java Android开发
android开关按钮
<span style="font-size:18px">刚开始接触开关样式的按钮是在IOS系统上面,它的切换以及滑动十分帅气,深入人心。</span> <p><span style="font-size:18px"><span style="white-space:pre"></span>所谓的开关按钮,就是只有2个状态:on和off,下图就是系统IOS 7上开关按钮效果。</span
1880 0
|
XML Android开发 iOS开发
android仿ios开关按钮
<p style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"> 前一段时间在做项目的时候遇到了一个问题,美工在设计的时候设计的是一个iPhone中的开关,但是都知道Android中的Switch开关和IOS中的不同,这样就需要通过动画来实现一个iPhone开关了。</p> <p s
2347 0