We have our custom view that adapts to multiple sizes now; that's good, but what happens if we need another custom view that paints the background blue instead of red? And yellow? We shouldn't have to copy the custom view class for each customization. Luckily, we can set parameters on the XML layout and read them from our custom view:
- First, we need to define the type of parameters we will use on our custom view. We've got to create a file called attrs.xml in the res folder:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="OwnCustomView"> <attr name="fillColor" format="color"/> </declare-styleable> </resources>
- Then, we add a different namespace on our layout file where we want to use this new parameter we've just created:
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/activity_vertical_margin"> <com.packt.rrafols.customview.OwnCustomView android:layout_width="match_parent" android:layout_height="wrap_content"
app:fillColor="@android:color/holo_blue_dark"/>
</LinearLayout> </ScrollView>
- Now that we have this defined, let's see how we can read it from our custom view class:
int fillColor;
TypedArray ta =
context.getTheme().obtainStyledAttributes(attributeSet,
R.styleable.OwnCustomView, 0, 0);
try {
fillColor =
ta.getColor(R.styleable.OwnCustomView_ocv_fillColor,
DEFAULT_FILL_COLOR);
} finally {
ta.recycle();
}
By getting a TypedArray using the styled attribute ID Android tools created for us after saving the attrs.xml file, we'll be able to query for the value of those parameters set on the XML layout file.
In this example, we created an attribute named fillColor that will be formatted as a color. This format, or basically, the type of the attribute, is very important to limit the kind of values we can set, and how these values can be retrieved afterwards from our custom view.
Also, for each parameter we define, we'll get a R.styleable.<name>_<parameter_name> index in the TypedArray. In the preceding code, we're querying for the fillColor using the R.styleable.OwnCustomView_fillColor index.
Let's see the results of this little customization:
![](assets/a9126c6f-80b6-489a-8525-aebfd9ecb311.png)
We've used color in this specific case, but we can use many other types of parameters; for example:
- Boolean
- Int
- Float
- Color
- Dimension
- Drawable
- String
- Resource
Each one has its own getter method: getBoolean(int index, boolean defValue) or getFloat(int index, float defValue).
In addition, to know if a parameter is set we can use the hasValue(int) method before querying or we can simply use the default values of the getters. If the attribute is not set at that index, the getter will return the default value.
For the full example, check the Example04-Parameters folder in the GitHub repository.