52

在 android 中创建自定义组件时,经常会询问如何创建 attrs 属性并将其传递给构造函数。

通常建议在java中创建组件时,只需使用默认构造函数,即

new MyComponent(context);

而不是尝试创建一个 attrs 对象以传递给基于 xml 的自定义组件中常见的重载构造函数。我试图创建一个 attrs 对象,但它似乎既不容易或根本不可能(没有非常复杂的过程),而且从所有角度来看,这并不是真正需要的。

那么我的问题是:在使用 xml 对组件进行膨胀时,在传递或设置原本由 attrs 对象设置的属性的 java 中构造自定义组件的最有效方法是什么?

4

1 回答 1

101

(完全披露:这个问题是创建自定义视图的一个分支)

您可以创建超出从继承的三个标准构造函数View添加您想要的属性...

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

...但我不推荐它。最好遵循与其他组件相同的约定。这将使您的组件尽可能灵活,并防止使用您的组件的开发人员因为您的与其他所有内容不一致而撕毁他们的头发:

1. 为每个属性提供 getter 和 setter:

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

于 2010-12-21T02:10:49.620 回答