尊重他人劳动成果,转载请注明出处。

转自:http://kandy0619.blog.163.com/blog/static/64344345201012325939280/

  可能是一直都在做Web的富客户端开发的缘故吧,在接触Android之后,发现其控件实在惨不忍睹(不知道是否说得过于偏激),我所说的惨不忍睹的意思不是说控件难看,Android的控件非常漂亮,这是我们公司公认的,但是最大的缺点在于控件功能非常弱小。弱小得一个Radio只能放一个text,而没有value(key)可以存放。这就是为什么我说惨不忍睹的原因。

但是这不能怪google,毕竟才刚刚发展起来,Android提供的只是一个最基本的控件实现,而非一个完整、强大的实现。可幸的是,Android提供了自定义控件的实现。有了自定义控件,我们就可以再Android的基础控件上实现我们想要的功能了。经过一天的摸索,我终于实现了我第一个自定义的组合控件——RadioButton组合RadioGroup!

下面我将带领大家进入Android自定义控件的世界。如果觉得我的文章能够帮助大家的话,请大方留下你的一些话语。因为你们的留言是我分享经验的精神源泉!谢谢!

1、设置自定义控件:Android自带的RadioButton只能存放text,这不符合我们的需求,我们需要一个可以同时存放key-value对应的键值。所以我们要编写一个自定义控件能存放key-value。

设计思路:新建一个类叫org.kandy.view.RadioButton,继承自android.wedget.RadioButton,重写父类的所有构造方法。这样我们就实现了一个跟父类一摸一样的控件。在此基础上加入我们需要的功能:加入一个属性value,用来存放RadioButton的key。

代码如下:

 1 public class RadioButton extends android.widget.RadioButton { 2  3  private String mValue; 4  5  public RadioButton(Context context, AttributeSet attrs, int defStyle) { 6   super(context, attrs, defStyle); 7  } 8   9  public String getValue() {10   return this.mValue;11  }12 13  public void setValue(String value) {14   this.mValue = value;15  }16  public RadioButton(Context context, AttributeSet attrs) {17   super(context, attrs);18   try {19    /**20     * 跟values/attrs.xml里面定义的属性绑定21 */22    TypedArray a = context.obtainStyledAttributes(attrs,23                  R.styleable.RadioButton);24    this.mValue = a.getString(R.styleable.RadioButton_value);25    a.recycle();26   } catch (Exception e) {27    e.printStackTrace();28   }29   30  }31 32  public RadioButton(Context context) {33   super(context);34  }35 36 }

红色代码可以先不看。先看我们新加入的属性value,由于Android习惯属性命名以m开头。所以我们自定义控件就按照这个规则来写。不过对于setter、getter方法来说,不需要加入m。像上面的:属性名称mValue,setter:setValue(),getter:getValue()。当然,你也可以不按照Android的习惯来命名。

这样,我们就可以使用这个自定义控件了。而且可以给它设置一个value,加上父类的text属性。我们就可以在RadioButton中加入key-value的键值了。当然,这里面的key对应是控件的value属性,value是对应控件的text属性。完了?没有。自定义控件才刚开始了。

2、XML中引用自定义控件

在XML中加入自定义控件其实很简单。只需要在控件名字前加入包名即可。如下:

1  <org.kandy.view.RadioButton android:id="@id/isPayDepositTrue" fsms:value="true"2       android:layout_width="wrap_content" android:layout_height="wrap_content"3       android:text="@string/yes" android:textSize="18sp">4  </org.kandy.view.RadioButton>

同样,红色部分可以先不看,也不需要加入到代码中,这个时候加入会报错,请注意。

3、attrs.xml属性定义。

在我们的思想中,既然我在自定义控件中加入了一个新的属性,那么我就应该能够在xml中引用它,并对它赋初始值。我当初也是这样想的。可是却无从下手。就是这一点,折腾了我一个下午。

正解:res/values/attrs.xml中定义属性,在自定义控件中获取这个属性,然后跟自定义控件的属性相绑定。

attrs.xml如果没有,就新建一个。这里只存放自定义控件中需要的属性,在我看来,这个文件是一个中介,负责将layout/xx.xml里面的对这个变量的引用和自定义控件里面的属性绑定起来。

attrs.xml完整代码如下:

1  <?xml version="1.0" encoding="utf-8"?>2 <resources>3  <declare-styleable name="RadioButton"><!-- 控件名称-->4   <attr name="value" format="string"/><!-- 属性名称,类型-->5  </declare-styleable>6 </resources>

如果res下没有错误的话,在R中应该就会生成这些资源的id。这样我们就能在自定义控件中引用他们。

4、控件属性与XML定义绑定。

这下子我们又回到了自定义控件的编写上来了。先看看我们在第一点提到的红色字体部分。这一部分就是实现控件属性与XML定义绑定的代码。

1  /**2     * 跟values/attrs.xml里面定义的属性绑定3 */4    TypedArray a = context.obtainStyledAttributes(attrs,5                  R.styleable.RadioButton);6    this.mValue = a.getString(R.styleable.RadioButton_value);7    a.recycle();

TypedArray其实就是一个存放资源的Array,首先从上下文中获取到R.styleable.RadioButton这个属性资源的资源数组。attrs是构造函数传进来,应该就是对应attrs.xml文件。a.getString(R.styleable.RadioButton_value);这句代码就是获取attrs.xml中定义的属性,并将这个属性的值传给本控件的mValue.最后,返回一个绑定结束的信号给资源:a.recycle();绑定结束。

5、在xml中对控件赋初始值。

请看第2点,绑定结束后可以在需要赋初始值的地方赋值。

 1 <ScrollView android:layout_width="fill_parent" 2  android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" 3  xmlns:fsms=http://schemas.android.com/apk/res/org.kandy> 4  5 <org.kandy.view.RadioButton android:id="@id/isPayDepositTrue" fsms:value="true" 6       android:layout_width="wrap_content" android:layout_height="wrap_content" 7       android:text="@string/yes" android:textSize="18sp"> 8      </org.kandy.view.RadioButton> 9 10 </ScrollView>

红色部分首先声明命名空间。命名空间为fsms.路径是http://schemas.android.com/apk/res/这一部分是不变的,后面接的是R的路径:org.kandy.R。然后在自定义控件的xml描述中就可以这样使用fsms:value="true"。这样就实现了自定义控件的初始化赋值。

6、RadioGroup、RadioButton组合控件的实现

上面是自定义控件的实现,下面将要说的是组合控件的实现。在组合控件中,最经常用到的应该就是RadioGroup和RadioButton。RadioButton的实现已经在上面介绍了。下面要介绍RadioGroup的自定义控件和功能扩展:

代码如下:

 1  public class RadioGroup extends android.widget.RadioGroup { 2  3  private String mValue; 4   5  public RadioGroup(Context context, AttributeSet attrs) { 6   super(context, attrs); 7  } 8  9  public RadioGroup(Context context) {10   super(context);11  }12  // 设置子控件的值13  public void setChildValue(){14   int n = this.getChildCount();15   for(int i=0;i<n;i++){16    final RadioButton radio = (RadioButton)this.getChildAt(i);17    if(radio.getValue().equals(this.mValue)){18     radio.setChecked(true);19    }else{20     radio.setChecked(false);21    }22   }23  }24  // 获取子类的值25  public void getChildValue(){26   int n = this.getChildCount();27   for(int i=0;i<n;i++){28    RadioButton radio = (RadioButton)this.getChildAt(i);29    if(radio.isChecked()){30     this.mValue=radio.getValue();31    }32   }33  }34  35  public void setValue(String value) {36   this.mValue = value;37   setChildValue();38  }39  40  public String getValue(){41   getChildValue();42   return this.mValue;43  }44 }

RadioGroup只做两件事:获取子控件(RadioButton)所选择的值;设置子控件要选择的值。

方法非常简单,循环或者RadioGroup的子控件,检测哪个控件被checked,然后getValue,将此value赋值给RadioGroup的扩展属性value。在这里不多说了。相信大家都能看懂。

转载于:https://www.cnblogs.com/nanhuchongzi/archive/2012/03/29/2422914.html

Android.自定义控件的实现 (转载)相关推荐

  1. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  2. Android自定义控件三部曲

    Android自定义控件 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)--alpha.scale.translate.rotate.set的xml属性及用法> 2.& ...

  3. Android自定义控件系列八:详解onMeasure()(二)--利用onMeasure测量来实现图片拉伸永不变形,解决屏幕适配问题

    上一篇文章详细讲解了一下onMeasure/measure方法在Android自定义控件时的原理和作用,参看博文:Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸( ...

  4. [置顶] Android自定义控件 芝麻信用分雷达图

    [置顶] Android自定义控件 芝麻信用分雷达图 标签: android自定义雷达芝麻信用 2016-10-23 20:11  3548人阅读  评论(24)  收藏  举报   分类: 自定义控 ...

  5. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  6. android里的editText怎么用,Android自定义控件EditText使用详解

    本文实例为大家分享了Android自定义控件EditText的具体代码,供大家参考,具体内容如下 自定义控件分三种: 1. 自绘控件 2. 组合控件 3. 继承控件 代码已上传到 github 以后的 ...

  7. android汽车之家顶部滑动菜单,Android自定义控件之仿汽车之家下拉刷新

    关于下拉刷新的实现原理我在上篇文章Android自定义控件之仿美团下拉刷新中已经详细介绍过了,这篇文章主要介绍表盘的动画实现原理 汽车之家的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull ...

  8. Android 自定义控件打造史上最简单的侧滑菜单

    侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin ...

  9. Android绘制自定义控件,Android自定义控件绘制基本图形基础入门

    本文讲述绘制android自定义各种图形效果,为自定义控件的入门篇 相关视频链接: android自定义控件系列 android视频全系列 绘制点–这个控件只需要在布局中引用或者代码中new 即可,下 ...

最新文章

  1. tensorflow中的BN层实现
  2. 遇到 400、500 错误千万不要慌!
  3. Android Studio 单刷《第一行代码》系列 05 —— Fragment 基础
  4. mysql残余文件的清理
  5. ios::sync_with_stdio(false)的作用
  6. Java使用递归实现全排列的代码
  7. win上部署基于openvino2020.2的yolov5算法
  8. Golang错误和异常处理的正确姿势
  9. springBoot跨域注解@CrossOrigin
  10. Javascript特效:获取选中内容分享至微博
  11. VMware15.5.2安装unlocker时下载工具一直失败
  12. 西门子plc选型分析
  13. 教你如何写Bug:Google Guava源码分析之——Joiner
  14. 【视频】离职创业感悟
  15. 盘点:上海十处最具情调的小资地!(组图)
  16. 制造业原材料价格上涨 安防设备涨还是不涨?
  17. vue created钩子使用后台数据赋值给data里的变量,报错‘undefined’
  18. IMU预积分的简单理解
  19. 2020年总结与展望
  20. 有写字好看的人给点实用性技巧吗?

热门文章

  1. c++实现顺序表的相关操作
  2. ubuntu下搭建nfs服务器
  3. 【计算机系统设计】实践笔记(2)插叙:综合与实现
  4. 函数sigsuspend
  5. 函数read、write、lseek
  6. 网易严选Java开发三面面经:mysql索引面试题
  7. 列表,元组,字典类的常见简单方法
  8. 05精益敏捷项目管理——超越Scrum
  9. [Luogu1890]gcd区间
  10. 【Java基础】List迭代并修改时出现的ConcurrentModificationException问题