During this chapter, we will take a closer look at how Android’s XML capabilities allow application developers, and more importantly, application designers, to define their Android 7 application user interface (UI) design , styles, themes, constants, permissions, icons, activities, services, and how they function within the Google Play e-storefront, all without having any knowledge of Java programming. Of course, I am going to teach you Java programming in this book, starting with the next chapter, but you could hire people to do just Android 7 design, and all they would have to know is how to use the XML and Visual Design Editor features that we are going to learn about during this chapter. It is important to note that these same XML concepts that you will be learning in this chapter apply to both the 32-bit Android 4.4.4 OS as well as to the 64-bit Android 5.0, 5.1, 6.0, 7.0, and to the new Android 7.1.1 OS.
In the previous chapter, you created the foundation for your Hello World bootstrap Android application using the Android Studio 2.3 (IntelliJ 2016) New Android Application series of dialogs. As part of this new application creation process, more than half a dozen XML definition files were created. We are going to review all of these XML files during this chapter, as well as show you how to add features to them and refine them. We will do this so that you can learn the basics of XML implementation, and also to show you how to visually design user interfaces, add text constant values, create styles using Android themes (high-level Android OS user interface element styles), set your screen layout dimensions, request your Android application permissions, and define your Java 8 code module configuration. These last two are done using the Android Manifest XML definition. All this can easily be implemented using only XML, or eXtensible Markup Language, once you know the rules of the XML game in Android 7.x.
We will again take a closer look at all of the basic Android application components that are defined using XML in your bootstrap project during this chapter; but this time, instead of doing this by looking at the Android Studio application (app) resource (res) folder structure, we will do this by looking at the XML files themselves. We will be learning about the Android Manifest XML definition file and its functions, structure, and its role in defining and controlling how your application will work within the Android OS. It is important to note that the AndroidManifest.xml application characteristics definition file works in exactly the same way, whether you are developing for 32-bit Android 4.4.4 OS devices, or for 64-bit Android 5.0 through 7.1.1 OS devices. We’ll also look at the Android Studio Visual Design Editor.
As you progress in your knowledge of Android – in this chapter, this will be your knowledge of XML – you will continue to enhance the application foundation that you put into place in Chapter 3, and will continue to do so during each chapter in the book, learning the fundamental capabilities of Android OS, as well as the Android Studio 2.3 IDE in the process.
Extensible Markup Language: XML Overview
XML stands for eXtensible Markup Language. Extensible means that you can use it for whatever you like (think “customizable”). You could in fact create your own set of XML tags for any purpose that you wish. It is a markup language, because it uses simple “tags” to define what you wish to do. Most of you will be familiar with another markup language called HTML5, or Hypertext Markup Language V5, which is used for creating HTML5 websites, and more recently, for creating HTML5 applications .
Markup languages differ from programming languages, in that they use tags, parameters (also called attributes or characteristics) within these tags, and nesting structures to accomplish tasks that high-level programming languages, such as Java 8, will implement using complex programming structures like data arrays, logic loops, and method calls. We will be getting into Java 8 and these types of Java constructs in Chapter 5’s Java primer. You’re really learning two programming languages: one that uses code, and the other that uses markup, and how they work together in Android Studio, during this book .
The reason for this approach, that is, using XML for everything that could possibly be construed as being design oriented, is that using XML frees the members of your application development team who are designing your application’s usability, feature access, user interface, user experience, styles, theme, graphics, and the like, from having to learn (that is, understand) how Java 8 programming works.
As you will soon see, when you compare this chapter to the next one on Java, XML markup is an order of magnitude easier to learn and implement than Java 8 programming structures and concepts are. For this reason, during this Absolute Beginners book, I’m going to implement everything that I possibly can using XML markup, including using the parts of Android Studio where you can “drag and drop” components into the Visual Design Editor, and have Android Studio write your XML markup for you, which is a great way to learn XML markup as you design user interfaces. I will do this so that I can quickly get you to an intermediate level of 32-bit Android 4.4.4 and 64-bit Android 5.0 through 7.1.1 application development in this book in less than 600 (dense) pages of learning material.
Although I’d like to take all the credit for this book being able to take you so very far from being an Absolute Beginner (zero Android app development experience) to an Android developer, the primary reason this is possible is because Google Android OS developers made sure the advanced, “front-facing” features, which allow you to ratchet up the “wow-factor” for your applications, can be designed and implemented almost entirely using XML, often using only a few lines of Java programming logic!
Some examples of advanced Android design-related features that you can implement primarily using XML markup “definitions” include multi-state graphics, skinned UI elements (custom graphic design User Interface elements), frame or bitmap image animation, vector or “tween” (procedural) animation, user interface layout design animation (UI property animator), options menus, pop-up menus, and context-sensitive menus, dialog boxes, alert dialogs, styles, themes, and your application’s manifest.
You can also implement less advanced, strategic design features using XML, including string (text) constant values for your app, integer (numeric) value constants, state or status (Boolean) value constants (such as on or off, visible or hidden, true or false), and screen spacing (dimension) values for your UI designs. Arrays, which are collections of data used in your app (like a simple database), can also be created, and loaded with their data values, by using XML files. Again, remember that all of this holds true for XML in 32-bit Android 4.4.4 devices and for 64-bit Android 5.0 through 7.1.1 devices.
XML markup is contained in simple text format files identified using the .xml file extension. You can create XML files in a text editor, such as Windows Notepad; however, most programmers usually use a software editing tool with programming and markup design features, such as Eclipse, IntelliJ, and NetBeans. These XML files can then be read or “parsed” by the Android OS, or your application Java code, and turned into Java object structures using an XML “data or object definition” in each XML file.
XML Naming Schema: Tag and Parameter Repository
XML is comprised of “tags” and their “parameters.” Parameters are part of the tags, and are used to configure and fine-tune what each of these tags accomplishes, as well as to reference any new media assets, or text fonts, or color values, or styles, or themes, or other XML definitions, and similar Android application assets that might be required to “skin,” or otherwise define how that application user interface element will appear, or “render,” relative to your users’ Android device display screen .
XML tags and parameters that you can use in any particular design framework, such as in Android 7.1.1 development, are specified by using an XML “ naming schema.” This definition of the XML tags and their parameters are stored in a centralized repository, similar to the one Android Studio accessed in Chapter 2, when you did a Check for Updates function; or Chapter 3, when I updated Android 7 to API 24.0.1, or when you update the Android 7.1.1 API 25 to the next version coming in late 2017.
The SDK repository hosts the latest Android SDK versions and code base, whereas the Android XML repository is located at a different URL location (a different folder) on Google’s Android OS servers. The reason XML needs to have a naming schema is because this language is inherently designed to be “extensible.” This means there is no “standard” version of XML; each version is customized for some required implementation (end use) by whatever person or organization needs to use it. The process of making sure that XML tags and their attributes or parameters are correct, or valid and in conformance with their XML definition, is called XML validation.
Android XML has been specifically customized for, and implemented for, the development of Android applications. For example, Android OS developers created the XML tag named <ConstraintLayout> for UI design using Constraint Layouts. The ConstraintLayout Java class was introduced in Android 7, as an improvement to the Android RelativeLayout Java class, which was covered in my previous three editions of this book (and still exists in the SDK), and was specifically designed to work hand-in-hand (code-in-code) with the drag and drop Layout Editor in Android Studio 2.3. Since this is an Absolute Beginner title, we will be showing you how to use the Layout Editor and ConstraintLayout class together, so that you can use Android Studio 2.3 for visual design rather than writing XML markup.
The XML naming schema is referenced inside of each of your XML definition files, at the very top, as you’ll see in Figure 4-1, in the first two lines of XML markup in the central editing pane of Android Studio. This is done so that the XML markup inside of your XML file can reference its XML naming schema.
Figure 4-1. The contents of the activity_main.xml file in the app/res/layout folder in the Android Studio middle editing pane
Android Studio does not need to validate the XML file in “real time”, so you do not need an active Internet connection to be able to develop the XML markup.
In any custom extensible markup language, such as the one that has been created by Google for Android, the XML version is declared on the first line, and the naming schema URL reference needs to be contained in the first outermost parent tag, which is most always the second line of XML markup. The following lines of XML markup from Figure 4-1 declare XML and the XML naming schema, abbreviated as XMLNS, as well as configuring the ConstraintLayout Java class characteristics using attributes or parameters inside of the parent <ConstraintLayout> tag:
<?xml version="1.0" encoding="utf-8" ?>
< android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.myapplication.MainActivity" >
This parent layout container tag will usually contain other child tags, which are nested inside of, and underneath, the opening parent tag. This nesting of child tags, as well as nesting parameters inside of the tag, can more easily seen if the XML programmer uses indenting to show which tags are inside of other higher-level (parent) tags, as I have done in the above markup, and which Android Studio has done as seen in Figure 4-1 in the activity_main.xml editor tab in the middle of the screen.
Let’s take a look at the Constraint Layout UI design in the activity_main.xml file, which Android Studio created for you as the UI layout foundation to start building your UI design upon for the MyApplication Hello World Android application. As seen in Figure 4-1, the first line of the parent <ConstraintLayout> UI layout container tag has xmlns:android=" http://schemas.android.com/apk/res/android " as its first parameter. This parameter defines the XML naming schema repository for Android 7 as being in the schemas virtual server, on an android.com HTTP address, in an /apk folder, in a /res subfolder, and finally in an /android sub-subfolder.
In this case the <ConstraintLayout> container is the parent tag and the xmlns:androidis one of the parameters that configures this tag. This parameter will allow this UI layout tag to reference the XML naming scheme repository, and defines the prefix android as a markup shortcut to reference this repository. Note that just because it references the proper XML definition repository does not mean that it is connecting in real time to check this repository, as I pointed out earlier (it is used as a unique identifier). As you can see inside of the <ConstraintLayout> tag, there are a significant number (three) of parameters that start with android: and what this android: reference equates to, as it is defined by that first xmlns:android parameter. Essentially, what is happening here, is that this xmlns:android parameter is defining a shortcut for all the other parameters that start with android: to be able to check themselves against the XML naming schema repository. Thus, because of the xmlns:android URL definition parameter, the android:width="match_parent" parameter is actually shorthand for an http://schemas.android.com/apk/res/android:width="match_parent" parameter.
The same code-replacement logic would apply to the xmlns:tools parameter in conjunction with your tools:context="com.example.user.myapplication.MainActivity" <ConstraintLayout> parameter, also seen in Figure 4-1. An XML tools parameter sets the context for the ConstraintLayout definition as the MainActivity class, which Android Studio created for you, using the New Android Application dialogs.
As you can see here, Android OS really has three XML naming schemas (language definitions), in three different software repositories, as there is also one that defines an app: shortcut that you can see is used inside of the <TextView> child tag inside of the <ConstraintLayout> parent tag. This is set to xmlns:app=" http://schemas.android.com/apk/res-auto " and is used in four app:layout_constraint parameters. The Android Package APK naming schema was designed for high-level, design-oriented XML and is at schemas.android.com/apk. It is also the XML naming schema you will be using 99% of the time in your Android application development, and the one I will be covering throughout this book.
The Android Tools (tools) naming schema was created to provide low-level (OS-related usage) XML, and is at schemas.android.com/tools. You can use it to do things such as declare the Context object using XML. You’ll learn more about Context objects during Chapter 14, when I cover Android Service class concepts and structures, as well as when we encounter Context objects. This Context object here defines the context for the ConstraintLayout class UI design as your MainActivity activity class, which is obvious as context is set to the MainActivity class in your com.example.user.myapplication Android project, as can be seen in Figure 4-1, and in the previous XML markup example.
XML Syntax: Containers, Brackets, and Nesting
There are two ways to code (or to mark up, to be more precise) any XML tag, and which markup approach you use depends upon whether that tag is going to have any children (nested tags) or not. Attributes, also known as parameters, are inside of each tag and configure the tag and what it will do. Parameters would not be considered children of the tag, but are attributes specifying values or references customizing the tag. Parameters will use quotation marks to do this, such as the android:text="data value" parameter, which we’ll be changing shortly to more closely follow Android design conventions.
If an XML tag is a parent tag (which it is if it has “nested” or child tags inside of it), it can be said to be a container, just like the XML file itself is the container for that entire XML construct, which Android uses for data or Java object definition of one type or another, as you will see throughout this chapter, as well as throughout the rest of this book.
Fortunately the bootstrap UI layout design seen in Figure 4-1 shows both of these types of bracketing treatments, so I can simply describe the usage here, and you can observe it in Figure 4-1 or in Android Studio if you have it running on your computer workstation , which I am hoping you do.
Since the <TextView> UI element that defines a Text User Interface element on the screen (as you might have guessed) stands alone; has zero children; and has parameters configuring width, height, and text content, this tag is opened using the <TextView portion of the tag, and is closed using the /> character sequence. Tags that contain other tags are closed using only the right-chevron > bracket.
So, with android and app parameters inside of this TextView tag, your tag structure will look like this:
<TextView android:parameter="value" app:parameter="value" />
The XML for this child tag, which is shown in Figure 4-1 and below in full, uses indentation for easy parameter views, as well as setting Android Text class constants that you will learn about in the next chapter covering Java. The android:text parameter references a Java String directly setting a text data value in quotes. I will be showing you how to use a text String constant in your strings.xml file a bit later on during this chapter, which is really how things should have been set up initially by Android Studio.
For now, we are just going to look at the syntax of XML—that is, how it needs to be constructed or structured (written on the screen). We will look at how it all works together in the next section of this chapter. Since your <ConstraintLayout> tag does indeed have a child <TextView> tag nested inside it, it will use a different (parent) bracket configuration. Using high-level pseudo-code, it looks like this:
<android.support.constraint.ConstraintLayout xmlns:parameter="value" android:parameter="value" >
<TextView android:parameter="value" app:parameter="value" />
</ConstraintLayout>
Once you put parameters inside of the parent and child tags, and indent everything, so that you know what level each of these tags and its parameters are supposed to be at, it will look exactly like what you see in Figure 4-1, which I will replicate below. We will be going over what all of this XML markup is doing during this chapter, as well as using the Visual Design Editor to add User Interface elements to it. Since an entire book could be written on XML (and has, such as my 2014 Pro Android UI title from Apress), this will be one of the longer chapters in the book, as a significant percentage of what your application looks like, and what it is allowed to do via the Android OS, will ultimately be defined using XML markup definitions.
<?xml version="1.0" encoding="utf-8" ?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.myapplication.MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
app:layout_constraintBottom_toLeftOf="@+id/activity_main"
app:layout_constraintBottom_toRightOf="@+id/activity_main"
app:layout_constraintBottom_toTopOf="@+id/activity_main" />
</android.support.constraint.ConstraintLayout>
In summary, any tag that you will use as a parent tag will have an opening tag; in this case that is the <ConstraintLayout> tag, and its paired closing tag </ConstraintLayout> with the tag name in both the opening and the closing tag. The closing tag will have a slash in front of the tag name to signify to the XML parsing engine (the code that is interpreting the XML markup and turning it into something else; in this case, Java objects, data constants, and data variables) that this is the closing tag.
Alternatively, the child tag that has no children of its own will have the closing slash at the end of the opening tag, like this: <TextView android:parameters app:parameters /> which allows a much more compact way of writing a child tag. You might think of this as an implicit closing tag, so a tag with no child tags nested inside of it, will not have an explicit closing tag, or a backslash in front of the tag name inside of < > chevron bracketing like the </ConstraintLayout> UI layout container has. Since a layout container will always inherently be a container it will always have child tags, and therefore UI layout container tags will always have an explicit closing tag at the bottom of the XML definition. It is important to note, nesting can be more than one level deep, so you can have the following structure:
<ConstraintLayout>
<LinearLayout>
<TextView android:parameter="data value" />
<ImageView android:parameter="data value" />
<TextView android:parameter="data value" />
</LinearLayout>
</ConstraintLayout>
As you can see, the explicit closing tags must be in the reverse order from the opening tag order, so that the XML tag structure exhibits the proper nesting for the parsing engine within its level hierarchy.
XML Referencing: Chain XML Constructs Together
XML files can also reference other XML files, so that you can create a chain where XML definitions can be modular , since they can be blocks of code that can be used by more than one XML construct. XML file referencing is somewhat akin to XML tag nesting, but it spans across files. XML referencing in Android is done by using an @ symbol, which is specific to Android XML file referencing syntax .
Android uses the @ character to signify that another XML file is being referenced, as you will see over the rest of the chapter, as we look at how to use XML markup, to define values, dimensions, strings, styles, themes, and your Android Manifest, which defines everything regarding your application.
Without this referencing capability XML markup would end up being all lumped together in one or two massive files. Referencing allows an XML structure to be created, such as the XML structure for your Hello World bootstrap application, which the Android Studio IDE put into place for you using the New Android Application Project series of dialogs.
We’ll be looking at your application’s current XML structure, and all of the files within it, as well as how these XML files reference each other. We will also be looking at how to change tag parameter values within these XML files in order to customize an Android application during the remainder of this book.
Once we’re all finished looking at each of the XML files that are currently in your bootstrap project, I’ll include a visual of how all of these go together to for the foundational XML structure for your Android application that Android Studio created for you in Chapter 3. If you want to cheat and look ahead in this chapter, you can go ahead and take a quick peek; the visual is in Figure 4-11.
Let’s take a closer look at the strings.xml file located in the app/res/values folder first, as this is one of the most often used XML files in Android application development, and one we’ll be adding to soon.
Open the app/res/values folder by clicking the right-facing arrow next to it. Find and right-click on the strings.xml file, and select the Jump to Source option from the context-sensitive menu. This is how you open an editing tab for a file you want to view or edit in the Android Studio 2.3 central editing pane, so if you are used to a File Open, or a File Edit, context menu sequence, then pay close attention to this!
As you can see in Figure 4-2, the strings.xml file does not need to reference the XML repository URL, as it just contains resource constant definitions, using the parent <resources> tag, and, in this case, child <string> tags defining each string data value and giving the value a (variable) name. We will get into variables in Chapter 5. The reason this file doesn’t require an xmlns:android XML naming schema definition at the top of the XML definition is because the attributes (parameters) used inside of the child tags in this file do not preface themselves with something else (such as app: or android: or tools: for instance, which require xmlns:app, xmlns:tools, or xmlns:android repository definition parameters).
Figure 4-2. Right-click on the strings.xml file located in the app/res/values folder, and select Jump to Source from the menu
Notice in Figure 4-2 and the line of code below the XML markup uses name="app_name" and not android:name="app_name". If you needed to use android:name="app_name" then you would need the xmlns:android XML name schema definition in the top of the definition (resource tag) before you used this parameter naming convention.
The way a <string> child tag defines a string (text) variable is that the name parameter is used as the parameter in the first part of the string value XML definition. This defines a string variable name, and the actual text data value for a string goes inside of the <string>text data</string> as you can see in Figure 4-2. The app_name string XML definition would thus be:
<string name="app_name">My Application</string>
Next, we will add an app_message string constant with the data “Hello World” in it, because we want to collect all the string constants in one place, so we can customize the application text in one place.
XML Constants: Adding New Constants Using XML
Since the “Hello World!” message is “hard-coded” in the activity-main.xml UI layout XML definition, I will show you how to change this to a string constant value in the strings.xml file that is referenced from the activity_main.xml file using the @ character. Why Android Studio did not follow text constant convention, and install this in the strings.xml file, I do not know (previous versions of Android did set all of the bootstrap application text constants up in this way). I will simply take this as an opportunity to teach you in a more “hands-on” way how to do this, so you can experience inter-XML file referencing.
Select the entire first <string> child tag construct, and either use CTRL-C (Copy) and then CTRL-V (Paste), or right-click the selection and select Copy, and then click in the beginning of the line the <string> tag is on, and right-click and select Paste. This will give you two identical <string> constant constructs, and you can edit the second one to name it app_message with a data value of Hello World, as can be seen in Figure 4-3. Notice we are using Hello World without the exclamation point, so we can see the change, as well as when Android Studio renders that change in the Preview pane on the right-hand side, which will be visible in Figures 4-4 and 4-5.
Figure 4-3. Add a string constant named app_message with the Hello World data value underneath the app_name constant
Figure 4-4. Edit activity_main.xml and change the <TextView> android:text parameter to reference a new @string constant
Figure 4-5. Zoom in 33% in the Preview pane to make sure the new referencing is working with a new Hello World message
Once your strings.xml file looks like the following XML markup, click the activity_main.xml editing tab.
<resources>
<string name="app_name">My Application</string>
<string name="app_message">Hello World</string>
</resources>
In the <TextView> child tag android:text parameter value area, remove Hello World! and type in @string. As you can see in Figure 4-4, Android Studio will give you a drop-down selector containing all the current constant values which are currently in the strings.xml file in the app/res/values folder .
Select the @string/app_message constant, as seen in Figure 4-4, under the line of markup that you are editing. Notice that Android names the String constant XML definition file strings.xml (more than one String is usually in this file) but it references it using @string only (no “s” at the end). Also notice that while you are editing this change, the preview on the right shows the previous (hard-coded) text value. Once you select the app_message String constant, the preview on the right shows the new Hello World without the exclamation point. This can be seen in Figure 4-5, along with the completed (new) android:text value, a reference to your app_message constant in the app/res/values/strings.xml String constant repository for the Android application. I zoomed in 33% so you could see this better.
Now, if you wanted to change this text message, you can change it in this strings.xml file without touching any of your other XML markup or Java programming logic. Next, let’s take a look at the dimensions constants XML definition file located in your app/res/values/dimens.xml project hierarchy .
XML Dimensions: Editing Dimensions Using XML
Let’s take a look at the dimens.xml file in the app/res/values folder and see what global application margin spacing has been set up for your Android application by Android Studio. Right-click on your dimens.xml file, and select the Jump to Source option from the context-sensitive menu .
As you can see in Figure 4-6, there are two <dimen> child tags defined inside the parent <resources> tag. These are similar to what you just created in your strings.xml file, but instead of <string> tags, your child tags are <dimen> tags. These also use the name= parameter to name the dimension constants, and then set a data value of 16 dp, or density pixels. This is done in exactly the same way that your text string values were set. Here is an example of the XML child tag and parameter format that was used:
Figure 4-6. The dimens.xml file is located in the app/res/values folder, and has two <dimen> dimensions constants defined
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
If you wanted to put a little more space between your UI design (or content), and the edges of your Android device hardware, you could edit these values, and use something like 24dp or 32dp. You can try and edit these values and play around with the results of how close to or far away from the edge of the display screen you want your application content to be, to get some practice with using Android Studio. I’ll be covering dp (or DP), also known as device-independent pixels (DIP) during more advanced chapters (Chapters 6 through 9), covering UI design and graphic design.
Next, we are going to take a look at the second dimensions constants file, which has been defined using an alternate resource folder called esvalues-w820dp that we will learn about how to locate using the context menu in Android Studio by using the File Path command.
Alternate XML Resource: Dimensions for Tablets
As you can see in Figure 4-7, there are two dimens.xml files in the app/res/values folder, one of which has a (w820dp) next to it, telling us that there is an alternate resource folder named /values-w820dp somewhere that has another dimens.xml file in it. If you want to use the same file name for another file, it needs to be in another folder. So, how do we find out where this alternate folder is located? Android Studio has a File Path command in its context-sensitive menu (right-click menu) that will show you this.
Figure 4-7. The dimens.xml file is located in the app/res/values folder, and has two <dimen> dimensions constants defined
As you can see in Figure 4-7, I right-clicked and used Jump to Source to open the w820dpdimens.xml tab in the editing area , and I also used the File Path command to show me the path to the file, which is shown in a File Path pop-up, seen next to the context menu in Figure 4-7. As you can see the file is located in C:UsersuserAndroidStudioProjectsMyApplicationappsrcmain esvalues-w820dp, and this is the actual physical address on your hard disk drive, whereas the Project folder structure in Android Studio represents a simplified view of your Android 7.1.1 application’s project hierarchy.
You can use this File Path command on any file in your project pane to see where that file is being stored on your workstation hard disk drive. As you can see in the res/values-w820dp alternate folder version of the dimens.xml file, tablets with width (w) greater than 820, which would include your 960, 1024, 1280, 1920, 3840, and 4096 pixel devices) would get 64dp of horizontal margin allocated to the Activity screen. The vertical margin dimensions would remain whatever you had set them to be in the res/values/dimens.xml file, which sets the baseline or default dimensions, so in this case that would be 16dp (which can also be coded as 16DP, 16dip, or 16DIP, if you prefer). Also notice that on your operating system hard disk drive directory structure is delineated using the backslash character, as I did above for the actual location of the values-w820dpdimens.xml file on my workstation, whereas in Android coding and markup (as well as in the Linux OS) the project folder structure is delineated with a forward slash character, as I have been doing in most of this chapter, as in /app/res/values/dimens.xml for instance). If you think that this is confusing, I agree, it is, and it is one of the things that you’ll just have to get used to, and probably are already, if you use both Linux and Windows.
XML Styles: Editing Styles or Themes Using XML
Whereas text strings and density pixel dimensions are fairly straightforward, Android styles and the Android OS themes they reference, which are actually a collection of style definitions, are a bit more involved and detailed, and hence are more complicated. If you’re familiar with websites, e-books and applications created using HTML5 and CSS3, then you are already familiar with the concept of styling something by using a style definition, which is held separate from your Java code and XML content .
Styles and themes, as of Android 5.0 are called “materials,” and will be covered in Chapter 6 covering UI design. In short, what a style does is allow you to define, in one central location, how the UI design of your application is going to look, as far as color, spacing, and font characteristics (text typeface, type, and size) are concerned. This approach will allow you to extract the styling of your UI design from the actual content within that design, and from the programming logic behind how that UI design functions.
We’re not going to completely cover styles and themes in this chapter, as that more advanced subject matter is better suited for the UI design chapter, but I am going to show you how the styles.xml file fits into your overall app structure, and how it sets a default OS theme, so you can make your application use “light” (white or light gray) or “dark” (black or dark gray) operating system user interface themes.
Right-click on your styles.xml file, in your app/res/values folder, and select the Jump to Source option from your context-sensitive menu, so you can take a look at the XML markup in the styles.xml file in the central editing pane of Android Studio, as can be seen in Figure 4-8.
Figure 4-8. The styles.xml file is located in the app/res/values folder, and has the Theme.AppCompat.Light theme defined
As you can see, the parent <style> container has a name AppTheme that will be referenced in your AndroidManifest.xml file, as well as a parent parameter that is set to the Android OS constant Theme.AppCompat.Light.DarkActionBar standard Android theme definition. There is also a Light ActionBar theme as well. Inside the <style> tag are child <item> tags that override the style settings.
What this does is to set up the <style> tag named AppTheme to reference the standard or “parent” Android theme, which is simply a collection of all styles and their settings. This is done using the parent parameter , which makes the Light.DarkActionBar theme the parent of the AppTheme style. The Light.DarkActionBar and the Light.LightActionBar are part of the Theme.AppCompat application compatibility library that makes styles and themes work across all versions of Android OS. There may also be a Dark.DarkActionBar and a Dark.LightActionBar theme included in Android 7.x someday.
As you will see later this AppTheme style is referenced as the theme for the Android application in the AndroidManifest.xml file, which we will be looking at a bit later in the chapter, and the “chaining” that I talked about earlier between XML definitions would go something like this:
Manifest XML theme="@style/AppTheme > AppTheme Style > parent="Theme.AppCompat.Light.DarkActionBar"
As you can see in Figure 4-8 you can change any of the components of Android’s Light.DarkActionBar theme inside of your <style> parent tag by using <item> child tags. In the markup below, the primary (light) color, primary dark color, and accent color for Android 7.1.1 OS can be customized by using the <item name="style-constant-name">new data value</item> child tag structure, using references to the colors.xml color constants using the @color/constant-name reference structure.
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar" >
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
Next, let’s take a look at the colors.xml file that is referenced in these <style> child <item> tags.
XML Colors: Define Application Color Using XML
Right-click on the app/res/values/colors.xml file, and select Jump to Source to open it. Figure 4-7 shows that there are three custom colors defined using hexadecimal notation using <color> child tags named colorPrimary, colorAccent and colorPrimaryDark, inside of the parent <resources> tag. This is to define the primary and accent colors for the Android theme you are modifying in the styles.xml file.
Figure 4-9. The colors.xml file is located in the app/res/values folder and has three hexadecimal app color constants defined
Just like the @ symbol is used to preface a reference value, an # (hash or pound sign) is used to preface a hexadecimal value, as is shown in the XML markup below. We will cover this hexadecimal notation in Chapter 9 covering graphics design in Android 7.1.1, so for now, let’s just focus on the XML tags.
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
As with the other XML resource constant definitions, a <resources> parent tag contains <color> child tags. Now that you have taken a look at the file resource XML definition files in your app/res/values folder, and the alternate value folder, let’s look at the XML that is used to define your app itself. This is defined inside of the app/manifests/AndroidManifest.xml file.
Configuring an App Using XML: Android Manifest
Open your app/manifests folder (if it is not open already), and right-click on the AndroidManifest.xml file , and select the Jump to Source command option from the context-sensitive menu, and open the XML manifest definition file from the central editing area of Android Studio.
The parent tag of the manifest is the <manifest> tag, as you may have expected, which references an XML repository for android:parameter names as well as a com.example.user.myapplication package that you created and named back in Chapter 3. This tells Android where your application Java code will be stored, as well as a repository reference for the XML definition syntax used in the manifest file.
As you can see in Figure 4-10, the <application> child tag defines your application attributes, and its <activity> child tag defines your MainActivity attributes, which you created and named in Chapter 3.
Figure 4-10. The AndroidManifest.xml file defines your application characteristics, theme, assets, activities, and permissions
As you can see in this manifest XML definition, which I will list below, inside of the <manifest> parent tag there is an <application> child tag that has parameters defining the theme in the styles.xml file we looked at earlier, the application label (title in Actionbar) in the strings.xml file we looked at earlier, the application icon in the app/values/mipmap folder, shown on the left middle in Figure 4-10, opened up to show the PNG32 images used for the application icon, and two switches, both set to “on” or true for allowBackup (allows backups) and supportsRtl (right to left language support).
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
There is also a child <activity> tag under the <application> parent tag referencing the MainActivity Java class, which uses a period character to reference the Java .class file. Inside the <activity> there is also an <intent-filter> child tag, which we will be learning about during Chapter 7. This tells the app to launch the main Activity upon app startup. Next, let’s take a look at the Android Studio Visual Design Editor.
UI Design Editor: XML Markup Generation
Since this is an Absolute Beginner title , and Android Studio 2.3 has added a new Visual Design Editor that will generate the XML markup for your UI design automatically, I am going to spend the rest of this chapter showing you how this works, and how you can use it to learn XML, by switching back and forth between the Design and Text (Secondary Editing) tabs at the bottom of your activity_main.xml primary top tab, or any other Activity user interface XML tab. Select the activity_main.xml top editing tab, which is seen in Figure 4-11, and then click the Design tab at the bottom left of the central editor area in Android Studio. Select your Button widget (UI elements are called “widgets” in Android), and drag it onto the visual application design on the right, as shown on the right-hand side in Figure 4-11.
Figure 4-11. Select the bottom Design tab and drag a new Button UI element onto the current Hello World UI design screen
As you drag the Button UI element onto the existing visual design, you will see an outline and dashed red lines that will change as you drag the Button around the screen, showing in real time how this UI element will be aligned to other UI elements. Notice I am centering this under your existing TextView UI element , a comfortable distance down the screen. Let’s define its properties (parameters) next.
Once you release (drop) your new Button UI element in place, as shown in Figure 4-12, you will get a Properties pane on the right side of the Visual Design Editor. Name the Button ID button_universe, and the Button text “Upgrade App” using the data fields shown on the far right in Figure 4-12. Once you hit the return key to enter these values they will appear on the Button UI element preview as well.
Figure 4-12. In the Properties pane that appears once you drop the Button in place, provide the Button ID and Button text
The next UI element we’re going to add is the CheckBox widget, at the bottom of the screen, which will allow the user to select an alternate “Hello Universe” application message. The CheckBox widget is two widgets under the Button widget, as seen in Figure 4-12 in the Palette ➤ Widgets folder on the left-hand side of the Visual Design Editor.
Go ahead and use the same work process that you utilized for the Button UI element placement, and drag the CheckBox widget under the Button widget, and use the dashed red line to center it perfectly with the rest of the user interface design you are creating using Android Studio’s Visual Design Editor.
Once you drop the CheckBox into the design, the Properties pane for the UI element will appear, and you can create the checkBoxEarth ID (so we can all say Hello Universe to everyone in the Galaxy), and enter the Hello Universe text value. This is very similar to what we did for the Button UI element.
Notice that underneath the Palette pane that contains all of the UI Design elements, there is also a Component Tree pane. As you add user interface elements to your design, this pane keeps track of the UI element XML markup child tags that you are going to see inside of the ConstraintLayout parent tag when you switch back over into the XML Text editing tab. We will be doing this soon to show you that Android Studio is indeed writing your XML markup for you, which is really quite cool!
As you can see in Figure 4-13, the CheckBox UI element is now in place and informs the user that if checked, the Hello World message will be upgraded to a Hello Universe message. We will be doing the actual code implementation for this in the next chapter on Java 8 programming in Android 7.1.1.
Figure 4-13. Drag a CheckBox UI element onto the visual design editor and name it checkBoxEarth, with text Hello Universe
As you can see below adding these two UI elements has added two child tags and seven parameters, including an ID (which is used in Java code to reference UI components) and the text values that you specified in the Properties pane, as is shown in Figure 4-14.
Figure 4-14. Click the Text tab at the bottom of the activity_main.xml edit tab to look at the new XML tags and parameters
<?xml version="1.0" encoding="utf-8" ?>
<android.support.constraint.ConstraintLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android" android:id=”@+id/activity_main”
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height=”match_parent" tools:context="com.example.user.myapplication.MainActivity">
<TextView android:text="@string/app_message"
android:layout_width="match_parent" android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
app:layout_constraintBottom_toLeftOf="@+id/activity_main"
app:layout_constraintBottom_toRightOf="@+id/activity_main"
app:layout_constraintBottom_toTopOf="@+id/activity_main" />
<Button android:text="Upgrade App" android:id="@+id/button_universe" android:elevation="0dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_editor_absoluteY="312dp” android:layout_editor_absoluteX="143dp" />
<CheckBox android:text="Hello Universe" android:id="@+id/checkBoxEarth" android:checked="false"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_editor_absoluteY="453dp” android:layout_editor_absoluteX="150dp" />
</android.support.constraint.ConstraintLayout>
As you can see in my above XML markup, how you space out the tags and parameters is flexible as long as you indent properly and can easily ascertain what your XML tags and parameters are doing.
To follow convention , create app_button and app_checkbox constants in the strings.xml file as seen in Figure 4-15. Next, change your text values, to "@string/app_button" and "@string/app_checkbox" respectively, in the <Button> and <CheckBox> android:text parameters, as you did for app_message.
Figure 4-15. Create String constants in strings.xml for Button (app_button) and CheckBox (app_checkbox) UI elements
Next, let’s add a friendly image to this design. This is done using the ImageView, seen selected in gray in Figure 4-16 in the Palette pane. Notice your @string reference now shows in the Properties pane, shown labeled with a red 1. We will right-click on app/res/drawable and use File Path to see where we need to place our SmileyFace.png file. This is labeled with a red 2 in Figure 4-16.
Figure 4-16. Right-click on app/res/drawable and use a File Path command to find where you need to place SmileyFace.png
Use your file management utility to place the SmileyFace.png image into the folder on your hard disk drive indicated by the file path that you got using the File Path command, as is shown in Figure 4-17. In my case it’s C:UsersuserAndroidStudioProjectsMyApplicationappsrcmain esdrawable.
Figure 4-17. Place the SmileyFace.png file
As you can see in Figure 4-18, once you copy this PNG file into the correct folder, it will appear in the drawable folder, as shown highlighted in the top left. Drag the ImageView into the UI Design and drop it in the top center of the Activity screen , as seen in Figure 4-18 with a red dashed center align guide.
Figure 4-18. Make sure your drawable is in place and drag the ImageView onto the UI Design and drop it once it is centered
Once you drop the ImageView, the Resources dialog will open and you can select the drawable, as is shown highlighted in blue in Figure 4-19. Click the OK button to load the drawable in your ImageView.
Figure 4-19. Select the SmileyFace drawable asset and click the OK button to use it in the ImageView
As you can see in Figure 4-20, the image is bigger than the ImageView you dragged onto the screen, so you will reduce the image size about 50%, and position it so that it fits in the top of the UI Design. I have highlighted the new component tree , as well as the @drawable/SmileyFace reference (note you do not need to specify the .PNG file extension) shown circled in red in Figure 4-20.
Figure 4-20. Use the resizing handles on the perimeter of the ImageView to scale the image down 50% so it will fit in the UI
Drag the lower-right corner (solid) resizing handle for this ImageView, until the layout_width and the layout_height are set to 220 pixels (DP), which is about half the original image dimension. You can also enter these values directly into the data fields in the Properties pane if you prefer to work that way; the Visual Design Editor is very flexible.
As you will see in Figure 4-21, Android 7.1.1 has a very effective scaling algorithm. We will be covering scaling of imagery in Chapter 9 on graphics design. You may be wondering what the wrap_content means in the layout_width and layout_height data fields in Figure 4-20, and we will be covering this wrap_content UI design constant in detail during Chapter 6, so don’t worry about what that does or what it means, at least for now. Here’s a hint: Think Shrink-Wrap! More on this later.
Figure 4-21. Position the ImageView at the top middle of the UI design, and make sure the image is a square 220x220 pixels
To position the resized ImageView click in the middle of it, and drag it into position using the centering guidelines, until you have a well-balanced UI design, as is shown in Figure 4-21. We now need to adjust or “tweak” the UI design a bit more to perfect it, for instance, the Hello World text is too small to be read comfortably on a smartphone, so we will need to use a large font instead of a small one.
After we do that, we will take a look at the Text (XML markup) tab once more to see how Android Studio’s coding of our UI design for us is progressing (an automated labor force is always nice). I will then show you how to fix any anomalies Android Studio finds in our design, and we’ll be ready to get into Java programming in Chapter 5’s Java primer. This just keeps getting more and more exciting!
Select the TextView widget in the UI design (in either rendered view or architect view) and drop-down your textAppearance constant selector, seen circled in red in Figure 4-22. Select AppCompatLarge for your constant , which will give you a nice, large text font size across all versions of the Android OS.
Figure 4-22. Select the TextView widget, drop-down the textAppearance parameter, and select a AppCompatLarge font size
Now that we are getting close to a more professional UI design, let’s click the Text tab at the bottom of the XML editor pane (tab) and look at all of this XML markup Android Studio generated, which is shown in Figure 4-23. There are some problems (red underlined markup) that we need to look into!
Figure 4-23. Android Studio generated two dozen lines of additional XML markup that you did not have to write yourself
If you place the mouse over the red underlined tag, you will get the pop-up shown in Figure 4-24. This informs you that although the UI layout design (technically called a view in Android, as it comes from the View superclass) has design-time positions, it will snap, jump, or collapse to the upper-left corner of the screen (pixel X,Y location 0,0) unless you add constraints. Fortunately, this is easy to do in Visual Design Editor so let’s take a look at how you’ll do this next. Constraints will remove all of these errors .
Figure 4-24. Mouse-over any of the three error highlights (Figure 4-23), and you’ll get the following positioning advisement
To set constraints, you use the edge (middle) handles, which will have a round white circle around them when you mouse-over them. Let’s do the Button UI widget first, dragging the left constraint, shown in Figure 4-25 in panes 1 and 2, to the left side of the screen. Release the mouse to create the left constraint, as shown in pane 3, and then drag the right constraint to the right side of the screen, shown in pane 4, which will then re-center the Button widget, which is shown in pane 5. Repeat this process for the top and bottom constraint (middle) handles, and you will get the result that is shown in pane 1 in Figure 4-26, which shows the constraint results (sawtooth constraint lines in place) for all three of the UI widgets that were generating errors in the XML markup shown in Figure 4-23.
Figure 4-25. Set UI widget positioning constraints using the middle edge handles on each widget and drag to edge of screen
Figure 4-26. UI widget position constraints in place for Button, CheckBox, and ImageView widget so they can conform to the UI
The reason this sawtooth (or accordion) line representation is used, is because when the screen size and (or) shape changes, the position of the UI widget stays the same, while the space on the top, left, bottom, and right will expand or contract, thus making sure the design maintains the same spacing or alignment. You could also think of these alignment constraint lines as being springs, if you prefer.
Now if you click on the Text tab at the bottom of your XML editing pane (tab) as shown in Figure 4-27, you will see that your XML markup is error free. There are now app:layout_constraint parameters in all of your three new UI widgets, similar to the ones that were already in the TextView widget that Android Studio had in the UI design in the first place. Since the XML tag parameters use a verbose, detailed parameter naming schema, you can pretty much figure out what each parameter is doing, based on what it is named, which makes working with XML markup that much easier, as long as you understand user interface design terms and concepts. If you don’t, take a look at the Pro Android UI title from Apress, which covers UI design concepts , UI design prototyping (with Evolus Pencil), and UI layout containers and the XML markup that is needed to create different UI design approaches and scenarios.
Figure 4-27. Use the Text tab to check the XML markup to make sure all errors are gone and layout_constraint parameters are inserted and correct
We will be learning more about XML-based user interface design in Chapter 6, but just in case you want to look over the parameter names (which are fairly self-explanatory), I will list the code that the Visual Design Editor created for us (four dozen lines of code that we didn’t have to write ourselves) here in case you want to examine how XML defines and places these user interface components on the screen. I can’t teach you all of the Android XML in this book in one chapter, so we will be using (and learning) XML markup for the rest of the book, excepting possibly Chapter 5 covering Java.
<? xml version="1.0" encoding="utf-8" ?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.user.myapplication.MainActivity"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_message"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
app:layout_constraintRight_toRightOf="@+id/activity_main"
app:layout_constraintTop_toTopOf="@+id/activity_main"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintVertical_bias="0.56"
android:id="@+id/textView2" />
<Button android:text="@string/app_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_universe"
android:elevation="0dp"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="@+id/activity_main"
android:layout_marginRight="16dp"
app:layout_constraintTop_toTopOf="@+id/imageView"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.78" />
<CheckBox android:text="@string/app_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/checkBoxEarth"
android:checked="false"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="@+id/activity_main"
android:layout_marginRight="16dp"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="@+id/activity_main"
app:layout_constraintVertical_bias="0.97" />
<ImageView android:layout_width="220dp"
android:layout_height="220dp"
app:srcCompat="@drawable/SmileyFace"
android:id="@+id/imageView"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="@+id/activity_main"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="@+id/activity_main"
app:layout_constraintBottom_toBottomOf="@+id/activity_main"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.03" />
</android.support.constraint.ConstraintLayout>
Now we are ready to show you how Java can be used to “inflate” the XML definitions (turn them into Java objects) as well as make them interactive and functional so you can make Android applications .
Summary
In this fourth chapter, you learned about the XML markup language, as well as how Android utilizes XML markup to simplify the application development work process, so that non-programmers can get involved. You learned about how XML uses tags and parameters to define XML definition structures, as well as how levels of nesting define parent and child XML tags.
You also learned about XML naming schemas, and how these are defined in the parent tags at the beginning of XML definition files. You looked at some of the types of XML files that are always included in an Android application. These were created by Android Studio in the bootstrap XML files that were generated by the New Android Application Project series of dialogs in Chapter 3.
You examined, and in some cases edited, XML files defining String value constants, application styles from Android OS themes, and the Android Manifest, which defines your entire application. You learned how to utilize the @ sign to reference one XML file from inside of another XML file, allowing you to create more complex and organized XML infrastructures, and allowing a modularization similar to what Java offers via objects, classes and packages, which we will be learning about next.
Finally, you learned how to use the Visual Design Editor in Android Studio 2.3, and added a Button, CheckBox, and Imagery to the Hello World UI design, refining the UI design in its entirety and learning how to use the primary components (panes) in the Visual Design Editor. You observed how this can be used to learn XML markup by switching back and forth between the Design and Text tabs at the bottom of the XML editing pane in Android Studio.
In the next chapter, you will learn all about the Java SE programming language by taking an in-depth look at the Android application that you created in Chapter 3, including the Java files in the app/java/ folder. You’ll also learn all about Java objects, classes, methods, variables, constants, and interfaces in Chapter 5 for those readers who are really absolute beginners and do not know Java.