How to programmatically set custom attributes of custom components?

mz496 picture mz496 · Aug 28, 2015 · Viewed 12.7k times · Source

I have a custom component called CircleView, and I want to change a custom attribute called fillColor defined in attrs.xml:

<declare-styleable name="CircleView">
    <attr name="radius" format="integer" />
    <attr name="fillColor" format="color" />
</declare-styleable>

I have set it initially in my layout XML, which currently looks like this (namespace circleview is defined as xmlns:circleview="http://schemas.android.com/apk/res-auto"; it works fine when I define it in the XML, so this shouldn't be an issue):

<com.mz496.toolkit.CircleView
     ...
     circleview:fillColor="#33ffffff"/>

I can get the fillColor attribute just fine in my CircleView, which extends View, but I don't know how to set its value.

I've investigated things like setBackgroundColor and looked for other "set" methods, but I couldn't find any. I imagined a method like

circle.setAttribute(R.styleable.CircleView_fillColor, "#33ff0000")

Answer

mz496 picture mz496 · Aug 28, 2015

A CircleView in the layout is nothing more than an instance of the CircleView class, so simply add a function into CircleView.java:

public void setFillColor(int newColor) {
    fillColor = newColor;
}

And then call it whenever needed:

CircleView circle_view = (CircleView) findViewById(R.id.circle_view);
circle_view.setFillColor(0x33ffffff);
circle_view.invalidate();

Also note that this just changes an internal variable, but you still need to redraw the custom component using the invalidate() method of the View class, since the custom component is only redrawn automatically if the entire view is redrawn, e.g. when switching fragments (see: Force a View to redraw itself).

(I figured this out at the very end when I was just about to ask, "Would I need to define this myself?" And I tried defining it myself, and it worked.)