王学岗自定义控件(一)
2016-05-25 17:46
579 查看
自定义控件分为四个步骤
第一:自定义属性;
第二:获取自定义属性的值;
第三:重写onMeasure()方法;(视情况而定,本步骤不是必须的)
第四:重写onDraw()方法
自定义属性;
我们写一个MyTextView类,继承View,首先要重写构造方法;如下图
![](https://img-blog.csdn.net/20160525164353875)
我们分析下父类的三种构造方法:
我们分析了下三个构造方法的区别,但实际开发中我们总是希望能够调用参数较多的第三种构造方法,因为参数越多越能描述当前View的特性,以至于我们总是这么写;
然后我们可以在xml文件中为自定义的view添加相应的属性,但是我们发现我们现在能添加的属性大都是父类的属性,而我们自定义自己的view就是为了定义独特的属性,那我们该如何定义自己的属性呢?
![](https://img-blog.csdn.net/20160525170226386)
第一步:我们在values文件夹下建立attrs文件
![](https://img-blog.csdn.net/20160525171022582)
attrs文件如下
第二步:在activity_xml中增加命名空间
这里介绍个小技巧;res后面跟的是当前应用的包名;可以在Mainfest中获取
![](https://img-blog.csdn.net/20160525172954502)
xmlns:myandroid=”http://schemas.android.com/apk/res/com.example.zi_ding_yi_kong_jian”
第三步:获取控件的属性
然后可以在MytextView中获取所有的属性,这里介绍几种获取属性值的方法
方法一:
看下MyTextView代码:
这是打印输出结果:
![](https://img-blog.csdn.net/20160525174409868)
与我们定义的属性一一对应;
但是这种方法有着一个明显的缺陷;那就是无法拿到引用的属性值;
如果我们的MyTextView的myText属性这么定义
myandroid:myText=”@string/myText”
我们看下打印的结果
![](https://img-blog.csdn.net/20160525182433791)
为了解决这种情况我们只能用下面的方法了
看我们第二种方法的代码:
大家看这句代码
TypedArray ta =
context.obtainStyledAttributes(attrs, R.styleable.myTextView);
点击R.styleable.myTextView会发现R文件如下所示代码
数组的三个元素就是我们自定义的三个属性;
R.styleable.myTextView中的styleable是和declare-styleable标签相联系的;
我们看下打印输出结果,myandroid:myText=”@string/myText”也可以打印出内容,而不是引用的地址
![](https://img-blog.csdn.net/20160525191226199)
好了,自定义view要分好几篇博客才可以讲完;本片博客讲的都是基础的;更深入的分析请看下面的博客
第一:自定义属性;
第二:获取自定义属性的值;
第三:重写onMeasure()方法;(视情况而定,本步骤不是必须的)
第四:重写onDraw()方法
自定义属性;
我们写一个MyTextView类,继承View,首先要重写构造方法;如下图
我们分析下父类的三种构造方法:
//使用java代码创建的时候调用 public MyTextView(Context context) { super(context); }
//AttributSet 是属性集合,因为xml文件会被反射成一个类,使用xml文件创建view的时候会调用该构造方法 public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); }
//defStyle是default style的简写,当有指定样式的时候调用构造方法 public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
我们分析了下三个构造方法的区别,但实际开发中我们总是希望能够调用参数较多的第三种构造方法,因为参数越多越能描述当前View的特性,以至于我们总是这么写;
public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MyTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyTextView(Context context) { this(context, null); }
然后我们可以在xml文件中为自定义的view添加相应的属性,但是我们发现我们现在能添加的属性大都是父类的属性,而我们自定义自己的view就是为了定义独特的属性,那我们该如何定义自己的属性呢?
第一步:我们在values文件夹下建立attrs文件
attrs文件如下
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- name 值一般和自定义的类名相同 ,也可以不一样 --> <declare-styleable name="myTextView"> <!-- 属性的类型 字符串:string 像素:dimension 颜色:color 引用:reference @ --> <attr name="myText" format="string" /> <attr name="myTextSize" format="dimension" /> <attr name="myTextColor" format="color" /> </declare-styleable> </resources>
第二步:在activity_xml中增加命名空间
这里介绍个小技巧;res后面跟的是当前应用的包名;可以在Mainfest中获取
xmlns:myandroid=”http://schemas.android.com/apk/res/com.example.zi_ding_yi_kong_jian”
第三步:获取控件的属性
<com.example.zi_ding_yi_kong_jian.myview.MyTextView android:layout_width="wrap_content" android:layout_height="wrap_content" myandroid:myText="张欣喜欢我" myandroid:myTextColor="#13579a" myandroid:myTextSize="10sp" />
然后可以在MytextView中获取所有的属性,这里介绍几种获取属性值的方法
方法一:
看下MyTextView代码:
package com.example.zi_ding_yi_kong_jian.myview; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; public class MyTextView extends View { public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); int count=attrs.getAttributeCount(); for(int i=0;i<count;i++){ String myName= attrs.getAttributeName(i); String myValue= attrs.getAttributeValue(i); Log.i("zhang_xin", myName+";"+myValue); } } public MyTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyTextView(Context context) { this(context, null); } }
这是打印输出结果:
与我们定义的属性一一对应;
但是这种方法有着一个明显的缺陷;那就是无法拿到引用的属性值;
如果我们的MyTextView的myText属性这么定义
myandroid:myText=”@string/myText”
我们看下打印的结果
为了解决这种情况我们只能用下面的方法了
看我们第二种方法的代码:
package com.example.zi_ding_yi_kong_jian.myview; import com.example.zi_ding_yi_kong_jian.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.View; public class MyTextView extends View { public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.myTextView); //数组中的第一个值 String myText = ta.getString(R.styleable.myTextView_myText); // 指定颜色的默认值,如果没有定义该属性就返回默认值 int myTextColor = ta.getColor(R.styleable.myTextView_myTextColor, Color.RED); // sp的默认值可以使用下面的方法得到,如果是dp的默认值就是TypedValue.COMPLEX_UNIT_dip int defaultValue = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 12, getResources() .getDisplayMetrics()); int MyTestSize = (int) ta.getDimension( R.styleable.myTextView_myTextSize, defaultValue); Log.i("zhang_xin", "myText=" + myText + " myTextColor=" + myTextColor + " MyTestSize=" + MyTestSize); ta.recycle();// 要回收 Be sure to call recycle() when done with them } public MyTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyTextView(Context context) { this(context, null); } }
大家看这句代码
TypedArray ta =
context.obtainStyledAttributes(attrs, R.styleable.myTextView);
点击R.styleable.myTextView会发现R文件如下所示代码
public static final int[] myTextView = { 0x7f010000, 0x7f010001, 0x7f010002 };
数组的三个元素就是我们自定义的三个属性;
R.styleable.myTextView中的styleable是和declare-styleable标签相联系的;
我们看下打印输出结果,myandroid:myText=”@string/myText”也可以打印出内容,而不是引用的地址
好了,自定义view要分好几篇博客才可以讲完;本片博客讲的都是基础的;更深入的分析请看下面的博客
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories