您的当前位置:首页正文

高级UI<第三十六篇>:自定义View之构造方法

来源:华拓网

在我们编写自定义view时第一件事总是编写构造方法,我之所以将自定义View的构造方法单独拉出一章来讲是因为它非常重要。

就以自定义Textview为例

public class CustomTextView extends AppCompatTextView {
    public CustomTextView(Context context) {
        super(context);
    }

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

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

默认情况下,我们的自定义构造方法是这个样子的,但是,如果我们需要初始化一些参数呢?

一般情况下,一些初始化操作是放在构造方法中执行的,但是以上代码有三个构造方法,那么我们是将初始化方法分别在这三个构造方法中?

public class CustomTextView extends AppCompatTextView {
    public CustomTextView(Context context) {
        super(context);
        init();
    }

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

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化数据
     */
    private void init(){

    }
}

我们不清楚程序到底执行哪个构造方法,所以我们需要在每个构造方法里面都加上我们的初始化方法。

以上代码看起来比较繁琐,那么有没有什么简单的方法呢?

有的,我们可以使用层级的方式,也就是说,第一个构造方法调用第二个构造方法,第二个方法调用第三个构造方法,以次类推,最后一个构造方法依然调用父类的构造方法。

最终代码如下:

public class CustomTextView extends AppCompatTextView {
    public CustomTextView(Context context) {
        this(context, null);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化数据
     */
    private void init(){

    }
}

【补充】

  • this() ---- 调用当前类的构造方法

  • super() ---- 调用父类的构造方法

  • 当使用xml初始化view时,默认调用第二个构造方法,在View类的源码也可以看出,如下:

      /**
       * Constructor that is called when inflating a view from XML. This is called
       * when a view is being constructed from an XML file, supplying attributes
       * that were specified in the XML file. This version uses a default style of
       * 0, so the only attribute values applied are those in the Context's Theme
       * and the given AttributeSet.
       *
       * <p>
       * The method onFinishInflate() will be called after all children have been
       * added.
       *
       * @param context The Context the view is running in, through which it can
       *        access the current theme, resources, etc.
       * @param attrs The attributes of the XML tag that is inflating the view.
       * @see #View(Context, AttributeSet, int)
       */
      public View(Context context, @Nullable AttributeSet attrs) {
          this(context, attrs, 0);
      }
    

注释的中文翻译是:

从XML中展开视图时调用的构造函数。这叫做从XML文件构造视图时,提供在XML文件中指定的属性。此版本使用默认样式0,因此应用的唯一属性值是上下文主题中的那些值以及给定的属性集。

在添加了所有子项之后,将调用onFinishInflate()方法。

[本章完...]