野人学Android第二弹——自定义控件的分析与实例
2015-11-17 11:18
537 查看
在学会Android基础的控件之后,有没有想自己开发一个控件呢?随着各种需求的提出,基础的控件已经不能满足Android的开发,幸好可以自定义控件,那么这一篇博文,就跟大家聊聊自定义控件。
想要跑,先学走。在自定义之前,让我们整理下Android原装控件是怎么运行的:
1.xml文件中会声明一个控件,然后就是各种属性;
2.JAVA文件中会加载这个xml;
3.如果有监听事件,控件会在java中初始化,然后绑定相应的监听事件;
根据上面的信息,可以推测,有相关的类获取xml中的属性,并且将这些属性与相应的控件绑定在一起,并且会给这些控件绑定相应的监听事件接口。想来想去,找Button开刀,追溯到View这个类存在大量的业务代码。找了半天,找到下面一些代码,而这些代码验证了我的推测。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/13/792047053b27e94b7c18c4c9b20c2f29)
关于参数的解释,不懂的可以自行翻译,在这里就不多说了。要强调的是,attrs这个参数是xml中对应的属性,也就是推测1中的控件属性。既然有了控件属性,那么怎么从xml中转换成java的代码呢。这里要说下TypeArray这个类型以及context.obtainStyledAttributes()这个方法。就是将xml中的属性转换成数组类型。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/13/a4b4ba6b280fdd73a26481d7e2827c12)
如上图所示:
第一步,在循环中获取数组中的属性值;
第二步,按照条件进行选择,其中case后面的条件就是xml中具体的属性名称,只不过最后一个“.”后面的构成规则有点讲究,这个在后面的实例中会讲解;
第三步,就是将指定的属性值赋值给对应的参数。
分析到这里,其实已经完成一大步了。不同的控件,赋值的方法不一样。并且本博文中讲到的自定义控件,也是建立在基础控件的基础上的,所以接下来就要用到基础控件的属性设定方法。如果自定义的控件没有监听事件,分析到这里也差不多了。既然对自定义控件的分析完毕,那么就来具体实现一下吧。
网络上有很多教程,我大概总结下了,有这么几步:
1.在values文件夹中新建“atts.xml”文件,定义控件的属性;
2.新建自定义控件的class文件,继承RelativeLayout类,按照上面的思路,获取xml文件中的属性值,然后新建基础控件,并且将属性值赋予这些控件;
3.如果有监听事件,那么写一个监听接口,最后添加在相应的监听事件中,这样从外界就可以添加事件了。
如果不理解这几步,那么来看看具体的代码吧。
第一步,新建atts.xml
关于这个文件,需要解释的有以下几点:
1.<declare-styleable>这个标签是针对控件属性的,所以要死记硬背;
2.name="Topbar"这个属性是整个自定义控件的名称,后面的代码中会引用到;
3.<attr name="titleText" format="string"/>中的name就是属性的名称,format是属性值的类型,这里就是string,需要强调的是,eclipse中没有提示,需要自己百度查。
第二步,新建Topbar.class
上面的代码已经将功能全部实现,包括属性值的转换、将属性值赋值给控件,点击事件等等步骤,慢慢消化吧。自定义控件的工作基本完成,剩下的就是使用了。关于这个自定义控件的使用,还有几点需要强调的。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/13/fb1685386f92e4fb499740235d34be8a)
1.需要添加这么一段引用代码,其中custombar是自己定义的,和3中的custombar相对应;
2.自定义控件的标签需要将包名也写上,Topbar指的是上面写的Topbar.class的文件名;
3.因为rightText这个属性值是自定义添加的,所以要用custombar引用;
最后的最后,来一张图片,看看自定义控件的效果吧。
想要跑,先学走。在自定义之前,让我们整理下Android原装控件是怎么运行的:
1.xml文件中会声明一个控件,然后就是各种属性;
2.JAVA文件中会加载这个xml;
3.如果有监听事件,控件会在java中初始化,然后绑定相应的监听事件;
根据上面的信息,可以推测,有相关的类获取xml中的属性,并且将这些属性与相应的控件绑定在一起,并且会给这些控件绑定相应的监听事件接口。想来想去,找Button开刀,追溯到View这个类存在大量的业务代码。找了半天,找到下面一些代码,而这些代码验证了我的推测。
关于参数的解释,不懂的可以自行翻译,在这里就不多说了。要强调的是,attrs这个参数是xml中对应的属性,也就是推测1中的控件属性。既然有了控件属性,那么怎么从xml中转换成java的代码呢。这里要说下TypeArray这个类型以及context.obtainStyledAttributes()这个方法。就是将xml中的属性转换成数组类型。
如上图所示:
第一步,在循环中获取数组中的属性值;
第二步,按照条件进行选择,其中case后面的条件就是xml中具体的属性名称,只不过最后一个“.”后面的构成规则有点讲究,这个在后面的实例中会讲解;
第三步,就是将指定的属性值赋值给对应的参数。
分析到这里,其实已经完成一大步了。不同的控件,赋值的方法不一样。并且本博文中讲到的自定义控件,也是建立在基础控件的基础上的,所以接下来就要用到基础控件的属性设定方法。如果自定义的控件没有监听事件,分析到这里也差不多了。既然对自定义控件的分析完毕,那么就来具体实现一下吧。
网络上有很多教程,我大概总结下了,有这么几步:
1.在values文件夹中新建“atts.xml”文件,定义控件的属性;
2.新建自定义控件的class文件,继承RelativeLayout类,按照上面的思路,获取xml文件中的属性值,然后新建基础控件,并且将属性值赋予这些控件;
3.如果有监听事件,那么写一个监听接口,最后添加在相应的监听事件中,这样从外界就可以添加事件了。
如果不理解这几步,那么来看看具体的代码吧。
第一步,新建atts.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Topbar"> <attr name="titleText" format="string"/> <attr name="titleTextSize" format="dimension"/> <attr name="titleTextColor" format="color"/> <attr name="leftBackground" format="reference|color"/> <attr name="leftText" format="string"/> <attr name="leftTextColor" format="reference|color"/> <attr name="rightBackground" format="reference|color"/> <attr name="rightText" format="string"/> <attr name="rightTextColor" format="reference|color"/> </declare-styleable> </resources>
关于这个文件,需要解释的有以下几点:
1.<declare-styleable>这个标签是针对控件属性的,所以要死记硬背;
2.name="Topbar"这个属性是整个自定义控件的名称,后面的代码中会引用到;
3.<attr name="titleText" format="string"/>中的name就是属性的名称,format是属性值的类型,这里就是string,需要强调的是,eclipse中没有提示,需要自己百度查。
第二步,新建Topbar.class
public class TopBar extends RelativeLayout { private float titleTextSize; private int titleTextColor; private String titleText; private Drawable leftBackground; private int leftTextColor; private String rightText; private Drawable rightBackground; private int rightTextColor; private String leftText; private LayoutParams leftParams, rightParams, titleParams; private topbarClickListener listener; //定义Listener的接口 public interface topbarClickListener{ public void leftClick(); public void rightClick(); } public void setOnTopbarClickListener(topbarClickListener listener){ this.listener = listener; } public MyTopBar(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Topbar);//将xml中属性转换成数组 titleTextSize = ta.getDimension(R.styleable.Topbar_titleTextSize, 0);//获取相应属性值 titleTextColor = ta.getColor(R.styleable.Topbar_titleTextColor, 0); titleText = ta.getString(R.styleable.Topbar_titleText); leftBackground = ta.getDrawable(R.styleable.Topbar_leftBackground); leftText = ta.getString(R.styleable.Topbar_leftText); leftTextColor = ta.getColor(R.styleable.Topbar_leftTextColor, 0); rightBackground = ta.getDrawable(R.styleable.Topbar_rightBackground); rightText = ta.getString(R.styleable.Topbar_rightText); rightTextColor = ta.getColor(R.styleable.Topbar_rightTextColor, 0); ta.recycle(); TextView title = new TextView(context);//新建基础控件 Button leftButton = new Button(context); Button rightButton = new Button(context); title.setText(titleText);//将属性值赋值给新建的基础控件 title.setBackgroundColor(titleTextColor); title.setTextSize(titleTextSize); leftButton.setText(leftText); leftButton.setBackground(leftBackground); leftButton.setBackgroundColor(leftTextColor); rightButton.setText(rightText); rightButton.setBackground(rightBackground); rightButton.setBackgroundColor(rightTextColor); setBackgroundColor(0x7CFC0055);//整个控件的背景色 titleParams = new LayoutParams( android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT);//设定控件的宽和高 titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);//设定控件的位置,CENTER_IN_PARENT指的是在父类空间的中间 addView(title, titleParams);//最后是将设定好的基础控件加在自定义控件中 leftParams = new LayoutParams( android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); addView(leftButton, leftParams); rightParams = new LayoutParams( android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE); addView(rightButton,rightParams); //设定左边按钮的点击事件 leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub listener.leftClick(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub listener.rightClick(); } }); } }
上面的代码已经将功能全部实现,包括属性值的转换、将属性值赋值给控件,点击事件等等步骤,慢慢消化吧。自定义控件的工作基本完成,剩下的就是使用了。关于这个自定义控件的使用,还有几点需要强调的。
1.需要添加这么一段引用代码,其中custombar是自己定义的,和3中的custombar相对应;
2.自定义控件的标签需要将包名也写上,Topbar指的是上面写的Topbar.class的文件名;
3.因为rightText这个属性值是自定义添加的,所以要用custombar引用;
最后的最后,来一张图片,看看自定义控件的效果吧。
相关文章推荐
- android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!
- android 文本框不获取焦点的两种方式
- 使用GSON解析list集合上传服务器,服务器报400错误
- android 自定义折线图
- Android下拉刷新开源控件 liaohuqiu/android-Ultra-Pull-To-Refresh
- 关于Android Studio中如何解决Scode校验失败的解决方法
- android dialog弹出的情况下监听返回键
- 【Android解决方案】在onResume里调用getIntent()得到的是上一次数据
- android 显示图文混排
- android 下拉刷新控件PtrClassicFrameLayout(cube)
- 打造开发神器—Android Studio上的常用5个插件介绍
- Android 自定义 DialogFragment 宽度问题
- 屏幕适配全攻略
- android程序中,点击一个按钮,实现字符加一的功能
- android hal学习——aidl,java service,jni编写
- 自定义view-SlideSwitch开源详解
- 国内一些优秀Android 开发者信息
- Android 为PopupWindow设置动画效果
- Android专用Log开源项目——KLog
- Android基础之在Eclipes中关联SDK源码和查看SDK源码