自定义滑动开关

转载请注明出处:http://blog.csdn.net/forwardyzk/article/details/42526343

当开发的时候,使用开关的时候,效果不能不满足我们的需求,要表现出滑动的效果。我们就可以自定义开关。

思路:

1.把开关分为两部分,一部分是开关的背景,另一部分是滑动按钮。

2.测量开关的长和宽,当然是在onMeasure中进行处理

3.在onTouchEvent()根据触摸开关进行滑动位置进行监听,在onDraw()中进行绘画。

当然也要绘画两部分:开关背景和滑动按钮

4.对触摸位置和滑动位置进行判断

1.触摸位置要在开关背景的范围内。

2.在绘画的时候,滑动按钮不能超出开关背景的范围。

在onTouchEvent()方法中调用invalidate()方法,会根据位置的变化不断的在onDraw()方法中绘画按钮。

设置开关的背景和滑动按钮

onXPosition和offXPosition为开关状态的变化之间,滑动按钮左侧的X坐标不能必须在两者之间。

public void setImageResource(int switchOnBg, int slipBtn) {
		Log.d(TAG, "setImageResource");
		switch_bg = BitmapFactory.decodeResource(getResources(), switchOnBg);
		slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn);
		onXPosition = switch_bg.getWidth() - slip_Btn.getWidth();
		offXPosition = 0;
	}

在OnTouchEvent()中监听手势滑动的位置

public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		// 按下,判断按下的位置在开关上,才可以做后面的操作
		case MotionEvent.ACTION_DOWN:
			Log.d(TAG, "MotionEvent.ACTION_DOWN");
			if (event.getX() > switch_bg.getWidth()
					|| event.getY() > switch_bg.getHeight()) {
				return false;
			}

			isSlipping = true;
			currentX = event.getX();
			break;
		// 滑动,记录当前的按下的位置
		case MotionEvent.ACTION_MOVE:
			Log.d(TAG, "MotionEvent.ACTION_MOVE");
			currentX = event.getX();
			break;
		// 松开,设置开关的监听器,设置开关的状态
		case MotionEvent.ACTION_UP:
			Log.d(TAG, "MotionEvent.ACTION_UP");
			isSlipping = false;
			// 松开前开关的状态
			boolean previousSwitchState = isSwitchOn;
			// 如果当前的位置在开关背景中间位置的右侧,表示的是开的状态,否则为关
			if (event.getX() >= (switch_bg.getWidth() / 2)) {
				isSwitchOn = true;
			} else {
				isSwitchOn = false;
			}

			// 如果设置了监听器,则调用此方法
			if (onSwitchListener != null && (previousSwitchState != isSwitchOn)) {
				onSwitchListener.onSwitched(isSwitchOn);
			}
			break;

		default:
			break;
		}

		// 重新绘制控件
		invalidate();// 不要忘了重绘开关
		return true;
	}

在最后不要忘了调用invalidate(),否则不会进行绘画开关。

判断了触摸的范围必须在开关上

在onDraw()绘画开关

protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Log.d(TAG, "onDraw");
		Matrix matrix = new Matrix();
		Paint paint = new Paint();
		// 滑动按钮的X方向左侧坐标
		float left_SlipBtn;
		// 把开关的背景画出来
		canvas.drawBitmap(switch_bg, matrix, paint);
		// 判断当前是否正在滑动
		if (isSlipping) {
			if (currentX > switch_bg.getWidth()) {
				left_SlipBtn = switch_bg.getWidth() - slip_Btn.getWidth();
			} else {
				// 保持滑动的位置是滑动按钮的中间位置
				left_SlipBtn = currentX - slip_Btn.getWidth() / 2;
			}
		} else {
			// 根据当前的开关状态设置滑动按钮的位置
			if (isSwitchOn) {
				left_SlipBtn = onXPosition;
			} else {
				left_SlipBtn = offXPosition;
			}
		}

		// 对滑动按钮左侧和右侧进行判断,不能超过背景的范围
		if (left_SlipBtn < 0) {
			left_SlipBtn = 0;
		} else if (left_SlipBtn > switch_bg.getWidth() - slip_Btn.getWidth()) {
			left_SlipBtn = switch_bg.getWidth() - slip_Btn.getWidth();
		}
		// 绘制滑动开关
		canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint);
	}

canvas.drawBitmap(switch_bg, matrix, paint)绘画开关背景

canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint)绘画滑动按钮

滑动按钮滑动的时,保持不能超过开关背景的范围,保持点击的位置在滑动按钮的中间位置。

使用步骤:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/main_button_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="15dp"
        android:paddingBottom="3dp"
        android:paddingLeft="25dp"
        android:paddingRight="25dp"
        android:paddingTop="3dp"
        android:text="切换状态"
        android:textSize="15sp" />

    <com.example.view.MySlipSwitch
        android:id="@+id/main_myslipswitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="20dp" />

</RelativeLayout>

在MainActivity.java中使用

public class MainActivity extends Activity {

	private Button switch_Btn;
	private MySlipSwitch slipswitch_MSL;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		setListener();
	}

	public void initView() {
		slipswitch_MSL = (MySlipSwitch) findViewById(R.id.main_myslipswitch);
		slipswitch_MSL.setImageResource(R.drawable.switch_bkg_switch,
				R.drawable.switch_btn_slip);
		slipswitch_MSL.setSwitchState(true);
		switch_Btn = (Button) findViewById(R.id.main_button_switch);
	}

	public void setListener() {
		//设置开关状态变化监听器
		slipswitch_MSL.setOnSwitchListener(new OnSwitchListener() {

			@Override
			public void onSwitched(boolean isSwitchOn) {
				// TODO Auto-generated method stub
				if (isSwitchOn) {
					Toast.makeText(getApplicationContext(), "开关已经开启", 0).show();
				} else {
					Toast.makeText(getApplicationContext(), "开关已经关闭", 0).show();
				}
			}
		});

		switch_Btn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				slipswitch_MSL.setSwitchState(!slipswitch_MSL.getSwitchState());
				if (slipswitch_MSL.getSwitchState()) {
					Toast.makeText(getApplicationContext(), "开关已经开启", 0).show();
				} else {
					Toast.makeText(getApplicationContext(), "开关已经关闭", 0).show();
				}
			}
		});

	}
}

点击切换按钮,获取开关的状态

设置滑动开关状态的的监听器,滑动的位置影响到了开关的状态,有响应的监听。

源码下载: http://download.csdn.net/detail/forwardyzk/8341363

效果图:

时间: 2024-10-05 00:21:15

自定义滑动开关的相关文章

Android 三档自定义滑动开关,禁止点击功能的实现,用默认的seekbar组件实现

android三档自定义滑动开关,禁止点击功能的实现,普通开关网上有很多例子,三档滑动开关的则找了整天都没有相关例子,开始用普通开关的源码修改了自己实现了一个类,但效果不如人意,各种边界情况的算法很难考虑周全很难调试出满意的效果. 今 天尝试用系统组件seekbar实现自定义风格的滑动条,但禁止点击和判断滑动不到指定范围返回花了不少时间,网上基本上都说用继承seekbar修改里 面的方法实现,但整了半天也没有一个能够达到效果了,而且感觉太麻烦了,所以自己把默认的实现的几个接口返回的信息详细打印出

Android自定义view 滑动开关 支持左右滑动 适用于listview

要做这样一种开关. 当开关在左边时,都是灰色的,向右滑动的时候,滑到一半的时候,改变颜色,变成绿色: 当开关在右边是,都市绿色的,向左滑动的时候,滑动一半的时候,改变颜色,变成灰色. 这里就要涉及要可滑动最大距离,以及你现在滑动的距离.通过这个来比较,改变颜色. import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.

Android之实现滑动开关组件

由于Android并未提供滑动开关之类的组件,所以我们需要自己去实现一个自定义的视图组件来实现滑动开关效果. 这里有一个示例代码,它包括三个类:开关组件视图.状态监听接口.MainActivity 我们先来看看整个demo的效果图: 我们先来看看视图组件的完整代码,代码都已经注释: package com.bear.swtichbuttondemo; import java.util.ArrayList; import android.content.Context; import androi

Android 拖动条(SeekBar)实例 附完整demo项目代码

1.拖动条的事件 实现SeekBar.OnSeekBarChangeListener接口.需要监听三个事件:数值改变(onProgressChanged)开始拖动(onStartTrackingTouch)停止拖动(onStopTrackingTouch) onStartTrackingTouch开始拖动时触发,与onProgressChanged区别是停止拖动前只触发一次而onProgressChanged只要在拖动,就会重复触发. 2.拖动条的主要属性和方法setMax 设置拖动条的数值se

屏幕锁案例

转载请注明出处:  http://blog.csdn.net/forwardyzk/article/details/42676213 现在的手机都有屏幕锁,有图案的,有数字的.下面介绍一个使用图案的屏幕锁. 思路: 1.根据屏幕的宽度,计算出9个点的坐标和半径. 2.使用画笔画出9个圆. 3.根据触摸的坐标判断是否在圆的范围之内,如果在圆的范围之内,表示此圆被触摸了. 4.根绝触摸圆的顺序,根据圆心,构建滑动的path,然后使用画笔画出. 计算圆的圆心和半径 int perSize = 0; i

android自定义View-------IOS风格的滑动开关

源码和测试例子已经放到github https://github.com/Leaking/SlideSwitch,欢迎star欢迎fork欢迎提issue 项目开发中,经常会有一些关于用户个性化的设置,此时经常需要一个开关控件,周末将之前写的自定义开关控件优化了一下,效果图如下.先说说大概思路:按钮绘制了三个图层,最下面是覆盖整个View的灰色,第二个是覆盖整个View的自定义的颜色,它可以改变透明度.第三个是白色.当白色部分移动时,修改第二个图层的透明度,即可作出如图滑动过程中颜色渐变的效果.

Android SwitchButton(滑动开关)

版本:1.0 日期:2014.5.17 2014.6.1 版权:© 2014 kince 转载注明出处 在介绍SwitchButton之前,先来看一下系统Button是如何实现的.源码如下: @RemoteView public class Button extends TextView { public Button(Context context) { this(context, null); } public Button(Context context, AttributeSet att

自定义控件基础01_菜单轮__viewPager_下拉框_自定义开关

1,自定义控件分类: 1.1组合控件:由安卓中原生的控件组合起来,配合动画达成的效果 1.2自定义控件 1.3组合控件案例演示: 案例:优酷菜单demo 三层圆环,按下menu键会通过动画效果消失在界面,点击小房子和中层圆环,最外层圆环消失 ①布局实现: 三层相对布局相互叠加(因为图片背景是透明的,所以可以叠加显示) 由于三个布局是叠加显示的,所以这个菜单选项要使用一个占据焦点比较强的(不然有可能点击不到)ImageButton控件 控件上background=”@android:color/t

安卓自定义开关控件

我们都知道Android4.0以上才带有滑动开关Switch,那么在4.0以下呢,很多人会选择用CheckBox,放两张图片,但是这样子只 能点击,效果不太好,所以我就自定义了滑动开关WiperSwitch这么一个控件,下面先把截图贴上吧,这蹩脚的图片真戳啊,大家可以自己换三张图片 [java] view plain copy package com.example.wiperswitch; import android.content.Context; import android.graph