Как передать пользовательские параметры компонентов в Java и XML - PullRequest
49 голосов
/ 21 декабря 2010

При создании пользовательского компонента в Android часто спрашивают, как создать и передать свойство attrs конструктору.

Часто предлагается, чтобы при создании компонента в Java вы просто использовали значение по умолчаниюконструктор, то есть

new MyComponent(context);

вместо попытки создания объекта attrs для передачи через перегруженный конструктор, часто встречающийся в пользовательских компонентах на основе xml.Я пытался создать объект attrs, и это не кажется ни легким, ни вообще невозможным (без чрезвычайно сложного процесса), и, судя по всему, на самом деле не требуется.

Мой вопрос: каков наиболее эффективный способ создания пользовательского компонента в java, который передает или задает свойства, которые в противном случае были бы установлены объектом attrs при накачивании компонента с использованием xml?

1 Ответ

95 голосов
/ 21 декабря 2010

(полное раскрытие: этот вопрос является ответвлением Создание пользовательского представления )

Вы можете создать конструкторы помимо трех стандартных, унаследованных от View, которые добавляют необходимые атрибуты...

MyComponent(Context context, String foo)
{
  super(context);
  // Do something with foo
}

... но я не рекомендую это.Лучше следовать тому же соглашению, что и другие компоненты.Это сделает ваш компонент настолько гибким, насколько это возможно, и не позволит разработчикам, использующим ваш компонент, рвать на себе волосы, потому что ваши несовместимы со всем остальным:

1.Укажите методы получения и установки для каждого из атрибутов:

public void setFoo(String new_foo) { ... }
public String getFoo() { ... }

2.Определите атрибуты в res/values/attrs.xml, чтобы их можно было использовать в XML.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="MyComponent">
    <attr name="foo" format="string" />
  </declare-styleable>
</resources>

3.Предоставьте три стандартных конструктора из View.

Если вам нужно выбрать что-либо из атрибутов в одном из конструкторов, которое принимает AttributeSet, вы можете сделать ...

TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MyComponent);
CharSequence foo_cs = arr.getString(R.styleable.MyComponent_foo);
if (foo_cs != null) {
  // Do something with foo_cs.toString()
}
arr.recycle();  // Do this when done.

После всего этого вы можете создать MyCompnent программно ...

MyComponent c = new MyComponent(context);
c.setFoo("Bar");

... или через XML:

<!-- res/layout/MyActivity.xml -->
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:blrfl="http://schemas.android.com/apk/res-auto"
  ...etc...
>
  <com.blrfl.MyComponent
   android:id="@+id/customid"
   android:layout_weight="1"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:layout_gravity="center"
   blrfl:foo="bar"
   blrfl:quux="bletch"
  />
</LinearLayout>

Дополнительный ресурс - https://developer.android.com/training/custom-views/create-view

...