Android - AttributeSet

时间:2013-08-09 21:47:43

标签: android

我有一个像这样的代码:

public class CannonView extends SurfaceViewimplements SurfaceHolder.Callback{
Activity activity;

及其构造函数:

public CannonView(Context context, AttributeSet attrs){
Super(context,attrs)
activity = (Activity) context; 

但显然AttributeSet什么也没做,我不知道为什么会这样,所以我的问题是:1。什么是AttributeSet? 2.为什么我们需要提供AttributeSet attrs作为第二个参数?顺便说一下,其余代码用于使用画布进行绘画。感谢。

3 个答案:

答案 0 :(得分:3)

http://developer.android.com/training/custom-views/create-view.html - 这是一个解释。

简而言之,GUI编辑器需要attributeSet。
AttributeSet是一组参数 layout_widthlayour_height等等。 你需要新的自定义属性,你需要扩展以扩展AttributSet类

答案 1 :(得分:3)

视图有3个构造函数:

SurfaceView(Context context)
SurfaceView(Context context, AttributeSet attrs)
SurfaceView(Context context, AttributeSet attrs, int defStyle)

注意:第三种样式是在API级别11中添加的。但是如果要为较新版本的API创建自定义视图,则应该实现它。

实现自定义视图时,如果您希望它可以广泛使用,那么您应该实现三个构造函数 - 在代码的不同部分中使用View或另一个应用程序可以使用任何构造函数实例化它

如果以编程方式构建视图,则可以决定使用哪个构造函数。

但是,Android框架在从XML引用时会实例化您的视图。

<com.me.Common.MyView
   android:layout_width="wrap_contents"
...
/>

这些实例化视图的XML声明可以包含许多属性,其中一些属于“android:”命名空间中的标准android。如果你将这些传递给你正在扩展的SuperClass(如果你正在扩展一个View类 - 那么它将解析它们并使用它们,你不需要做太多。

但您也可以在自己的名称中定义和使用自定义属性

<com.me.Common.MyView
   android:layout_width="wrap_contents"
...
   com.me:num_elements="10"
/>

然后你应该解析构造函数中传递的属性集,并更改View对象的行为以尊重XML中的设置。 “超级类”将解析并使用“android:”属性。

因此,由于您不确切知道Android框架将如何实例化您的自定义视图(它将取决于声明它的XML标记),您应该实现三个构造函数。

注意:执行标准Java覆盖样式并让每个构造函数通过super使用更复杂的构造函数很诱人:

MyView(Context context, AttributeSet attrs) {
    super(context, attrs, 0);
}

但我已经看到这会导致问题,因为0并不总是有效的风格。 因此,我建议您实现一个init()方法来执行您自己的客户代码,并调用Superclass的构造函数,该构造函数对应于Framework用于客户视图的构造函数的参数:

public AnimationController(Context context) {
    super(context);
    initUI(context, null, -1);
}

public AnimationController(Context context, AttributeSet attrs) {
    super(context, attrs);
    initUI(context, attrs, -1);
}

public AnimationController(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initUI(context, attrs, defStyle);
}

特别是因为具有三个参数的super()可能不存在于具有API&lt; 11。

以这种方式实现自定义视图使它们更具可配置性和可重用性,因为您可以将它们放置在具有不同属性集的不同XML文件中,或者使用定义一组属性的样式 - 就像使用Android视图一样。

答案 2 :(得分:1)

SurfaceView有3个构造函数:

SurfaceView(Context context)
SurfaceView(Context context, AttributeSet attrs)
SurfaceView(Context context, AttributeSet attrs, int defStyle)

我相信你应该能够覆盖其中任何一个,所以从技术上来说,你没有 提供AttributeSet作为第二个参数。

至于为什么有AttributeSet,您可以参考View文档:http://developer.android.com/reference/android/view/View.html。根据该站点,构造函数SurfaceView(Context context, AttributeSet attrs)在“从XML扩展视图时被调用”。

至于AttributeSet是什么:根据http://developer.android.com/reference/android/util/AttributeSet.html

,它是“与XML文档中的标记相关联的属性集合”