how to access custom attribute with multiple formats?

狂风中的少年 提交于 2019-12-05 07:56:40

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

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