Android应用之——自定义控件ToggleButton

我们经常会看到很多优秀的app上面都有一些很漂亮的控件,用户体验非常好,比如togglebutton就是一个很好的例子,IOS系统下面那个精致的togglebutton如今在android下面也可以实现了,而且还可以自定义它的颜色文字背景图,做出各种漂亮的开关按键出来。这里就用到了android里面一个比较常用的技术——自定义控件。

先来看下我们实现的自定义的togglebutton效果图:

    

自定义控件的步骤:

1、首先,定义一个类继承View 或者View的子类,这个取决于要定义的控件的类型,本例中,继承自View。

2、继承了View后 就需要重写构造函数,有三个方法,分别是

	public MyView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
	}

	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub

这三个方法,根据不同的情况来使用,如果自定义的控件需要设置xml属性那么就要用到第三个构造函数,如果需要设置xml属性并且定义样式,那么就需要实现第二个构造函数,使用其第三个参数defStyleAttr,如果没有以上两点要求,那么直接重写第一个构造函数即可。

这这个demo中,我们实现第一个构造函数即可

	public ToggleButton(Context context, AttributeSet attrs) {
		super(context, attrs);

		initBitmap();//初始化bitmap
	}

重写构造函数后,接下来就要根据不同控件的要求来选择是否重写onDraw和onMeasure方法了。

如果自定义控件的大小是需要自定义的,比如本例中的togglebutton,那么首先需要重写onMeasure方法,测算出自定义控件的宽和高。

很明显,我们这个togglebutton的宽和高是很容易得出来的,高度就是这个控件背景图的宽和高

      

所以onMeasure方法重写如下,得到自定义控件的宽和高

	/**
	 * 初始化开关图片
	 */
	private void initBitmap() {
		background = BitmapFactory.decodeResource(getResources(),
				R.drawable.switch_background);
		slideBackground = BitmapFactory.decodeResource(getResources(),
				R.drawable.slide_button_background);
	}
	/**
	 * 设置当前控件的宽和高
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		// 设置开关的宽和高
		setMeasuredDimension(background.getWidth(), background.getHeight());
	}

得到宽和高后,就需要绘制这个控件了,利用View的onDraw方法

重写onDraw方法,我们可以得到一个参数canvas

void onDraw(Canvas canvas)

有了这个canvas对象,就可以很方面的绘制出控件的样子

先绘制控件的背景,因为togglebutton,其实就是一个button在一个背景图上面来回滑动产生不同的效果,所以我们先绘制它的背景。

canvas.drawBitmap(background, 0, 0, null);

绘制完背景后,就要绘制小滑块了。小滑块有两种状态,一种是在滑动,另一种是静止状态,这两种状态我们需要分别进行处理。

当小滑块在滑动的时候,背景图是不会变的,而且它滑动到某个时刻的样子也很明确,滑动了多少距离就绘制它在某距离的状态,但是有一种情况需要进行处理,那就是滑块滑出边界的情况,如果是从左边滑出边界,那么就应该将它离左边的距离置为0,也就是不让它继续滑动,同理右边也要进行相应的处理。

滑动过程代码如下:

if(isSliding) {		// 正在滑动中
			int left = currentX - slideBackground.getWidth() / 2;

			if(left < 0) {		// 当前超出了左边界, 赋值为0
				left = 0;
			} else if(left > (background.getWidth() - slideBackground.getWidth())) {
				// 当前超出了右边界, 赋值为: 背景的宽度 - 滑动块的宽度
				left = background.getWidth() - slideBackground.getWidth();
			}

			canvas.drawBitmap(slideBackground, left, 0, null);
		}

静止状态的话,很容易,根据不同的状态将滑块放置到控件的左边和右边即可

if(currentState) {
				// 绘制开的状态
				canvas.drawBitmap(slideBackground, 0, 0, null);
			} else {
				// 绘制关的状态
				int left = background.getWidth() - slideBackground.getWidth();
				canvas.drawBitmap(slideBackground, left, 0, null);
			}

上面,我们就完成了自定义一个togglebutton的界面上的操作了,但是togglebutton的作用是用来控制开关的,所以还要对它的一些事件进行处理。

滑动事件的处理,捕获用户的操作,为它设置一个自定义的状态改变监听器

/**
	 * 捕获用户操作的事件
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			currentX = (int) event.getX();
			isSliding = true;
			break;
		case MotionEvent.ACTION_MOVE:
			currentX = (int) event.getX();
			break;
		case MotionEvent.ACTION_UP:
			isSliding = false;
			currentX = (int) event.getX();

			int center = background.getWidth() / 2;

			// 当前最新的状态
			boolean state = currentX < center;
			// 如果两个状态不一样并且监听事件不为null
			if (currentState != state && mOnToggleStateChangeListener != null) {
				// 调用用户的回调事件
				mOnToggleStateChangeListener.onToggleStateChange(state);
			}
			currentState = state;
			break;
		default:
			break;
		}
		invalidate(); // 此方法被调用会使onDraw方法重绘
		return true;
	}

这里自定义了一个状态改变监听器,用来监听togglebutton的状态改变,然后回调方法,进行相应的处理。

public interface OnToggleStateChangeListener {

	void onToggleStateChange(boolean state);

}

最后,为这个控件提供三个方法,设置状态为开或关的方法,还有一个设置监听事件的方法

/**
	 * 设置开关的状态
	 *
	 * @param state
	 */
	public void setToggleState(boolean state) {
		currentState = state;
	}

	public boolean getToogleState() {
		return currentState;
	}

	public void setOnToggleStateChangeListener(
			OnToggleStateChangeListener listener) {
		mOnToggleStateChangeListener = listener;
	}

到这里,整个自定义togglebutton的过程就算完了。接下来我们就可以在程序中使用自己定义的控件了。

在xml文件中,用全路径名使用自定义控件,然后在java代码中就可以获取到这个自定义控件的对象 和相关的方法了

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.yang.togglebutton.ToggleButton
        android:id="@+id/togglebutton"
        android:layout_width="wrap_content"
        android:layout_height="30dip"
        android:layout_centerInParent="true" />

    <com.yang.togglebutton.ToggleButtonVIPS
        android:id="@+id/toggle2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/togglebutton"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

总结一下其实就是几个步骤:

1、继承View或者它的子类,根据不同的情况重写不同的构造函数(必须)

2、重写onMeasure方法,测量控件的大小(非必须)

3、重写onDraw方法,绘制控件(非必须)

4、为控件设置一些自定义方法和监听器(非必须)

5、在xml中使用,或者直接在java代码中使用

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

Demo下载

Android应用之——自定义控件ToggleButton

时间: 2024-10-19 17:43:29

Android应用之——自定义控件ToggleButton的相关文章

荐 android 如何打包自定义控件(转)

荐 android 如何打包自定义控件(转) 目录[-] 方式一:将项目打包成jar包 方式二:项目作为一个library 设计自定义的控件对android开发人员来说,是家常便饭了,但是多次做项目的经验证明了一个道理,自定义的控件,可以在其他项目中,多次使用,所以接下来我们来介绍2种常用的打包方式,并讨论他们的利于病. 我们可以假设想要自定义一个改变文字显示的button(纯属假设,这样简单的功能其实也用不着自定义) 首先写好布局文件mybutton.xml 1 2 3 4 5 6 7 8 9

Android开发技巧——自定义控件之自定义属性

Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个ViewGroup子类,把它们封装起来使用.这是我们接触到的最简单的一种自定制控件了.但许多时候,我们还需要在布局文件中使用它们的时候,能通过属性传入一些值,来影响最终的显示结果. 我们在做项目中经常会遇到的一个情况:一张图片加一个文本的组合.比如充值账户成功之后显示的一个界面,上面是一个表示成功的

android控件布局 ToggleButton按钮 图片和文字

ToggleButton控件具有checked属性对于要切换状态的功能按钮来说十分好用 这里以phone的开启DTMFTwelveKeyDialer的按钮为例 展示其效果和布局 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" andro

Android自助餐之自定义控件(一)从layout自定义控件

Android自助餐之自定义控件(一)从layout自定义控件 Android自助餐之自定义控件一从layout自定义控件 从layout自定义控件 从layout自定义控件 layout中新建一个layout <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

Android中的自定义控件(二)

案例四: 自定义开关       功能介绍:本案例实现的功能是创建一个自定义的开关,可以自行决定开关的背景.当滑动开关时,开关的滑块可跟随手指移动.当手指松开后,滑块根据开关的状态,滑到最右边或者滑到最左边,同时保存开关的状态,将开关的状态回调给调用者.当然,上述功能系统给定的switch控件也可以实现.      实现步骤:        1. 写一个类继承view,重写两个参数的构造方法.在构造方法中指定工作空间,通过attrs.getAttributeResourceValue方法将jav

Android 手机卫士--自定义控件(获取焦点的TextView)

本文地址:http://www.cnblogs.com/wuyudong/p/5906735.html,转载请注明源地址. 本文将实现标题栏下面的textview中的文字跑马灯的效果,就是将一行文字水平循环滚动,效果如下: 实现代码如下: <!-- android:ellipsize="end"添加省略点的所在位置 --> <!-- 想让文字出现跑马灯效果,必须让其获取焦点 --> <!-- android:marqueeRepeatLimit="

android控件之ToggleButton(多状态按钮)

一.概述 ToggleButton有两种状态:选中状态和没选中状态(类似一个开关),并且需要为不同的状态设置不同的显示文本 二.ToggleButton属性 android:checked = "true"  ——按钮的状态(true为选中(textOn),false为没有选中(textOff)) android:textOff = "关" android:textOn = "开" 三.代码演示 1.先将下面两个图片放入到资源文件中(分别命名为o

Android成长日记-使用ToggleButton实现灯的开关

案例演示 此案例实现思路:通过ToggleButton控件,ImageView控件实现 ---xml代码: <!-- textOn:true textOff:falase[s1] --> <ToggleButton android:id="@+id/toggleB utton1" android:layout_width="match_parent" android:layout_height="wrap_content" an

android中switch和toggleButton

状态开关按钮ToggleButton和开关Switch都是由Button派生而来,Button的所有属性和方法都适用,通常用于状态的切换. 1)activity_main.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w