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

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

先上图:

 

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

分析:

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

直接上代码:

  1. package com.example.widget;
  2.  
  3. import com.example.switchbutton_master.R;
  4.  
  5. import android.content.Context;
  6. import android.graphics.Bitmap;
  7. import android.graphics.BitmapFactory;
  8. import android.graphics.Canvas;
  9. import android.graphics.Color;
  10. import android.graphics.Paint;
  11. import android.graphics.RectF;
  12. import android.util.AttributeSet;
  13. import android.util.Log;
  14. import android.view.MotionEvent;
  15. import android.view.View;
  16. import android.widget.Toast;
  17.  
  18. //自己定义开关控件
  19. public class SwitchbuttonView extends View{
  20. //开关圆圈的按钮
  21. private Bitmap swithSilder;
  22. //获取的开关圆圈的宽度
  23. private int swithWidth;
  24. //开关圆圈在x轴上的位置
  25. private int swithShilerX;
  26.  
  27. //在轻微调整大小的长度
  28. private int baseHeight;
  29. private int baseWidth;
  30. //开关控件当前的状态,true:开,false:关
  31. private Boolean currentState = false;
  32. //画笔
  33. private Paint paint;
  34.  
  35. /** 开关状态改变监听 */
  36. private OnToggleStateChangeListener mListener;
  37.  
  38. public SwitchbuttonView(Context context, AttributeSet attrs) {
  39. super(context, attrs);
  40. initBitmap();
  41. }
  42.  
  43. private void initBitmap() {
  44. swithSilder = BitmapFactory.decodeResource(getResources(), R.drawable.swich_slider_new);
  45. swithWidth = swithSilder.getWidth();
  46. baseHeight = swithWidth / 10;
  47. baseWidth = swithWidth / 5;
  48.  
  49. paint = new Paint();
  50. //初始画笔的样式没不填充
  51. paint.setStyle(Paint.Style.STROKE);
  52. //画笔颜色为灰色
  53. paint.setColor(Color.parseColor("#D3D1D1"));
  54. // 去锯齿
  55. paint.setAntiAlias(true);
  56. //设置笔的颜色
  57. paint.setStrokeWidth(2);
  58. //设置开关圆圈的x轴位置
  59. swithShilerX = -3;
  60. }
  61.  
  62. @Override
  63. protected void onDraw(Canvas canvas) {
  64. super.onDraw(canvas);
  65. //canvas.drawColor(Color.WHITE);
  66. //绘制开关的按钮
  67. //绘制一个圆角的矩形,依据开关的大小进行绘制
  68. RectF re3 = new RectF(0,0, swithWidth*2 - baseWidth, swithWidth - baseHeight);
  69. canvas.drawRoundRect(re3, swithWidth/2, swithWidth/2, paint);
  70. //在绘制一个控制按钮的图片,x轴为-3,是要让他向x轴的左側移动一点
  71. canvas.drawBitmap(swithSilder,swithShilerX, 0, null);
  72. }
  73. @Override
  74. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  75. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  76. //设置控件的大小为开关圆圈的大小,必须设置。不然没有办法计算当前组件的时间大小
  77. setMeasuredDimension(swithWidth*2 - baseWidth, swithWidth);
  78. }
  79. @Override
  80. public boolean onTouchEvent(MotionEvent event) {
  81. switch (event.getAction()) {
  82. case MotionEvent.ACTION_UP: // 手指抬起
  83. currentState = (currentState == true) ?
  84.  
  85. false : true;
  86. //Log.i("Switch", currentState+"");
  87. if(currentState){
  88. //设置所绘制矩形的状态
  89. paint.setStyle(Paint.Style.FILL); //填充
  90. paint.setColor(Color.GREEN); //绿色
  91. //设置开关圆圈的位置
  92. swithShilerX = swithWidth - baseHeight - 3;
  93. }else{
  94. paint.setStyle(Paint.Style.STROKE); //不填充
  95. paint.setColor(Color.parseColor("#D3D1D1")); //灰色
  96. swithShilerX = -3;
  97. }
  98. //调用回调方法,传递当前的状态
  99. mListener.onToggleStateChange(currentState);
  100. break;
  101. }
  102. invalidate(); // 刷新控件,该方法会调用onDraw(Canvas canvas)方法
  103. return true; // 自己处理事件,不让父类负责消耗事件
  104.  
  105. }
  106.  
  107. /**
  108. * 对外设置监听方法
  109. * @param listener
  110. */
  111. public void setOnToggleStateChangeListener(OnToggleStateChangeListener listener) {
  112. this.mListener = listener;
  113. }
  114.  
  115. //用于进行设置当开关的状态发生改变是同一时候上层调用这进行的处理操作
  116. public interface OnToggleStateChangeListener{
  117. /**
  118. * 当开关状态改变回调此方法
  119. * 当前开关的最新状态
  120. */
  121. void onToggleStateChange(boolean b);
  122. }
  123.  
  124. }

关键点:

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

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

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

  1. <com.example.widget.SwitchbuttonView
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content"
  4. android:id="@+id/am_sbv"
  5. />
  1. private SwitchbuttonView am_sbv;
  2.  
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. am_sbv = (SwitchbuttonView) findViewById(R.id.am_sbv);
  8. //为开关控件设置点击的回调事件
  9. am_sbv.setOnToggleStateChangeListener(new OnToggleStateChangeListener(){
  10.  
  11. @Override
  12. public void onToggleStateChange(boolean b) {
  13. if(b){
  14. Log.i("State", b+",开");
  15. }else{
  16. Log.i("State", b+",关");
  17. }
  18. }
  19.  
  20. });
  21. }

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. 【转】OPC远程访问相关配置信息

    原文:http://blog.gkong.com/kking_25653.ashx 对于远程访问OPC服务器,需要在客户和服务器计算机上都进行DCOM设置,本文提供一些具体配置方法.(by Kevin ...

  2. hdu 4764 巴什博弈

    Stone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  3. Android单个按钮自定义Dialog

    代码改变世界 Android单个按钮自定义Dialog dialog_layout.xml <?xml version="1.0" encoding="utf-8& ...

  4. 【bzoj3489】A simple rmq problem 三维KD-tree

    题目描述 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会 ...

  5. 【bzoj3689】异或之 可持久化Trie树+堆

    题目描述 给定n个非负整数A[1], A[2], ……, A[n].对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n ...

  6. BZOJ 4033 [HAOI2015]树上染色 ——树形DP

    可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...

  7. BZOJ 1861 [Zjoi2006]Book 书架 ——Splay

    [题目分析] 模板题目. 首尾两个虚拟结点,十分方便操作. [代码] #include <cstdio> #include <cstring> #include <cma ...

  8. [TyvjP1519] 博彩游戏(AC自动机 + DP)

    传送门 和bzoj1030一个德性 #include <queue> #include <cstdio> #include <cstring> #define N ...

  9. Spoj-BOKAM143SOU Checking cubes.

    Given a integer N. Find number of possible ways to represent N as a sum of at most five cubes. Input ...

  10. Codeforces Round #269 (Div. 2) D - MUH and Cube Walls kmp

    D - MUH and Cube Walls Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & % ...