34

我正在学习如何使用以下自定义视图:

http://developer.android.com/guide/topics/ui/custom-components.html#modifying

描述说:

类初始化 与往常一样,首先调用 super。此外,这不是默认构造函数,而是参数化构造函数。EditText 是在从 XML 布局文件中扩展时使用这些参数创建的,因此,我们的构造函数需要同时获取它们并将它们传递给超类构造函数。

有更好的描述吗?我一直在试图弄清楚构造函数应该是什么样子,并且我提出了 4 种可能的选择(参见帖子末尾的示例)。我不确定这 4 个选择做什么(或不做什么),为什么要实现它们,或者参数的含义。有这些描述吗?

public MyCustomView()
{
    super();
}

public MyCustomView(Context context)
{
    super(context);
}

public MyCustomView(Context context, AttributeSet attrs)
{
    super(context, attrs);
} 

public MyCustomView(Context context, AttributeSet attrs, Map params)
{
    super(context, attrs, params);
} 
4

3 回答 3

66

你不需要第一个,因为那是行不通的。

第三个将意味着您的自定义View将可用于 XML 布局文件。如果你不关心这个,你就不需要它。

第四个是错的,AFAIK。没有View将 aMap作为第三个参数的构造函数。有一个将 anint作为第三个参数,用于覆盖小部件的默认样式。

我倾向于使用this()语法来组合这些:

public ColorMixer(Context context) {
    this(context, null);
}

public ColorMixer(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ColorMixer(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // real work here
}

您可以在本书示例中看到此代码的其余部分。

于 2010-05-22T15:07:12.507 回答
11

这是我的模式(在这里创建自定义ViewGoup,但仍然):

// CustomView.java

public class CustomView extends LinearLayout {

    public CustomView(Context context) {
        super(context);
        init(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context ctx) {
        LayoutInflater.from(ctx).inflate(R.layout.view_custom, this, true);
            // extra init
    }

}

// view_custom.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Views -->
</merge>
于 2012-06-02T15:39:00.610 回答
8

当您Viewxml like 添加自定义时:

 <com.mypack.MyView
      ...
      />

您将需要公共构造函数 ,否则您MyView(Context context, AttributeSet attrs),ExceptionAndroid尝试.inflateView

当您添加Viewfromxml指定android:style attribute类似内容时:

 <com.mypack.MyView
      style="@styles/MyCustomStyle"
      ...
      />

您还需要第三个公共构造函数 MyView(Context context, AttributeSet attrs,int defStyle)

第三个构造函数通常在您扩展样式并对其进行自定义时使用,然后您希望将其设置为布局style中的给定值View

编辑详细信息

public MyView(Context context, AttributeSet attrs) {
            //Called by Android if <com.mypack.MyView/> is in layout xml file without style attribute.
            //So we need to call MyView(Context context, AttributeSet attrs, int defStyle) 
            // with R.attr.customViewStyle. Thus R.attr.customViewStyle is default style for MyView.
            this(context, attrs, R.attr.customViewStyle);
    }

看到这个

于 2015-01-08T11:54:12.943 回答