WORKS: Android Custom Component - access Array in strings.xml, supplied via layout.xml

ⅰ亾dé卋堺 提交于 2019-12-11 12:25:28

问题


I have class, which extends LinearLayout, in it there are Buttons and a Spinner.

This Object gets included via my layout XML file:

<com.ics.spinn.ComboBox android:id="@+id/myautocombo"
  android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:entries="@array/suppliers" />
/>

The array suppliers is defined in strings.xml.

If this component now wouldn't be com.ics.spinn.ComboBox, but a Spinner, Android would auto-populate the "android:entries" to the Spinner adapter.

I'd like my component com.ics.spinn.ComboBox to behave the same way: to be able to access the array defined via the xml file, so I can supply it to the Spinner inside my component, via:

    ArrayAdapter<String> a = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_spinner_dropdown_item, ARRAYINSIDEMYXML);
    s.setAdapter(a);

I now I could access the array defined in strings.xml DIRECTLY via getResources().getStringArray(R.array.suppliers) but my code shouldn't know of the name "suppliers", since it shall be supplied via android:entries...

This + the entries in xml in João Melo solution WORK:

        public ComboBox(Context context, AttributeSet attrs) {
        super(context, attrs);

          TypedArray b = context.obtainStyledAttributes(attrs,
                    R.styleable.ComboBox, 0, 0);

            CharSequence[] entries = b.getTextArray(R.styleable.ComboBox_myEntries);
            if (entries != null) {
                ArrayAdapter<CharSequence> adapter =
                        new ArrayAdapter<CharSequence>(context,
                                android.R.layout.simple_spinner_item, entries);
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                s.setAdapter(adapter);
            }
}

回答1:


I don't know if it's possible to do that with android:entries attribute unless your component extends Spinner, but I'm only guessing.

You can achieve that creating your own custom attribute in attrs.xml

<declare-styleable name="ComboBox">
    <attr name="myEntries" format="reference"></attr>
</declare-styleable>

Then you can access this reference (int) inside your component and set the ArrayAdapter into your spinner.

TypedArray customAttrs = context.obtainStyledAttributes(attrs, R.styleable.ComboBox);
    for (int i = 0; i < customAttrs.length(); i++) {
        int attrValue = customAttrs.getIndex(i);
        switch (attrValue) {
            case R.styleable.ComboBox_myEntries:
                mArrayId = customAttrs.getResourceId(attrValue, 0);
                ArrayAdapter<String> a = new ArrayAdapter<String>(this.getContext(),android.R.layout.simple_spinner_dropdown_item, mArrayId);
                s.setAdapter(a);
                break;
        }
    }

On your layout, add this line xmlns:app="http://schemas.android.com/apk/res/yourPackageName" below xmlns:android="http://schemas.android.com/apk/res/android" in the root view:

Then you can instantiate your component and custom attrs via xml:

<com.ics.spinn.ComboBox android:id="@+id/myautocombo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
app:myEntries="@array/suppliers" />
/>

Don't know if this answer is exactly what you're looking for but it would behave just like android:entries. Hope it helps.




回答2:


Try to load your array like this:

String[] array = getResources().getStringArray(R.array.recipes_string_array);

ArrayAdapter spinnerAdapter = new ArrayAdapter<String>(getActivity(), R.layout.simple_spinner_dropdown_item) {

    @Override
    public int getCount() {
       return array.length;
    }

    @Override
        public String getItem(int position) {
        return array[position];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //Create your item for the spinner and return it         
        return spinnerItemview; 
    }

}

spinner.setAdapter(spinnerAdapter);



回答3:


Joala's answer above is technically correct, but there is a much simpler way of expressing it.

Instead of iterating over the StyledAttributes you can just ask for the resourceId of the StringArray directly.

// Get the DisplayValues from the XML config.
final TypedArray customAttrs = getContext().obtainStyledAttributes(attrs, R.styleable.ComboBox);
final int resourceId = customAttrs.getResourceId(R.styleable.ComboBox_myEntries, -1);
if (resourceId == -1) {
    throw new IllegalArgumentException("ComboBox requires a myEntries attribute that points to a string-array resource");
}

final ArrayAdapter<String> a = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_spinner_dropdown_item, resourceId);
s.setAdapter(a);


来源:https://stackoverflow.com/questions/13747400/works-android-custom-component-access-array-in-strings-xml-supplied-via-layo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!