Android Custom View Constructor - PullRequest
       10

Android Custom View Constructor

33 голосов
/ 21 мая 2010

Я узнаю об использовании пользовательских представлений из следующего:

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

В описании сказано:

Инициализация класса. Как всегда, супер называется первым. Более того, это не конструктор по умолчанию, но параметризованный. 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);
} 

Ответы [ 3 ]

64 голосов
/ 22 мая 2010

Вам не нужен первый, потому что он просто не будет работать.

Третий будет означать, что ваш пользовательский View будет использоваться из файлов макета XML. Если тебя это не волнует, тебе это не нужно.

Четвертый - просто неправильный, AFAIK. Не существует конструктора View, который принимает Map в качестве третьего параметра. Есть один, который принимает int в качестве третьего параметра, используемого для переопределения стиля по умолчанию для виджета.

Я склонен использовать синтаксис 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
}

Вы можете увидеть остальную часть этого кода в этом примере книги .

11 голосов
/ 02 июня 2012

Вот мой шаблон (здесь создается пользовательский 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>
7 голосов
/ 08 января 2015

Когда вы добавляете свой пользовательский View из xml как:

 <com.mypack.MyView
      ...
      />

вам потребуется открытый конструктор MyView(Context context, AttributeSet attrs),, в противном случае вы получите Exception, когда Android попытается inflate вашего View.

А когда вы добавляете View из xml, а также укажите 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);
    }

Смотрите это

...