2

I am trying to extend an android.widget.Button and added a styleable attribute to my custom widget, which should hold a reference to a value in res/values/strings.xml.

 <resources>
      <attr name="infoText" format="reference" />
      <declare-styleable name="FooButton">
           <attr name="infoText" />
      </declare-styleable>
 </resources

In my layout I have something like this:

 <LinearLayout
      android:layout_height="wrap_content"
      android:layout_width="fill_parent"
      android:orientation="horizontal">
      <com.example.FooButton
           android:layout_height="wrap_content"
           android:layout_width="wrap_content"
           android:id="@+id/fooButton"
           infoText="@string/fooButtonInfoText" />
 </LinearText>

My res/values/strings.xml looks like this:

 <?xml version="1.0" encoding="utf-8"?>
 <resources>
      <string name="fooButtonInfoText">BAR</string>
 </resources>

The extraction of the attribute value in my custom FooButton looks like this:

 TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.FooButton);
 Integer infoTextId = typedArray.getResourceId(R.styleable.FooButton_infoText, 0);
 if (infoTextId > 0) {
      infoText = context.getResources().getString(infoTextId);
 }
 typedArray.recycle();

I've got these three constructors implemented:

 public FooButton(Context context) {
      super(context);
 }

 public FooButton(Context context, AttributeSet attributeSet) {
      super(context, attributeSet);
      setInfoText(context, attributeSet);
 }

 public FooButton(Context context, AttributeSet attributeSet, int defStyle) {
      super(context, attributeSet, defStyle);
      setInfoText(context, attributeSet);
 }

The method FooButton.setInfoText(context, attributeSet) is called every time there is a FooButton declared.

I am fighting this problem for too long and read dozens of Stackoverflow questions... why does this not work?

1 Answer 1

1

You must declare the namespace for custom attributes. It should look like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/auto"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:orientation="horizontal">
    <com.example.FooButton
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:id="@+id/fooButton"
         app:infoText="@string/fooButtonInfoText" />
 </LinearText>
Sign up to request clarification or add additional context in comments.

2 Comments

To clarify: Where xmlns:app="schemas.android.com/apk/res/auto" would be xmlns:app="schemas.android.com/apk/res/com.example" in case your apps namespace is declared as com.example in the AndroidManifest.xml. Thanks!
Actually, res/auto does what it sounds like: automatically maps your application's namespace. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.