6

我有这样的代码:

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 作为第二个参数?顺便说一句,其余代码用于使用画布进行绘画。谢谢。

4

3 回答 3

3

视图有 3 个构造函数:

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

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

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

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

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

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

等等

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

但是你也可以在自己的名字name中定义和使用自定义属性

<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() 方法,并调用与框架用于您的客户视图的构造函数的参数相对应的超类的构造函数:

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 < 11 的设备上可能不存在。

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

于 2014-04-06T11:11:17.933 回答
3

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

很快,GUI 编辑器需要attributeSet。
AttributeSet 是一组参数,如 layout_width,layour_height等等。如果您需要新的自定义属性,则需要扩展 AttributSet 类

于 2013-08-09T21:53:28.973 回答
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 文档中的标签相关联”

于 2013-08-09T21:53:53.943 回答