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的宽和高是非常easy得出来的,高度就是这个控件背景图的宽和高

      

所以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);
		}

精巧状态的话,非常easy,依据不同的状态将滑块放置到控件的左边和右边就可以

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下载

时间: 2024-10-15 22:20:26

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

Android圆形图片--自己定义控件

Android圆形图片控件效果图例如以下: 代码例如以下: RoundImageView.java package com.dxd.roundimageview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Ca

Android经常使用自己定义控件

http://www.see-source.com/androidwidget/list.html

Android自定义控件1--自定义控件介绍

Android控件基本介绍 Android本身提供了很多控件比如我们常用的有文本控件TextView和EditText:按钮控件Button和ImageButton状态开关按钮ToggleButton单选复选按钮RadioButton和RadioGroup单选按钮和复选按钮CheckBox图片控件ImageView时钟控件AnalogClock和DigitalClock进度条ProgressBar和日期与时间选择控件DatePicker和TimePicker等. 文本控件TextView 和Ed

Android自己定义控件之轮播图控件

背景 近期要做一个轮播图的效果.网上看了几篇文章.基本上都能找到实现,效果还挺不错,可是在写的时候感觉每次都要单独去又一次在Activity里写一堆代码.于是自己封装了一下.这里仅仅是做了下封装成一个控件,不必每次反复写代码了. 效果图 实现分析 轮播图的功能就是实现左右滑动的广告.图片信息展示,那我们就用ViewPager来实现,由于考虑到用户体验,我们还须要在以下加一个指示器来标示滑动到了第几张轮播图.指示器我们能够用一个线性布局来依据要展示的轮播图设置显示的View,我们要做这种一个控件没

从源码中浅析Android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何通过布局文件,就能实现控件效果的不同呢?比如在布局文件中,我设置了一个TextView,给它设置了textColor,它就能够改变这个TextView的文本的颜色.这是如何做到的呢?我们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码. 1.attrs.xml: 我们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了所有的控件的属性,就是我们在布局文件中设置的各类属性 你可以找到attr

Android自己定义控件(状态提示图表)

[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重分享成果] 1 背景 前面分析那么多系统源代码了.也该暂停下来歇息一下,趁昨晚闲着看见一个有意思的需求就操练一下分析源代码后的实例演练--自己定义控件. 这个实例非常适合新手入门自己定义控件.先看下效果图: 横屏模式例如以下: 竖屏模式例如以下: 看见没有.这个控件全然自己定义的,连文字等都是自己定义的,没有不论什么图片等资源,就仅仅是一个小的java文件,这个界面仅仅有一个控件.例如以下咱们看下实现代

Android自己定义控件皮肤

Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有一定变化,用户体验十分好. 这当中,就涉及到了Android自己定义控件属性的操作方法,下面操作以实现自己定义button皮肤为例. 1. 我们要自己定义将要实现的外观状态.能够是图片或者是自己定义的xml,这是我们直接自己定义不同状态的颜色xml,在values文件夹下新建colors.xml,代

android 自己定义控件属性(TypedArray以及attrs解释)

近期在捣鼓android 自己定义控件属性,学到了TypedArray以及attrs.在这当中看了一篇大神博客Android 深入理解Android中的自己定义属性.我就更加深入学习力一番.我就沿着这个学习,讲一下流程吧,兴许一篇还有应用. 1.attrs文件编写 <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="titleText" for

Android 自己定义控件开发入门(二)

上一次我们讲了一堆实现自己定义控件的理论基础.列举了View类一些能够重写的方法,我们对这些方法的重写是我们继承View类来派生自己定义控件的关键 我通过一个最简单的样例给大家展示了这一个过程,不管是多么复杂的自己定义控件.思路总是这样子的,可是由于我们只重写了onDraw方法使得大家认为怪怪的.作为一个控件,我们竟然还要为了他的实现为其添加麻烦的监听,这就不能叫做控件了. 以下再给大家介绍一个常常重写的方法法:publicboolean onTouchEvent (MotionEvent ev