【问题标题】:How to pass custom component parameters in java and xml如何在 java 和 xml 中传递自定义组件参数
【发布时间】:2011-05-28 14:05:14
【问题描述】:

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

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

new MyComponent(context);

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

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

【问题讨论】:

    标签: android components custom-attributes uicomponents


    【解决方案1】:

    (完全披露:这个问题是Creating custom view 的一个分支)

    除了从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

    【讨论】:

    • 我知道这为时已晚,但您需要在清单中添加 xmlns:blrfl="schemas.android.com/apk/res/com.blrfl" 吗?
    • 不,只针对使用命名空间的 XML 文档。我实际上没有注意到我将 Android 命名空间克隆到 Blrfl 命名空间中,这是错误的。这已经解决了。
    • 假设您在 XML 中定义了 MyComponent,但是在活动中计算了“foo”参数。然后你必须做((MyComponent) findViewById(R.id.customid)).setFoo("computedFoo");。我的问题是:这需要在onCreate 中的setContentView 调用之后完成,对吧?
    • 是的,setContentView() 可以让 findViewById() 在您请求绘制的视图中找到元素。
    • 伟大的 res-auto 帮助我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多