3

I am writing a custom DialogPreference and I setup the preference with 2 arrays of strings named entries and entryValues, similarly to what a ListPreference would need. Even though both arrays seem to be present when my constructor is called with the AttributeSet param, trying to fetch the styled arrays via obtainStyledAttributes fails by returning null.

What am I doing wrong and how can I try to fix this?

My custom class code is:

public class BackgroundPicker extends DialogPreference {    

    private CharSequence[] mEntries;
    private CharSequence[] mEntryValues;

    public BackgroundPicker(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // Print all values in attrs AttributeSet:
        for (int i=0;i<attrs.getAttributeCount();i++) {
            String name = attrs.getAttributeName(i);
            Object value  = attrs.getAttributeValue(i);
            Log.d(TAG, name + " : " + value + " of type " + value.getClass().getSimpleName());
        }

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPreference, 0, 0);

        // getIndexCount returns zero !
        for(int i=0; i<a.getIndexCount(); i++) {
            TypedValue v = a.peekValue(i);
            Log.d(TAG, "value[" + i + "] = " + v.toString());
        }

        // Both entries and entryValues are null.
        mEntries = a.getTextArray(R.styleable.ListPreference_entries);
        mEntryValues = a.getTextArray(R.styleable.ListPreference_entryValues);
    }
}

my debug print is:

BackgroundPicker CTOR: IN
BackgroundPicker CTOR param attrs:
entries : @2131099650 of type String
title : @2131165247 of type String
key : BackgroundImage of type String
summary : @2131165248 of type String
defaultValue : back.png of type String
entryValues : @2131099651 of type String
BackgroundPicker CTOR param defStyle = 0
BackgroundPicker CTOR: OUT

my styles in styles.xml

<declare-styleable name="ListPreference">
    <attr name="entries" format="reference" />
    <attr name="entryValues" format="reference" />
</declare-styleable>    

my data in arrays.xml

<array name="Backgrounds">
    <item>back.png</item>
    <item>one.png</item>
</array>

and my preferences setup:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
    <PreferenceCategory android:title="@string/generaloptions" >
        <BackgroundPicker
            android:defaultValue="back.png"
            android:entries="@+array/Backgrounds"
            android:entryValues="@+array/Backgrounds"
            android:key="BackgroundImage"
            android:summary="@string/backgroundImageSummary"
            android:title="@string/backgroundImage" />
    </PreferenceCategory>
 </PreferenceScreen>
TudorT
  • 441
  • 1
  • 5
  • 18

1 Answers1

3

The values with the + sign seem strange to me, I never used them in my settings, maybe it is the main reason of the incorrect behavior. Just use android:entries="@array/Backgrounds" without +.

Also try to obtain values by using my code, at least it worked for attributes of integer type, so it should work for other types as well:

TypedArray a = context.obtainStyledAttributes(attrs, new int[] { R.attr.entries, R.attr.entryValues });
mEntries = a.getTextArray(0); // because R.attr.entries has index 0 in the passed array
mEntryValues = a.getTextArray(1);
vortexwolf
  • 13,701
  • 2
  • 51
  • 70
  • Unfortunately this didn't solve it. getTextArray returns null. a.getIndexCount() even returns null although the a variable has a length of 2 and appears to have data. I've tried removing android: from the definition of entries, other obtain functions, etc. For now, I'm fetching the referenced resources, unstyled and use that (ugly, I know). – TudorT Mar 16 '13 at 14:07
  • 1
    @TudoT Actually android already has attributes `entries` and `entryValues`, you shouldn't have redefined them. Also try to add the android namespace to my example, like `android.R.attr.entries` – vortexwolf Mar 16 '13 at 17:52
  • Thanks a lot ! Using android.R.attr.entries solved the problem. PackageName.R.attr.entries did not work. Using custom names instead of "entries" and "entryValues" also did not work. So it was a namespace issue. – TudorT Mar 16 '13 at 23:22
  • 2
    Another way to solved this is to put the app: prefix in the preferences setup like so: app:entries="@+array/Backgrounds". This brings the custom attributes in the app namespace and make them accessible by the other code. See more at: [link](http://stackoverflow.com/questions/2695646/declaring-a-custom-android-ui-element-using-xml/2695649#2695649) – TudorT Mar 17 '13 at 18:55