How do I declare an Android UI element using XML?
In Android, the XML is used to implement UI-related data, and it's a lightweight markup language that doesn't make layout heavy.
While you can modify the Android source code to customize the System UI, doing so makes it more difficult and complex to apply future Android updates. Instead, Android supports the use of an overlay directory, which enables you to replace resource files without modifying the source code.
UsiXML (which stands for User Interface Extensible Markup Language) is an XML-compliant markup language that describes the UI for multiple contexts of use such as Character User Interfaces (CUIs), Graphical User Interfaces (GUIs), Auditory User Interfaces, and Multimodal User Interfaces.
So, this is how you create your own custom component in a few simple steps: Create the XML layout and style it to suit your needs. Derive your component class from the appropriate parent component, according to your XML layout. Add your component's business logic.
The Android Developer Guide has a section called Building Custom Components. Unfortunately, the discussion of XML attributes only covers declaring the control inside the layout file and not actually handling the values inside the class initialisation. The steps are as follows:
values\attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyCustomView"> <attr name="android:text"/> <attr name="android:textColor"/> <attr name="extraInformation" format="string" /> </declare-styleable> </resources>
Notice the use of an unqualified name in the declare-styleable
tag. Non-standard android attributes like extraInformation
need to have their type declared. Tags declared in the superclass will be available in subclasses without having to be redeclared.
Since there are two constructors that use an AttributeSet
for initialisation, it is convenient to create a separate initialisation method for the constructors to call.
private void init(AttributeSet attrs) { TypedArray a=getContext().obtainStyledAttributes( attrs, R.styleable.MyCustomView); //Use a Log.i("test",a.getString( R.styleable.MyCustomView_android_text)); Log.i("test",""+a.getColor( R.styleable.MyCustomView_android_textColor, Color.BLACK)); Log.i("test",a.getString( R.styleable.MyCustomView_extraInformation)); //Don't forget this a.recycle(); }
R.styleable.MyCustomView
is an autogenerated int[]
resource where each element is the ID of an attribute. Attributes are generated for each property in the XML by appending the attribute name to the element name. For example, R.styleable.MyCustomView_android_text
contains the android_text
attribute for MyCustomView
. Attributes can then be retrieved from the TypedArray
using various get
functions. If the attribute is not defined in the defined in the XML, then null
is returned. Except, of course, if the return type is a primitive, in which case the second argument is returned.
If you don't want to retrieve all of the attributes, it is possible to create this array manually.The ID for standard android attributes are included in android.R.attr
, while attributes for this project are in R.attr
.
int attrsWanted[]=new int[]{android.R.attr.text, R.attr.textColor};
Please note that you should not use anything in android.R.styleable
, as per this thread it may change in the future. It is still in the documentation as being to view all these constants in the one place is useful.
layout\main.xml
Include the namespace declaration xmlns:app="http://schemas.android.com/apk/res-auto"
in the top level xml element. Namespaces provide a method to avoid the conflicts that sometimes occur when different schemas use the same element names (see this article for more info). The URL is simply a manner of uniquely identifying schemas - nothing actually needs to be hosted at that URL. If this doesn't appear to be doing anything, it is because you don't actually need to add the namespace prefix unless you need to resolve a conflict.
<com.mycompany.projectname.MyCustomView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/transparent" android:text="Test text" android:textColor="#FFFFFF" app:extraInformation="My extra information" />
Reference the custom view using the fully qualified name.
If you want a complete example, look at the android label view sample.
LabelView.java
TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView); CharSequences=a.getString(R.styleable.LabelView_text);
attrs.xml
<declare-styleable name="LabelView"> <attr name="text"format="string"/> <attr name="textColor"format="color"/> <attr name="textSize"format="dimension"/> </declare-styleable>
custom_view_1.xml
<com.example.android.apis.view.LabelView android:background="@drawable/blue" android:layout_width="fill_parent" android:layout_height="wrap_content" app:text="Blue" app:textSize="20dp"/>
This is contained in a LinearLayout
with a namespace attribute: xmlns:app="http://schemas.android.com/apk/res-auto"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With