android自定义开关控件

近日在android项目要使用开关控件,但是android中自带的开关控件不太满意,所以就打算通过自定义View写一个开关控件

ios的开关控件当然就是我要仿照的目标。

先上图:

  

分析:

开关控件,中包含了两个部分,一个是一个圆,一个是圆角矩形,好了那我们只要通过view来进行绘制这两部分就可以了

直接上代码:

package com.example.widget;

import com.example.switchbutton_master.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

//自定义开关控件
public class SwitchbuttonView extends View{
	//开关圆圈的按钮
	private Bitmap swithSilder;
	//获取的开关圆圈的宽度
	private int swithWidth;
	//开关圆圈在x轴上的位置
	private int swithShilerX;

	//在轻微调整大小的长度
	private int baseHeight;
	private int baseWidth;
	//开关控件当前的状态,true:开,false:关
	private Boolean currentState = false;
	//画笔
	private Paint paint;

	 /** 开关状态改变监听 */
    private OnToggleStateChangeListener mListener;  

	public SwitchbuttonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initBitmap();
    }  

	private void initBitmap() {
		swithSilder = BitmapFactory.decodeResource(getResources(), R.drawable.swich_slider_new);
		swithWidth = swithSilder.getWidth();
		baseHeight = swithWidth / 10;
		baseWidth = swithWidth / 5;

		paint = new Paint();
		//初始画笔的样式没不填充
		paint.setStyle(Paint.Style.STROKE);
		//画笔颜色为灰色
		paint.setColor(Color.parseColor("#D3D1D1"));
		// 去锯齿
		paint.setAntiAlias(true);
		//设置笔的颜色
		paint.setStrokeWidth(2);
		//设置开关圆圈的x轴位置
		swithShilerX = -3;
    }

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//canvas.drawColor(Color.WHITE);
		//绘制开关的按钮
		//绘制一个圆角的矩形,根据开关的大小进行绘制
		RectF re3 = new RectF(0,0, swithWidth*2 - baseWidth, swithWidth - baseHeight);
		canvas.drawRoundRect(re3, swithWidth/2, swithWidth/2, paint);
		//在绘制一个控制按钮的图片,x轴为-3,是要让他向x轴的左侧移动一点
		canvas.drawBitmap(swithSilder,swithShilerX, 0, null);
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		//设置控件的大小为开关圆圈的大小,必须设置,不然没有办法计算当前组件的时间大小
		setMeasuredDimension(swithWidth*2 - baseWidth, swithWidth);
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		 switch (event.getAction()) {
	        case MotionEvent.ACTION_UP: // 手指抬起
	        	currentState = (currentState == true) ? false : true;
	        	//Log.i("Switch", currentState+"");
	        	if(currentState){
	        		//设置所绘制矩形的状态
	        		paint.setStyle(Paint.Style.FILL);  //填充
	        		paint.setColor(Color.GREEN); //绿色
	        		//设置开关圆圈的位置
	        		swithShilerX = swithWidth - baseHeight - 3;
	        	}else{
	        		paint.setStyle(Paint.Style.STROKE); //不填充
	        		paint.setColor(Color.parseColor("#D3D1D1")); //灰色
	        		swithShilerX = -3;
	        	}
	        	//调用回调方法,传递当前的状态
	        	mListener.onToggleStateChange(currentState);
	            break;
        }
        invalidate(); // 刷新控件,该方法会调用onDraw(Canvas canvas)方法
        return true; // 自己处理事件,不让父类负责消耗事件  

	} 

    /**
     * 对外设置监听方法
     * @param listener
     */
    public void setOnToggleStateChangeListener(OnToggleStateChangeListener listener) {
        this.mListener = listener;
    }  

	//用于进行设置当开关的状态发生改变是同时上层调用这进行的处理操作
	public interface OnToggleStateChangeListener{
		 /**
	     * 当开关状态改变回调此方法
	     *  当前开关的最新状态
	     */
		 void onToggleStateChange(boolean b);
	}

}

关键点:

1. 我们在自定义view的时候,使用的坐标都是我们当前的view视图的,不是相对于整个屏幕的

2. 绘制自定义view关键点就是绘制(onDraw)和确定控件的大小(onMeasure)

通过上面的代码我的自定义控件就建立了,然后就可以在界面中使用,这里要注意的是我们在activity要对该控件设置回调事件,具体使用方式:

<com.example.widget.SwitchbuttonView
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:id="@+id/am_sbv"
	    />
private SwitchbuttonView am_sbv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		am_sbv = (SwitchbuttonView) findViewById(R.id.am_sbv);
		//为开关控件设置点击的回调事件
		am_sbv.setOnToggleStateChangeListener(new OnToggleStateChangeListener(){

			@Override
			public void onToggleStateChange(boolean b) {
				if(b){
					Log.i("State", b+",开");
				}else{
					Log.i("State", b+",关");
				}
			}

		});
	}

ok,这样一个自定义的开关空间就完成了,同志们如果有问题可以提出来,讨论一下

源码下载

欢迎转载。。。。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 06:17:55

android自定义开关控件的相关文章

小米3系统计算器自定义开关控件-MySwitchView

1.前言 在android4.0以后,有switch控件,类似于iPhone上面滑块的效果,但是只能用在4.0以后的系统中,之前的平台,就无法使用这种控件.近段时间,看到了小米3手机上自带的计算器app,有这样的效果,上面的一个控件,觉得很漂亮,并且与iPhone上的效果略有不同,于是自己动手编写了一下这个功能,在编写的过程中,参考过网上的一些demo,运行后,在控件滑动的时候,感觉动画不平滑,有卡顿的现象,反复修改,最后还是有一些问题,感觉是在滑动中的状态,没有合理的控制好.无奈只能参考Goo

Android 自定义组合控件小结

引言 接触Android UI开发的这段时间以来,对自定义组合控件有了一定的了解,为此小结一下,本文小结内容主要讨论的是如何使用Android SDK提供的布局和控件组成一个功能完整组合控件并将其封装为面向对象的类,而并非讨论如何继承自SDK提供的控件类(比如TextView),对其进行自定义扩展的问题. 进入正题前,我们先来看一组功能需求 假设在手机需求上,那么如上三个界面我们可以使用三个Activity,每个Activity一个布局文件,实现起来比较独立,但是假设在Android pad上要

Android自定义用户控件简单范例(一)

一款优秀的移动应用需要具有自己独特统一的风格,通常情况下UI设计师会根据产品需求和使用人群的特点,设计整体的风格,界面的元素和控件的互效果.而原生态的Android控件为开发人员提供的是最基本的积木元素,如果要准确地传递统一的视觉效果和交互体验,对控件的自定义使用是非常有必要的. 这篇文章通过一个简单的从Java后台程序中进行创建的示例来说明Android自定义控件的运行原理. <LinearLayout xmlns:android="http://schemas.android.com/

Android自定义用户控件简单范例(二)

对于完全由后台定制的控件,并不是很方便其他人的使用,因为我们常常需要看到控件放到xml界面上的效果,并根据效果进行布局的调整,这就需要一个更加标准的控件制作流程: 我们的自定义控件和其他的控件一样,应该写成一个类,而这个类的属性是是有自己来决定的. 我们要在res/values目录下建立一个attrs.xml的文件,并在此文件中增加对控件的属性的定义. 使用AttributeSet来完成控件类的构造函数,并在构造函数中将自定义控件类中变量与attrs.xml中的属性连接起来. 在自定义控件类中使

Android自定义组合控件--底部多按钮切换

效果图: 现在市场上大多数软件都是类似于上面的结构,底部有几个按钮用于切换到不同的界面.基于OOP思想,我想把下面的一整块布局封装成一个类,也就是我们的自定义组合控件-底部多按钮切换布局,我把它叫做BottomLayout 看上面的布局,几个按钮横向排列,我们先看一下布局 最外面LinearLayout 方向 horizontal,然后5个weight相同的RelativeLayout,每个RelativeLayout里面有一个Button(用了显示选中状态)个ImageView(用来显示红点)

android自定义倒计时控件示例

这篇文章主要介绍了Android秒杀倒计时自定义TextView示例,大家参考使用吧 自定义TextView控件TimeTextView代码: 复制代码 代码如下: import android.content.Context;import android.content.res.TypedArray;import android.graphics.Paint;import android.text.Html;import android.util.AttributeSet;import and

android 自定义组合控件

自定义控件是一些android程序员感觉很难攻破的难点,起码对我来说是这样的,但是我们可以在网上找一些好的博客关于自定义控件好好拿过来学习研究下,多练,多写点也能找到感觉,把一些原理弄懂,今天就讲下自定义组合控件,这个特别适合在标题栏或者设置界面,看下面图: 就非常适合使用组合控件了,现在写一个玩玩: activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

Android自定义组合控件--图片加文字,类似视频播放软件的列表

分四步来写: 1,组合控件的xml; 2,自定义组合控件的属性; 3,自定义继承组合布局的class类,实现带两参数的构造器; 4,在xml中展示组合控件. 具体实现过程: 一.组合控件的xml 我接触的有两种方式,一种是普通的Activity的xml:一种是父节点为merge的xml.我项目中用的是第一种,但个人感觉第二种好,因为第一种多了相对或者绝对布局层. 我写的 custom_pictext.xml <?xml version="1.0" encoding="u

Android自定义UI控件(简单方便版,但不灵活)

这种方法的优点就是简单,容易理解,适合开发一些不经常用到的自定义UI控件 缺点就是比较不灵活,如果其他应用想使用这个控件的话得改很多 简单来说,这个方法是用来做成品的,下一篇的方法是用来做模板的. 先看成品,这是一个标题栏控件: 由左右两个按钮和中一个TextView组成: 实现方法: 第一步:定义一个xml文件,用来设计你自定义控件的雏形 示例代码:文件名为title 1 <?xml version="1.0" encoding="utf-8"?> 2