Подтвердить что ты не робот

Как передать пользовательские параметры компонента в java и xml

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

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

new MyComponent(context);

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

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

4b9b3361

Ответ 1

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

Вы можете создавать конструкторы за пределами трех стандартных, унаследованных от 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