Android custom view obtain multiple attributes

删除回忆录丶 提交于 2021-02-05 07:57:22

问题


I am creating a custom view in Android. In it's constructor I am obtaining some of the attributes that are set in the XML layout file. The code is like this:

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

    TypedArray styledAttrs = context.getTheme().obtainStyledAttributes(attrs, new int[] { android.R.attr.id, android.R.attr.digits, android.R.attr.padding, android.R.attr.inputType }, 0, 0);
    try {
        int id = styledAttrs.getResourceId(styledAttrs.getIndex(0), -1);
        String digits = styledAttrs.getString(styledAttrs.getIndex(1));
        float padding = styledAttrs.getDimension(styledAttrs.getIndex(2), 0.1f);
        int inputType = styledAttrs.getInt(styledAttrs.getIndex(3), -1);
    } finally {
        styledAttrs.recycle();
    }
}

The problem is that obtainStyledAttributes does not obtain all the attributes, even though they exist in the attribute set. What's even stranger, is that if I change the ordering of the ids in the int array I get different results. For example, if I use the following ordering

new int[] { android.R.attr.id, android.R.attr.digits, android.R.attr.padding, android.R.attr.inputType }

I get back 3 attributes, but if I use the following ordering

new int[] {android.R.attr.digits, android.R.attr.padding, android.R.attr.inputType, android.R.attr.id }

I get back 2. I'm including 2 screenshots of the watches window of these 2 cases. The breakpoint is set just after the try statement.

In any case if I obtain the attributes one at a time, it works for all of them. How does obtainStyledAttributes works? Also I'm not sure if I should use the styledAttrs.getIndex(i) function or not, but that is a problem after the current one is solved.


回答1:


Although it is not documented, obtainStyledAttributes expects a sorted array, and its code is optimized with that assumption.

So you need to provide your styledAttrs array with the elements sorted in ascending order according to their id values.

There are several ways you can determine the correct order:

  • based on their relative position in the resources
  • by checking their relative values and changing the array to match
  • or by sorting the array elements programmatically

If you choose to sort the array programmatically at run time, make sure you use the appropriate (sorted) index when calling getString() etc.

Another common workaround is to only get a single value with obtainStyledAttributes at a time. (An array with one element is already sorted.)

Also I'm not sure if I should use the styledAttrs.getIndex(i) function or not

I believe that's only necessary if you're looping through the TypedArray and its possible some of the elements may not have values; it basically "hides" the null elements for you as though it were a sparse array. In general I don't think it's necessary unless you're accessing styled resources in certain ways, for example when implementing a custom view.

Most of the time I use custom theme attributes that aren't related to a view at all, and in those cases I've always found TypedArray.getIndex() to be redundant.



来源:https://stackoverflow.com/questions/32273576/android-custom-view-obtain-multiple-attributes

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