Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring a custom android UI element using XML

How do I declare an Android UI element using XML?

like image 206
Casebash Avatar asked Apr 23 '10 01:04

Casebash


People also ask

Is XML used for UI?

In Android, the XML is used to implement UI-related data, and it's a lightweight markup language that doesn't make layout heavy.

Can you customize Android UI?

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.

What is UI in XML?

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.

What are different ways to implement a custom UI component in Android?

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.


1 Answers

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:

1. Declare attributes in 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.

2. Create constructors

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.

3. Use it in a layout files such as 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.

Android LabelView Sample

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"

Links

  • StackOverflow Thread: Retrieving an XML attribute for custom control
  • How do I use obtainStyledAttributes with internal themes of Android
  • Defining custom attributes + list of supported attribute formats
like image 117
Casebash Avatar answered Sep 17 '22 18:09

Casebash