自己定义控件是一些android程序猿感觉非常难攻破的难点,起码对我来说是这种,可是我们能够在网上找一些好的博客关于自己定义控件好好拿过来学习研究下,多练,多写点也能找到感觉,把一些原理弄懂,今天就讲下自己定义组合控件,这个特别适合在标题栏或者设置界面,看以下图:

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

就很适合使用组合控件了,如今写一个玩玩:

activity_main.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:hy="http://schemas.android.com/apk/res/com.example.customcircle"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. >
  8. <com.example.customcircle.SettingView
  9. android:id="@+id/sv1"
  10. android:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. hy:title = "标题1"
  13. hy:content = "内容1"
  14. ></com.example.customcircle.SettingView>
  15. <com.example.customcircle.SettingView
  16. android:id="@+id/sv2"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. hy:title = "标题2"
  20. hy:content = "内容2"
  21. ></com.example.customcircle.SettingView>
  22. <com.example.customcircle.SettingView
  23. android:id="@+id/sv3"
  24. android:layout_width="fill_parent"
  25. android:layout_height="wrap_content"
  26. hy:title = "标题3"
  27. hy:content = "内容3"
  28. ></com.example.customcircle.SettingView>
  29. </LinearLayout>
  1. SettingView.java
  1. public class SettingView extends RelativeLayout {
  2. private TextView title;
  3. private TextView content;
  4.  
  5. public SettingView(Context context, AttributeSet attrs, int defStyle) {
  6. super(context, attrs, defStyle);
  7. initView(context);
  8. }
  9.  
  10. public SettingView(Context context, AttributeSet attrs) {
  11. super(context, attrs);
  12. initView(context);
  13. /**
  14. * 获取一个样式的属性集
  15. * 把布局文件xml中的获取到的样式集合attrs跟自己自己定义的样式集合建立一个映射关系
  16. */
  17. TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SettingView);
  18. String title = a.getString(0);
  19. String content = a.getString(1);
  20. //设置到界面上
  21. setTitle(title);
  22. setContent(content);
  23. a.recycle();
  24. }
  25.  
  26. public SettingView(Context context) {
  27. super(context);
  28. initView(context);
  29. }
  30.  
  31. private View initView(Context context){
  32. View view = View.inflate(context, R.layout.setting_view, this);
  33. title = (TextView) view.findViewById(R.id.title);
  34. content = (TextView) view.findViewById(R.id.content);
  35. return view;
  36. }
  37.  
  38. public void setTitle(String tilte){
  39. title.setText(tilte);
  40. }
  41. public void setContent(String strContent){
  42. content.setText(strContent);
  43. }
  44. public void setTextSize(int size){
  45. content.setTextSize(size);
  46. title.setTextSize(size);
  47. }
  48. }

setting_view.xml

<?

xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="vertical" 

    android:background="#22000000"

    >

    

   <RelativeLayout 

   android:layout_width="fill_parent"

   android:layout_height="wrap_content"

   

   >

   <TextView

       android:id="@+id/title"

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:textSize="20sp"

       android:layout_marginTop="5dp"

       android:layout_marginLeft="5dp"

       />

   <TextView

       android:id="@+id/content"

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:textSize="16sp"

       android:layout_marginLeft="5dp"

       android:layout_below="@id/title"

       />

   <CheckBox 

       android:id="@+id/cb"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_alignParentRight="true"

       android:layout_centerVertical="true"

       />

  

</RelativeLayout>

<View 

       android:layout_width="fill_parent"

       android:layout_height="1px"

       android:background="#000000"

       android:layout_below="@id/cb"

       />

</LinearLayout>

我们发如今activity_main.xml中有二个属性

hy:title = "标题1"

hy:content = "内容1"

这个时候xml文件会报错

error: Error parsing XML: unbound prefix  说没有hy这种前缀,由于我们写android:什么属性  都是由于有xmlns:android ="http://schemas.android.com/apk/res/android"
这样一个命名空间在,
那我们也自己定义一个命名空间,仿照上面的写就是了
xmlns:hy ="http://schemas.android.com/apk/res/com.example.customcircle"//res后面的是你得包名

如今xml文件有报错了:
Multiple annotations found at this line:
 - error: No resource identifier found for attribute 'content' in package
 'com.example.customcircle'
说在我们的包下没有找到conent的定义


 hy:title = "标题"
   hy:content = "内容"
是我自己定义的属性
假设要使用自己定义的属性,就要把这些属性定义出来,而为什么系统的android:属性名---就能够呢?

那是由于android sdk已经声明好了,在找到我们使用的sdk

<declare-styleable name="TextAppearance">

        <!-- Text color. -->

        <attr name="textColor" />

        <!-- Size of the text. Recommended dimension type for text is "sp" for scaled-pixels (example: 15sp). -->

        <attr name="textSize" />

        <!-- Style (bold, italic, bolditalic) for the text. -->

        <attr name="textStyle" />

        <!-- Typeface (normal, sans, serif, monospace) for the text. -->

        <attr name="typeface" />

        <!-- Color of the text selection highlight. -->

        <attr name="textColorHighlight" />

        <!-- Color of the hint text. -->

        <attr name="textColorHint" />

        <!-- Color of the links. -->

        <attr name="textColorLink" />

    </declare-styleable>
这就是TextView中的属性,所以我们也要模仿他创建一个attrs文件在value文件夹下
 <declare-styleable name="TextAppearance">

declare-styleable  声明的意思 name表示 声明的控件名称
我们的  <declare-styleable name="SettingView">
     </declare-styleable >
当保存的时候就会在你R.java文件里生成了一个内部类
 public static final class attr
{//属性集
    }
然后声明属性
<attr name="title" format="string"></ attr>
<attr name="content" format="string" ></attr>
name表示属性的名称 format表示属性的类型

然后我们保存代码 就没错误提示了
然后再看R.java文件
 public static final class attr
{
        /** <p>Must
be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character.
<p>This may also be a reference
to a resource (in the form
"<code>@[ <i>package</i> :]<i>type </i>:<i> name</i></code>")
or
theme attribute (in the form
"<code>?[ <i>package</i> :][<i>type </i>:]<i> name</i></code>")
containing a value of this type.
         */
        public static final int content=0x7f010001;
        /** <p>Must
be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character.
<p>This may also be a reference
to a resource (in the form
"<code>@[ <i>package</i> :]<i>type </i>:<i> name</i></code>")
or
theme attribute (in the form
"<code>?[ <i>package</i> :][<i>type </i>:]<i> name</i></code>")
containing a value of this type.
         */
        public static final int title=0x7f010000;
    }
这个时候我们执行下我们的项目,发现这自己定义的属性并没有起作用,那意思就是说我们要用代码的方式让它显示出来

AttributeSet类表示属性的集合 在我们定义的属性
比方:
 android:id= "@+id/sv1"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  hy:title = "标题"
  hy:content = "内容"
相当于把这些属性封装成了一个类,这真是我们java强大之处,面向对象编程思想


然在构造函数中做这个操作


public SettingView(Context
context, AttributeSet attrs) {
          super(context,
attrs);
         initView(context);
          /**
          * 获取一个样式的属性集
          * 把布局文件 xml中的获取到的样式集合 attrs跟自己自己定义的样式集合建立一个映射关系
          */
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SettingView );
         String title = a.getString(0);
         String content = a.getString(1);
          //设置到界面上
         setTitle(title);
         setContent(content);
         a.recycle();
    }
这样就算成功了 

执行效果:

总结下自己定义组合控件的步骤:

1. 写一个类 继承  ViewGroup LinearLayout  RelativeLayout





2. 假设在布局文件中面定义view对象 使用这个view对象的两个參数的构造方法.





3. 定义这个自己定义控件里面要显示的内容

View.inflate(context, R.layout.ui_setting_view, this);





4. 加入自己定义控件的属性. 

    定义自己定义属性的命名空间





5. 声明自己定义的属性

    <declare-styleable name="SettingView">

        <attr name="title" format="string" />

        <attr name="desc_on" format="string" />

        <attr name="desc_off" format="string" />

    </declare-styleable>

   观察R文件 生成 attr内部类 生成styleable  数组 全部的attrs





6. 在xml布局文件中面配置  自己定义的属性.





7. 在自己定义view对象的构造方法里面 获取AttributeSet 

跟我们自己定义的属性建立映射关系





8. 在自己定义组合控件里面 设置 布局文件的数据, 扩展点击事件.





9. 在布局文件使用自己定义的view对象.

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

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

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

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

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

  3. android 自定义空间 组合控件中 TextView 不支持drawableLeft属性

    android 自定义空间 组合控件中 TextView 不支持drawableLeft属性.会报错Caused by: android.view.InflateException: Binary X ...

  4. Android Studio自定义组合控件

    在Android的开发中,为了能够服用代码,会把有一定共有特点的控件组合在一起定义成一个自定义组合控件. 本文就详细讲述这一过程.虽然这样的View的组合有一个粒度的问题.粒度太大了无法复用,粒度太小 ...

  5. Android中自定义组合控件

    Android中自定义控件的情况非常多,一般自定义控件可以分为两种:继承控件及组合控件.前者是通过继承View或其子类,重写方法实现自定义的显示及事件处理方式:后者是通过组合已有的控件,来实现结构的简 ...

  6. android自己定义开关控件

    近日在android项目要使用开关控件.可是android中自带的开关控件不太惬意,所以就打算通过自己定义View写一个开关控件 ios的开关控件当然就是我要仿照的目标. 先上图:   waterma ...

  7. Android自己定义View之组合控件 ---- LED数字时钟

    先上图 LEDView效果如图所看到的. 之前看到一篇博客使用两个TextView实现了该效果.于是我想用自己定义控件的方式实现一个LEDView.使用时就可以直接使用该控件. 採用组合控件的方式,将 ...

  8. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  9. 【转】android UI进阶之自定义组合控件

    [源地址]http://blog.csdn.net/notice520/article/details/6667827 好久没写博客了.实在是忙不过来,不过再不总结总结真的不行了.慢慢来吧,有好多需要 ...

随机推荐

  1. CentOS 6.9/7通过yum安装指定版本的Nginx

    说明:通过yum好处其实很多,环境变量不用配置,配置文件放在大家都熟悉的地方,通过rpm -ql nginx可以知道全部文件的地方等等. Nginx(1.12.2) 一.安装和配置 1.安装 # rp ...

  2. Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行

    Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行 Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执 ...

  3. Jacob调用COM组件总结,实例

    转自:http://blog.csdn.net/whw6_faye/article/details/5418506 最近做了一个Java Jacob调用COM组件的东西,其中遇到了不少问题,现在把经验 ...

  4. IIS7 win7 x64 MVC部署

    .net4.5已经装好,mvc4setup也装了,启动IIS后打开网页还是不能正常显示页面,404错误 最后发现把win7升级到SP1就正常了,具体是那个补丁修复的就不知道了

  5. jenkins报:反向代理设置有误

    1.如图所示: 2.点击更多信息,查看解决办法: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+s ...

  6. EF Power Tools使用介绍

            EF Power Tools可以从数据库反向生成实体及映射文件.一般在使用EF,有Database First,Code First以及Model First.常用的是Database ...

  7. Shell编程(脚本)的经常使用命令和语句

    一些经常使用的Shell编程(脚本)命令和语句,能够满足一般需求. 接收到的命令參数: 參数个数: $# 參数值: 命令本身:$0 第一个參数:$1 第二个參数:$2 -- 退出命令: exit ec ...

  8. iOS:UIApplication和它对象的代理

    <1>UIApplication的对象是单例对象   类方法:UIApplication *app = [UIApplication sharedAppplication] <2&g ...

  9. go语言基础之普通函数的调用流程

    函数调用流程:先调用后返回,先进后出,函数递归,函数调用自己本分,利用此物点 1.普通函数的调用流程 package main //必须 import "fmt" func fun ...

  10. GameObjectPool——Unity中的对象池

    这里介绍一种对象池的写法.它的优点在于无论取出还是插入游戏物体都是常数量时间. using UnityEngine; using System.Collections; using System.Co ...