Android UI: From XML to Touchable Screens
How do the XML elements in the XML file become View objects? The answer starts in the Activity class.
Inflating the UI: Behind the Scenes
When creating a new Android project, a pre-generated subclass of Activity known as MainActivity is automatically provided. This MainActivity class file can be located in the app/java directory of your project. Within this class, you’ll find a function known as onCreate(Bundle?).
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) // Inflating the XML layout
}
}
The onCreate(Bundle?) function is called when an instance of the activity subclass is created. when an activity is created, it needs a UI to manage. To give the activity its UI, you call Activity.setContentView(layoutResID: Int).
This setContentView function essentially performs the act of inflating a layout and presenting it on the screen. The term "inflating" refers to the process of translating the XML layout file into actual View objects. Within this layout, each view component (be it a TextView, Button, ImageView, or others) is instantiated based on its defined attributes. You specify which layout to inflate by passing the layout’s resource ID.
Resources and resource IDs
In Android, resources are pieces of your app that aren’t code — like images, audio, and XML files. These live in the app/res directory. For instance, your layout file, such as activity_main.xml, is in res/layout/, and strings are in res/values/.
To access these resources in your code, you reference them by their resource ID. The ID for your layout is automatically generated during compilation, like R.layout.activity_main. You don't create this ID yourself; the build process does it for you.
Understanding the R Class: Your Resource Map
During the compilation and packaging of your app, the build tools generate a class known as the R class. This class contains a long list of IDs as integer constants, allowing you to access and use your resources in your application. when referencing R.layout.activity_main, you are actually referencing an integer constant named activity_main within the layout inner class of R.
Here is an exmaple of what R class looks like:
public final class R {
public static final class layout {
public static final int activity_main = 2131230762;
// Other layout resource IDs...
}
public static final class values {
// Other value resource IDs...
}
// More resource categories...
// For example, you might have:
public static final class drawable {
public static final int ic_launcher = 2131230720;
// Other drawable resource IDs...
}
public static final class raw {
public static final int audio_sample = 2131230721;
// Other raw resource IDs...
}
// Add more categories based on your app's resources...
}
Just remember, as you add, change, or remove resources, the build process keeps this R class up-to-date, maintaining the correct mapping between your resources and their IDs. It's like a handy map that helps your code find and use the different parts of your app.
Manually Assigning Resource IDs
In Android, every user interface (UI) screen you create gets a unique identifier called a “resource ID.” This ID helps Android know which screen to display. However, this resource ID is assigned to the entire screen as a whole.
Now, when you design a screen with various elements like text boxes or buttons, Android doesn’t automatically create unique IDs for each of these elements. Not every element needs its own ID; it depends on whether you want to interact with it in your code.
If you do want to interact with a specific element in your code, you can manually assign it a unique resource ID by using the android: id attribute in the XML layout file. This attribute lets you give a special tag to individual views within the layout.
Here’s an example in XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- This TextView gets its own resource ID -->
<TextView
android:id="@+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!" />
<!-- This Button also gets its own resource ID -->
<Button
android:id="@+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!" />
</RelativeLayout>
In this example, @+id/myTextView and @+id/myButton are manually assigned resource IDs to the TextView and Button, respectively. This allows you to refer to and manipulate these specific elements in your code. The Android system won't generate these IDs automatically; you decide which elements need them based on your coding needs.
Getting references to views
Once you’ve inflated your XML layout, and possibly assigned resource IDs to specific views within that layout, the next step is to get references to these inflated view objects in your code. This process is important for interacting with and manipulating the UI elements programmatically.
Here’s how you can get references to inflated view objects in your Activity or Fragment:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Getting references to inflated view objects
val textView: TextView = findViewById(R.id.myTextView)
val button: Button = findViewById(R.id.myButton)
// Now you can interact with these view objects
textView.text = "Greetings, Android!"
button.setOnClickListener {
// Handle button click
Toast.makeText(this, "Button clicked!", Toast.LENGTH_SHORT).show()
}
}
}
In this example, findViewById() is used to get references to the inflated TextView and Button. This method searches for the specified resource ID within the layout and returns the corresponding view object. Once you have these references, you can manipulate their properties, add event listeners, or perform any other operations as needed in your code.
In this article, we’ve explored the core of Android UI, clarifying the process through which XML files and elements seamlessly transform into View objects. We’ve uncovered the role of the R class as a map, guiding the app to access various resources. Additionally, we’ve explained how individual views, like buttons and text elements, come to life within the UI, ensuring a clear understanding of the dynamic interplay between XML and the Android framework.