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

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

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

new MyComponent(context);

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

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

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

Другие вопросы по тегам