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

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

先上图:

 

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""> 

分析:

开关控件,中包括了两个部分,一个是一个圆,一个是圆角矩形,好了那我们仅仅要通过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,这样一个自己定义的开关空间就完毕了,同志们假设有问题能够提出来。讨论一下

源代码下载

欢迎转载。

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

  1. android 仿ios开关控件

    ios一些控件还是挺美丽的,可是对android程序猿来说可能比較苦逼,由于ios一些看起来简单的效果对android来说可能就没那么简单了,可是没办法非常多产品都是拿ios的一些控件叫android ...

  2. android 自己定义组合控件

    自己定义控件是一些android程序猿感觉非常难攻破的难点,起码对我来说是这种,可是我们能够在网上找一些好的博客关于自己定义控件好好拿过来学习研究下,多练,多写点也能找到感觉,把一些原理弄懂,今天就讲 ...

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

    1.前言             在android4.0以后,有switch控件.相似于iPhone上面滑块的效果.可是仅仅能用在4.0以后的系统中.之前的平台.就无法使用这种控件. 近段时间.看到了 ...

  4. android:自己定义组合控件Weight(高仿猫眼底部菜单条)

    在我们实际开发其中.会碰见一些布局结构类似或者同样的界面.比如应用的设置界面.tabbutton界面等. 这时候.对于刚開始学习的人来说,xml里面一个个绘制出来也许是最初的想法.可能随着经验的积累, ...

  5. Android 使用shape定义不同控件的的颜色、背景色、边框色

    Android 使用shape定义不同控件的的颜色.背景色.边框色 设置按钮的右边框和底边框颜色为红色,边框大小为3dp: 在drawable新建一个 buttonstyle.xml的文件,内容如下: ...

  6. Android常用酷炫控件(开源项目)github地址汇总

    转载一个很牛逼的控件收集帖... 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.Gri ...

  7. Android 常用炫酷控件(开源项目)git地址汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.P ...

  8. Android中通过WebView控件实现与JavaScript方法相互调用的地图应用

    在Android中通过WebView控件,可以实现要加载的页面与Android方法相互调用,我们要实现WebView中的addJavascriptInterface方法,这样html才能调用andro ...

  9. [Android学习笔记]组合控件的使用

    组合控件的使用 开发过程中,多个UI控件需要协同工作,相互交互之后,才可完成一个完整的业务需求,此时可把这些控件封装成为一个整体,相互之间的交互逻辑封装其中,外部调用可无需关心内部逻辑,只需获取处理后 ...

随机推荐

  1. NYOJ——239月老的难题(二分图最大匹配)

    月老的难题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一家, ...

  2. Java程序性能优化之缓冲优化

    优化前的代码: package com; import javax.swing.*; import java.awt.*; /** * 使用Eclipse,右键Run As,Java Applet运行 ...

  3. 【Tyvj1982】武器分配(费用流)

    题意:有N个人要从A个物品中各取一个,B个物品中各取一个,选取第i个A类物品和第j个B类物品的费用是(a[i]-b[j])^2 求最小总花费 n<=a,b<=80 a[i],b[i]< ...

  4. css3鼠标点击穿透--摘抄

    有些时候网页中用到了一些绝对定位的Div,因为需要事先这个Div是隐藏的,但是它所在的位置会遮挡住鼠标点击事件.这个时候可以用CCS3中的pointer-events属性来解决.   //穿透该层 p ...

  5. 集合-Vector

    Vector中的操作是线程安全的. public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCa ...

  6. Laravel5.1 报错:控制器不存在

    Laravel5.1 报错:控制器不存在 错误提示: Class App\Http\Controllers\Api/UserController does not exist 解决: (1)检查控制器 ...

  7. PHP输出控制函数(ob系列函数)

    PHP输出控制函数(ob系列函数) flush — 刷新输出缓冲ob_clean — 清空(擦掉)输出缓冲区ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲ob_end_flush — ...

  8. 在dedecms系统下, 改写火车头的入库接口 写一个接口文件运行一次自动读取 http://news.163.com/rank/

    1:火车头入库接口里面的密码与login.php传过来的密码是保持一致的: 2:在(!$ispost)里面编写一个form表单提交,验证用户名,channelid,以及typeid; html代码格式 ...

  9. Golang 入门 : 等待 goroutine 完成任务

    Goroutine 是 Golang 中非常有用的功能,但是在使用中我们经常碰到下面的场景:如果希望等待当前的 goroutine 执行完成,然后再接着往下执行,该怎么办?本文尝试介绍这类问题的解决方 ...

  10. luogu P3865 【模板】ST表

    题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为 NN 的数列,和 MM 次询 ...