`
renyuan_1991
  • 浏览: 69500 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自定义组合控件的总结

阅读更多
自定义组合控件的总结
转载请注明出处:http://renyuan-1991.iteye.com/blog/2306381
第一步:在Values中添加attrs.xml文件,首先搞清楚attts.xml怎么用,下面是一个完整的属性文件。控件的属性其实就为给我们提供某些信息的,我们在区分这个属性的时候不需要去想它能干什么,只要知道它能带来什么就行。比如format为string类型的属性,我们只要知道这个属性能为我们提供string类型的字符串就行,用来干什么依个人喜好而定。
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GeneralTitle">
        <!-- 该属性用来获取String信息 -->
        <attr name="name" format="string"/>
        <!-- 提供资源文件的引用,如:@drawable/图片ID -->
        <attr name="name" format="reference"/>
        <!-- 提供颜色值 如:#00FF00-->
        <attr name="name" format="color"/>
        <!-- 提供一个boolean值 如:true -->
        <attr name="name" format="boolean"/>
        <!-- 提供一个尺寸值 如:42dip -->
        <attr name="name" format="dimension"/>
        <!-- 提供一个浮点类型的数值 如:2.2 -->
        <attr name="name" format="float"/>
        <!-- 提供一个整数类型的数值 如:2 -->
        <attr name="name" format="integer"/>
        <!-- 提供一个百分比 如:100% -->
        <attr name="name" format="fraction"/>
        <!-- 枚举值的定义 -->
        <attr name="orientation">
            <enum name="horizontal" value="0" />
            <enum name="vertical" value="1" />
        </attr>
        <!-- 位或运算(这个从来没用过...) -->
        <attr name="windowSoftInputMode">
            <flag name = "stateUnspecified" value = "0" />
            <flag name = "stateUnchanged" value = "1" />
            <flag name = "stateHidden" value = "2" />
            <flag name = "stateAlwaysHidden" value = "3" />
            <flag name = "stateVisible" value = "4" />
            <flag name = "stateAlwaysVisible" value = "5" />
            <flag name = "adjustUnspecified" value = "0x00" />
            <flag name = "adjustResize" value = "0x10" />
            <flag name = "adjustPan" value = "0x20" />
            <flag name = "adjustNothing" value = "0x30" />
        </attr>
    </declare-styleable>
</resources>

在定义Activity的属性时会用到位或运算这个属性,如:
android:windowSoftInputMode = "stateUnspecified | stateUnchanged | stateHidden"

这样做的好处就是减少数据传输,只需要传递一个int值就ok啦。
属性定义时是可以指定多种类型值的,如:
<attr name = "background" format = "reference|color" />

使用:
android:background = "@drawable/图片ID|#00FF00"

第二步:自定义控件的实现
自定义的空间一般都有三个构造函数,这三个构造函数是有一些区别的:
一个参数的构造函数:
    在Code中实例化一个View时调用。
两个参数的构造函数:
    在xml中定义时调用。
三个参数的构造函数:
    一般情况下我们需要显示调用并传入style.默认的Style是指它在当前Application或Activity所用的Theme中的默认Style。

接下来就要往我们这个布局里面添加内容了,比如说这个布局是一个RelativieLaoyut,我们可以通过
LayoutInflater.from(context).inflate(R.layout.imagebtn_with_text, this, true)
这行代码直接从xml中读取一个布局,但是这样会让布局的嵌套又多了一层,因为inflate这个函数的第二个参数就是当前布局,这样就是把xml文件读取的布局添加到我们这个自定义布局中。我们可以通过自己创建控件通过addView()方法生成组合控件。
    首先读取自定义的属性,如下:
//读取属性集合
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.GeneralTitle);
//然后从该属性集合中取出自定义属性,如果在xml没有添加对应的属性这里获取的就是null,我们也可以通过这个值来判断是不是要生成对应的控件。
CharSequence title= ta.getText(R.styleable.GeneralTitle_title_text);
        int textColor = ta.getColor(R.styleable.GeneralTitle_title_textcolor,0xffffff);
        float textSize = ta.getDimension(R.styleable.GeneralTitle_title_textsize,18);
        Drawable leftPic = ta.getDrawable(R.styleable.GeneralTitle_title_left_pic);
        Drawable rightPic = ta.getDrawable(R.styleable.GeneralTitle_title_right_pic);
        float picWidth = ta.getDimension(R.styleable.GeneralTitle_title_pic_width,0);
        float title_leftpic_verticalpadding = ta.getDimension(R.styleable.GeneralTitle_title_leftpic_verticalpadding,0);
        float title_leftpic_horizontalpadding = ta.getDimension(R.styleable.GeneralTitle_title_leftpic_horizontalpadding,0);
        float title_rightpic_verticalpadding = ta.getDimension(R.styleable.GeneralTitle_title_rightpic_verticalpadding,0);
        float title_rightpic_horizontalpadding = ta.getDimension(R.styleable.GeneralTitle_title_rightpic_horizontalpadding,0);
        float title_leftpic_leftmagin = ta.getDimension(R.styleable.GeneralTitle_title_leftpic_leftmagin,0);
        float title_rightpic_rightmagin = ta.getDimension(R.styleable.GeneralTitle_title_rightpic_rightmagin,0);
ta.recycle();//属性拿到后一定要记得释放。
        if(null != title) {
            //标题
            TextView text_title = new TextView(context);
            text_title.setText(title);
            text_title.setTextColor(textColor);
            text_title.setTextSize(TypedValue.COMPLEX_UNIT_PX,textSize);
            LayoutParams ttp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            ttp.addRule(CENTER_IN_PARENT);
            this.addView(text_title, ttp);
        }
        if (null != leftPic){
            //左边的图片
            ImageView imageview_left = new ImageView(context);
            imageview_left.setImageDrawable(leftPic);
            imageview_left.setPadding((int) title_leftpic_horizontalpadding, (int)title_leftpic_verticalpadding,(int)title_leftpic_horizontalpadding, (int)title_leftpic_verticalpadding);
            LayoutParams ilp = new LayoutParams((int) picWidth, ViewGroup.LayoutParams.MATCH_PARENT);
            ilp.addRule(ALIGN_PARENT_LEFT);
            ilp.addRule(CENTER_VERTICAL);
            ilp.setMargins((int) title_leftpic_leftmagin,0,0,0);
            imageview_left.setOnClickListener(this);
            imageview_left.setTag("investor_title_imageview_left");
            this.addView(imageview_left, ilp);
        }
        if(null != rightPic) {
            //右边的图片
            ImageView Imageview_right = new ImageView(context);
            Imageview_right.setImageDrawable(rightPic);
            Imageview_right.setPadding((int)title_rightpic_horizontalpadding,(int)title_rightpic_verticalpadding,(int)title_rightpic_horizontalpadding,(int)title_rightpic_verticalpadding);
            LayoutParams irp = new LayoutParams((int)picWidth, ViewGroup.LayoutParams.MATCH_PARENT);
            irp.addRule(ALIGN_PARENT_RIGHT);
            irp.addRule(CENTER_VERTICAL);
            irp.setMargins(0,0, (int) title_rightpic_rightmagin,0);
            Imageview_right.setOnClickListener(this);
            Imageview_right.setTag("investor_title_imageview_right");
            this.addView(Imageview_right, irp);
        }

具体的案例详见:GeneralTitle --> http://git.oschina.net/renyuan_1991/MyWidget
获取属性我们也可以利用循环语句,TextView的源码里就是这样写的,如下:
int resourceId = -1;
     TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageView);
     ImageView iv = new ImageView(context);
     TextView tv = new TextView(context);
     int N = typeArray.getIndexCount();
     for(int i = 0 ;i<N;i++){
          int attr = typeArray.getIndex(i);
          switch (attr) {
               case R.styleable.MyImageView_Oriental:
                   resourceId = typeArray.getInt(R.styleable.MyImageView_Oriental, 0);
                    //
                    this.setOrientation(resourceId == 1 ? LinearLayout.HORIZONTAL :                     LinearLayout.VERTICAL);
               break;
               case R.styleable.MyImageView_Text:
               //获取资源,第二个参数是默认值
                   resourceId = typeArray.getResourceId(R.styleable.MyImageView_Text, 0);
                    //通过判断资源id是否存在,如果是存在说明在定义的时候定义的是字符串的资源id这里就通过资源id拿到字符,如果不是资源id就直接的到定义时的字符串
                   tv.setText(resourceId>0?                         typeArray.getResources().getText(resourceId):typeArray.getString(R.styleable.MyImageView_Text));
               break;
               case R.styleable.MyImageView_Src:
                   resourceId = typeArray.getResourceId(R.styleable.MyImageView_Src, 0);
                   //拿到资源id 如果有就设置给图片,如果没有就直接显示系统的图标
                   iv.setImageResource(resourceId>0?resourceId:R.drawable.ic_launcher);
               break;
         }
}
addView(iv);
addView(tv);
typeArray.recycle();//最后要清空属性集合

属性定义如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="MyImageView">
        <attr name="Text" format="reference|string"></attr>
        <!-- 枚举的没有format 在使用的时候也只能使用这两个属性 在自定义的时候不用指定枚举的名字,获取这个attr的名字就能拿到xml设置的属性 -->
        <attr name="Oriental">
            <enum name="Horizontal" value="1"></enum>
            <enum name="Vertical" value="0"></enum>
        </attr>
        <attr name="Src" format="reference|integer"></attr>
    </declare-styleable>

</resources>

这个例子并没有涉及到view得测量,布局,绘制这个三个必经的流程,如果想看怎么利用这几个方法创建完全自定义的view请看前一篇博客:http://renyuan-1991.iteye.com/blog/2232463
转载请注明出处:http://renyuan-1991.iteye.com/blog/2306381
希望爱好编程的小伙伴能加这个群,互相帮助,共同学习。群号: 141877583
0
0
分享到:
评论

相关推荐

    在Android开发中使用自定义组合控件的例子

    主要介绍了在Android开发中使用自定义组合控件的例子,作者根据例子总结到了实现父类的构造方法等基本要点,具有一定参考价值,需要的朋友可以参考下

    Android自定义View的三种实现方式总结

    总结来说,自定义控件的实现有三种方式,分别是:组合控件、自绘控件和继承控件。下面将分别对这三种方式进行介绍。 (一)组合控件 组合控件,顾名思义就是将一些小的控件组合起来形成一个新的控件,这些小的控件多...

    庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术

    6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对动态添加控件的视图状态分析 228 6.8 自定义类型转换器实现高效率序列化 231 6.9 页面状态性能优化策略 238 ...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part1

    6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对动态添加控件的视图状态分析 228 6.8 自定义类型转换器实现高效率序列化 231 6.9 页面状态性能优化策略 238 ...

    庖丁解牛 纵向切入ASP.NET 3.5控件和组件开发 part2

    6.4.3 视图状态和控件状态组合使用规则 225 6.5 加密页面状态 225 6.6 清除页面状态 226 6.7 对动态添加控件的视图状态分析 228 6.8 自定义类型转换器实现高效率序列化 231 6.9 页面状态性能优化策略 238 ...

    庖丁解牛纵向切入ASP.NET 3.5控件和组件开发技术.pdf

    6.4.3 视图状态和控件状态组合使用规则225 6.5 加密页面状态225 6.6 清除页面状态226 6.7 对动态添加控件的视图状态分析228 6.8 自定义类型转换器实现高效率序列化231 6.9 页面状态性能优化策略238 6.9.1 存储...

    Android中自定义View的实现方式总结大全

    这时候我们就需要对系统的view进行扩展或者组合,这就是所谓的自定义view。 Android自定义view的种类 自定义view大概可以分为四个大类,主要是通过实现方式来区分  1.自绘控件,继承view,重写onDraw方法,在其中...

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    书中还深入讲述了其他ASP.NET图书遗漏的高级主题,如自定义控件的创建、图像处理、加密等。此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软...

    面试题面试宝典.zip

    项目介绍.txt 总结的面试题库(1).txt 总结的面试题库.txt 广州公司面试题x Android 面试题(答案最全) ...使用过哪些框架和平台,自定义组合控件.txt 知识点.txt 50道面试题.txt android应用开发.jpg

    ASP.NET4高级程序设计(第4版) 3/3

    书中还深入讲述了其他ASP.NET图书遗漏的高级主题,如自定义控件的创建、图像处理、加密等。此外,《ASP.NET 4高级程序设计(第4版)》专门提供了两章的内容来教你如何用Ajax 技术制作快速响应的页面,以及如何使用微软...

    C#实训教程

    20 自定义控件 364 20.1 添加事件处理程序 368 20.2 添加更多的属性 370 20.3 内容总结 372 21 部署与安装 373 21.1 部署的设计 373 21.2 无干涉部署 387 21.3 内容总结 394 22 ASP.NET与Web窗口简介 395 ...

    asp.net知识库

    Asp.net 2.0功能体验,细节之Web控件(一) 隐藏控件 Asp.net 2.0功能体验,总体设计思想 Asp.net 2.0 WebPart使用经验点滴 革新:.NET 2.0的自定义配置文件体系初探 关于如何在ASP.NET 2.0中定制Expression ...

    Visual Basic 2010入门经典.part1.rar

    7.6 使用组合框创建下?131 7.7 总结 132 7.8 问与答 133 7.9 作业 133 7.9.1 测验 133 7.9.2 答案 134 7.9.3 练习 134 第八章 使用高级控件 135 8.1 创建定时器 135 8.2 创建带选项卡的对话框 137 8.3 在...

    Visual Basic 2010入门经典.part2.rar

    7.6 使用组合框创建下?131 7.7 总结 132 7.8 问与答 133 7.9 作业 133 7.9.1 测验 133 7.9.2 答案 134 7.9.3 练习 134 第八章 使用高级控件 135 8.1 创建定时器 135 8.2 创建带选项卡的对话框 137 8.3 在...

    HTML5 Canvas核心技术 图形、动画与游戏开发

    自定义控件 426 10.1 圆角矩形控件 427 10.2 进度条控件 433 10.3 滑动条控件 437 10.4 图像查看器控件 446 10.5 总结 454 第11章 移动平台开发 455 11.1 移动设备的视窗 456 11.2 媒体特征查询技术 461 ...

    vc++ 应用源码包_1

    自定义的标签控件对话框。 Undo_demo.zip undo_src.zip 在VC中实现Undo和Redo功能。 VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕...

    vc++ 应用源码包_6

    自定义的标签控件对话框。 Undo_demo.zip undo_src.zip 在VC中实现Undo和Redo功能。 VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕...

    vc++ 应用源码包_2

    自定义的标签控件对话框。 Undo_demo.zip undo_src.zip 在VC中实现Undo和Redo功能。 VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕...

    vc++ 应用源码包_5

    自定义的标签控件对话框。 Undo_demo.zip undo_src.zip 在VC中实现Undo和Redo功能。 VC 利用底层键盘钩子屏蔽任意按键MaskKey 动态链接库实现钩子,然后程序调用。 VC 透明窗口效果的电子标尺源代码 实现了屏幕...

Global site tag (gtag.js) - Google Analytics