Adding custom attributes to a view in android (through XML)
Very often we come to situations where we need to add a custom ability to a view in android, for example, say we need to set typeface to our text views. Of course, we can do this from our Java code also but to me its easier to add this in the XML [Because after just one-time setup, we need to add just one line of code].
Proceeding with the above scenario, let us now begin the thing. To begin, go to /res/values/attrs.xml and declare your custom styleable over there as follow
<declare-styleable name="CustomTextView">
<attr name="customTypeface" format="integer"/>
</declare-styleable>
As we can see, I have made a custom styleable, the name of which would be the name of my custom view class (convention, not mandatory, which I am gonna explain below). The attribute name is the name of the custom field using which you would like to set the custom attribute. Notice that we have used a field named “format.” Now “format” can be one of these [integer, boolean, color, boolean, flag, etc]. But my requirement needs it to be an integer. You can have your own.
Now we need to make a class that would extend the view on which you want to be able to add a custom attribute.
In my case, since its a TextView, I have made a class named as CustomTextView which extends TextView as shown below
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.TextView;
import yourPackageName.R;
public class CustomFontTextView extends TextView {
private int typefaceType;
private Typeface typeface;
public CustomFontTextView(Context context) {
super(context);
init(context);
}
public CustomFontTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomFontTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public CustomFontTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomFontTextView, 0, 0);
try {
typefaceType = ta.getInt(R.styleable.CustomFontTextView_customTypeface, 0);
} finally {
ta.recycle();
}
initTypeface(context);
}
private void init(Context context) {
initTypeface(context);
}
private void initTypeface(Context context) {
//You logic to use the variable typefaceType and accordingly set the typeface
super.setTypeface(typeface);
}
}
As we can see that in the class CustomTextView, all of my constructors except the first one( since it does not receive any attribute), call the function
private void init(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomFontTextView, 0, 0);
try {
typefaceType = ta.getInt(R.styleable.CustomFontTextView_customTypeface, 0);
} finally {
ta.recycle();
}
initTypeface(context);
}
private void init(Context context) {
initTypeface(context);
}
In the above function, We try to fetch the styled attributes for our custom styleable “CustomFontTextView” and using we can fetch the value provided by the user in his XML layout as shown below.
<yourPackageName.CustomFontTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="My text view with custom typeface"
android:textAlignment="center"
app:customTypeface="1"
/>
As you can see I have used the attribute customTypeface=1 to inform my class that I want this text view to have a typeface of type 1.
That’s all and we are done, creating a view that could set its typeface via XML.