自定义视图
Android框架虽然提供了许多与用户交互,并且能够展现各种数据的视图,但是有的时候Android内建的基本视图控件并不能够很好的满足一些特殊的要求,这个时候我们就需要自定义视图控件
创建自定义视图类
一个设计的很好的自定义视图就像一个设计的很好的类一样,它封装了一组特定的、易于使用的方法,它高效合理的利用手机CPU和内存,除了需要是一个设计良好的类之外,一个自定义的视图还应该满足以下几个条件:
1、符合Android平台标准
2、用Android XML layouts来提供自定义样式化属性
3、发送可访问性的事件
4、要能够兼容多种Android版本平台
Android框架为我们提供了一套基础的类和XML标签来帮助我们创建一个满足以上要求的视图类,现在我们就来学习下怎么利用Android框架来实现一个视图类的核心功能函数
如何创建一个自定义视图类
在Android框架中所有的视图类都是继承自View类,我们的自定义视图类也可以直接继承View类,当然如果为了节省时间我们也可以继承自一个已经实现好了的View的子类,例如Button类
为了让我们的视图能够和Android Developers Tool进行交互,我们的自定义视图类必须提供一个以 Context和
AttributeSet类型为参数的构造函数,通过这个构造函数我们的视图控件就能够让布局编辑器通过资源文件来进行构造和设置样式了,让我们可以在Android提供的图形编辑器中进行编辑
class PieChart extends View {
public PieChart(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}}
定义自定义属性
我们把一个内建的视图添加进用户界面,我们需要在一个XML元素文件中指定它,通过元素属性来控制它的显示和行为,为了更好的实现自定义视图,我们也需要通过XML来把它添加进用户界面和定义它的样式,为了满足这个需求我们应该做到如下几点
1、在资源元素
<declare-styleable>
中定义自定义属性
2、在XML layout文件中指定属性的值
3、在运行时检索属性的值
4、在视图中应用检索到的属性值
在
res/values/attrs.xml
使用
<declare-styleable>
元素定义自定义属性
<resources>;
<declare-styleable name="PieChart">
<attr name="showText" format="boolean" />
<attr name="labelPosition" format="enum">
<enum name="left" value="0"/>
<enum name="right" value="1"/>
</attr>
</declare-styleable>
</resources>
在XML layout中指定自定义属性的值
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.customviews">
<com.example.customviews.charting.PieChart
custom:showText="true"
custom:labelPosition="left" />
</LinearLayout>
在我们自定义的视图控件添加进layout中时,我们要指定类全名<packageName.className>,如果我们的视图类是内部类的话那就是<packageName.outClassName$innerClassName>
使用自定义属性
当你的视图在XML layout中创建出来的时候,所有配置的属性都是可以从资源文件中读取出来的,并会把它们当做 AttributeSet 类型的参数传递到视图的构造函数中,虽然可以直接从 AttributeSet 中读取属性的值,但这样做有一些缺点:
1、没有解决在资源文件中引用属性值的问题
2、样式还没有被附加
我们可以通过
obtainStyledAttributes()
方法
来读取属性的值,当调用
obtainStyledAttributes()
方法时会有一个 TypedArray 类型的返回值, TypedArray 里存储的属性值都是经过引用和附加过样式
public PieChart(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.PieChart,
0, 0);
try {
mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
} finally {
a.recycle();
}}
暴露属性和添加事件监听
属性是一个有力的手段用来控制视图的外观和行为,但是它们只有当视图初始化完成后才能够取得,为了提供一种动态的手段,为每一个自定义的属性提供setter和getter方法
public boolean isShowText() {
return mShowText;}
public void setShowText(boolean showText) {
mShowText = showText;
invalidate();
requestLayout();}
任何一个属性值的改变,都有可能影响到视图界面的外观、呈现的数据,我们需要通过调用
invalidate
()
方法
来通知系统重新绘制视图界面,同样地,属性值的改变也有可能影响到视图界面的大小和形状,我们需要通过调用
requestLayout
() 来重新生成视图界面的布局,这一点需谨记
我们还需要设置一些监听器来监听一些重要的事件,比如说用户的触屏事件...