how to access custom attribute with multiple formats?

孤人 提交于 2019-12-07 03:02:36

问题


I read in another answer that in android you can declare attributes for your custom view that have multiple formats like this:

<attr name="textColor" format="reference|color"/>

how can I access these attributes in my class? Should I just assume it to be a reference, use getResources().getColorStateList() and then assume it to be a raw RGB/ARGB color if Resources.getColorStateList() throws Resources.NotFoundException or is there a better way of differentiating between the formats/types?


回答1:


It should be something like this:

Variant 1

public MyCustomView(Context context,
                    AttributeSet attrs,
                    int defStyleAttr,
                    int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    TypedArray typed = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyleAttr, defStyleRes);
    int resId = typed.getResourceId(R.styleable.MyCustomView_custom_attr, R.drawable.default_resourceId_could_be_color);
    Drawable drawable = getMultiColourAttr(getContext(), typed, R.styleable.MyCustomView_custom_attr, resId);
    // ...
    Button mView = new Button(getContext());
    mView.setBackground(drawable);

}

protected static Drawable getMultiColourAttr(@NonNull Context context,
                                             @NonNull TypedArray typed,
                                             int index,
                                             int resId) {
    TypedValue colorValue = new TypedValue();
    typed.getValue(index, colorValue);

    if (colorValue.type == TypedValue.TYPE_REFERENCE) {
        return ContextCompat.getDrawable(context, resId);
    } else {
        // It must be a single color
        return new ColorDrawable(colorValue.data);
    }
}

Of course getMultiColourAttr() method could be not static and not protected, this is up to the project.

The idea is to get some resourceId for this specific custom attribute, and use it only if the resource is not color but TypedValue.TYPE_REFERENCE, which should means that there is Drawable to be obtained. Once you get some Drawable should be easy to use it like background for example:

mView.setBackground(drawable);

Variant 2

Looking Variant 1 you can use the same resId but just pass it to the View method setBackgroundResource(resId) and the method will just display whatever stays behind this resource - could be drawable or color.

I hope it will help. Thanks




回答2:


In your /res/attrs.xml:

<declare-styleable name="YourTheme">
    <attr name="textColor" format="reference|color"/>
</declare-styleable>

In your custom view constructor, try something like that (I didn't run it):

int defaultColor = 0xFFFFFF; // It may be anyone you want.
TypedArray attr = getTypedArray(context, attributeSet, R.styleable.YourTheme);
int textColor = attr.getColor(R.styleable.YourTheme_textColor, defaultColor);


来源:https://stackoverflow.com/questions/28179111/how-to-access-custom-attribute-with-multiple-formats

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