|Now with buttons.|
First, I have to say that before making this tutorial I was a little confused on how to customize buttons. I read a couple of tutorials which can be found here and here. I will use most of the code from the 2nd link but will explain it using the 1st link.
So Many Choices
There are actually a lot of different ways to perform customization on buttons. You could create images which will be used as the background (Android ImageButton or ninepatch) or mess around with the built in properties of a button. As far as I know, you could perform both either through java code or XML. The one I’ll discuss in this tutorial involves using XML. It’s pretty easy to change the look and feel once you have everything setup.
Understanding Button States
If you’re familiar with using Swing in Java (or an equivalent) then you can skip this part. Before you place and customize buttons, you have to understand its states. If you look carefully at any button on almost any program, you can see that it changes its look depending on what you’re doing with it. Some of the common states of buttons include hover, pressed, selected, enabled or disabled and normal/default. For this tutorial, let’s worry about only pressed and normal because… well because I’m using a touch device. States like hover are more useful with physical buttons or a mouse pointer.
Update: Placed the sample image above. It’s the 0 button from MS calculator. Default, hover and pressed states are shown.
Place a Button
To place a button, simply drag the icon from the palette form widgets panel from the left to the canvas or UI in the middle. Drag the icon below the ImageView or the space provided for your logo.
|You get a boring button as a result.|
If you have the property windows setup in your environment, you’ll notice all the things you can modify. If you check out the code, you’ll notice something like below.
|Auto-generated button code.|
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@button"/>
These are the most basic properties of a button. The “id” is used to reference the button in your program code (more on this later). Layout as you might expect is used to adjust the size of the button. Besides an actual pixel value, there are 3 values you can place to automatically adjust the size of the button.
The value “wrap_content” means that the object will adjust depending on the value of another item. In this case, the width of the button is adjusted depending on the length of the string or button label. On the other hand, the value “fill_parent” means it will fill up the space allotted for the button. The value “match_parent” means it will match the size allocated for the parent object. Most of the time I just use wrap and fill.
|Wrap_content (above) vs fill_parent.|
The last property from the auto-generated code is “text”. The value you put will be the label of the button. It’s better to put the value in the strings XML file. To do this, first place a value in the res/strings.xml file. I prefer placing values in code view. To insert a value simply VALUE (without the spaces). To finish it, go back to your button properties and in the text property use @string/value. See images below for a sample. The @ operator means it will access a file or folder.
|Sample of strings XML file. Disregard other values for now.|
|Accessing the string value in the button code. Results below.|
|Yes you are a button.|
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="button_label">I\'m a button</string> <string name="app_name">AMS</string> <string name="play_label">Play</string> <string name="player_data_label">Stats</string> <string name="highscore_label">Highscore</string> <string name="options_label">Options</string> </resources>
<Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_label"/>
Now we’ll start changing the default look. Credit goes to the tutorial here because I played around with that the author provided.
First let’s setup the requirements. Create the files colors.xml and styles.xml in the res/values folder. Right click and select new > Android XML. Just put “colors” and “styles” in the dialog. You’ll see that it’s a resource type and is similar to how we use the strings.xml.
|Notice it’s a resource type.|
Placing Color Values
We’ll place some values in the colors.xml to make the code easier to reuse. Colors in android are in the form #argb, #rgb, #rrggbb or #aarrggbb. What vodoo do I speak of? Simply A is alpha, R is red, G is green and B is blue. RGB values are used to represent colors. ARGB is the same but with an alpha value. The alpha is the transparency. RGB values create colors. A combination of intensity of the 3 will produce a certain color.
If you’ve used Photoshop (or similar), tried any form of web design then you’re already familiar with it. If you would like to see color values try Color Picker to get the hex RGB codes (see image below). For this tutorial
|The color picker site. You can auto-generate colors too.|
I’ll be using shades of blue similar to the logo colors. Take note of the color values as we’ll put it in code. If you’re not familiar with a gradient then it’s a combination of two colors or actually.
Blue Base: #449def
Blue Stroke: #2F6699
Gradient Start: #00a2e2
Gradient End: #0767a4
To insert these values go to colors.xml. the format is VALUE . Remove spaces. Plug in the name then the value. Notice it’s similar to how you add strings.
|You can choose a different naming scheme if you like.|
<color name="blue_base">#449def</color> <color name="blue_stroke">#2F6699</color> <color name="blue_gradientS">#00a2e2</color> <color name="blue_gradientE">#0767a4</color>
Creating the Button Look and Feel
Now that we have the colors to use, let’s start styling them’ buttons. Create a folder called “drawable” under the res folder. Right click that folder and select new XML file and name it “blue_menu_btn” under the choices select selector. See images below.
|Choose selector as the root element.|
What is a selector?
Based on my understanding(which could be technically wrong), you can use the selector item to define what happens in each state of a button. You can browse the tutorial code for where I got this from here. Anyway, each item is a state of button and Android reads it based on what is on top. The item on top will be read first the next one below and so on.
I’ll show the code below and then start to explain what each one means. Full project is available at the link in the last part.
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true"> <shape> <solid android:color="@color/blue_base"/> <stroke android:width="1dip" android:color="@color/blue_stroke" /> <corners android:radius="3dip"/> <padding android:left="40dip" android:right="40dip"/> </shape> </item> <item> <shape> <gradient android:startColor="@color/blue_gradientS" android:endColor="@color/blue_gradientE" android:angle="270"/> <stroke android:width="1dip" android:color="@color/blue_stroke"/> <corners android:radius="3dip"/> <padding android:left="40dip" android:right="40dip"/> </shape> </item> </selector>
The selector tag is automatically inserted when you selected it on creation. The item tag represents a specific state of a button. Like I explained in button states, since I’m using a fully touch based device I am only concerned with the state_pressed.
The first item is for the state pressed and Android will interpret it first. This is because the line state_pressed is a condition. If it isn’t pressed then it will go to the next item which is the non-pressed state. Shape means that we’ll draw it manually instead of referring a picture for the button. In item, solid means that the button would be using a solid color (one color) as the background. We refer to the blue_base color value in the colors.xml (using the @ operator). Stroke is a line that goes outside the button. The width is how thick the stroke would be and again the color is the one we defined earlier on. Corners represent how circular/rounded the end of each button is. Finally, padding is how much space to give on each side (how much space the text labels can use).
(If you’re familiar with Photoshop blending options then it is the same concept as the Stroke option there.)
The next item tag is the normal or unpressed state of the button. This will be what the button normally looks like. It’s quite similar to the previous one if you notice except for the gradient. What this means is that instead of using one solid color, we’ll use a transition of 2 colors. For the colors, we refer to our previous values in the colors.xml file (See how easy it would be to change the theme?). Angle is what angle the colors would transition from. If you modify the value then it can go from top down or left to right.
Below is an explanation to the button’s look.
|1. Stroke 2. Gradient Start. 3. Gradient End (Disregard font style, it’ll be below.)|
Using the Button Style
Now that we’ve set everything up, let’s use it. Go to your code view in Main.xml (Where the button xml code is located). Ready? Simply add android:background=”@drawable/blue_menu_btn” below the id tag. See images below.
|The button with our color style. Still needs fixing.|
Setting up styles
To fix the button we’ll be setting up a style. What are styles? Styles are a saved set of properties. We’ll be saving things like layout sizes, text colors, etc. We can import this to each of our buttons to have the same look for each one and save a lot of time.
Copy the code below in your styles.xml file.
|I will add/use syntax highlighter soon because images are just not great to use for code obviously.|
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="main_menu"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">55dip</item> <item name="android:textColor">@color/menu_text_color</item> <item name="android:gravity">center</item> <item name="android:layout_marginLeft">45dip</item> <item name="android:layout_marginRight">45dip</item> <item name="android:textSize">30sp</item> <item name="android:textStyle">bold</item> <item name="android:shadowColor">@color/menu_shadow_color</item> <item name="android:shadowDx">1</item> <item name="android:shadowDy">1</item> <item name="android:shadowRadius">4</item> </style> </resources>
Note: Hey I finally added syntax highlighter! Hooray!
Almost all of the code is self explanatory. The name is the name of the style and will be used in importing/referencing/using it. I used layout height of 55 dip because that seems to be a better fit. (Dip is density independent pixel).You can change any of the values to suit your liking. We use the color values we prepared before.
Again, credit goes to the tutorial here because I learned it from that post.
We use the style by adding style=”@drawable/blue_menu_btn” in the button properties. Results below.
So there we now have the cooler looking button. It’s much better than the default one. You have to fix the label because it’s too long.
Add a couple of more buttons and text labels in the strings.xml and you can come up with something similar to the code below.
Note: See below for the final code on the button styles.
You might notice the layout margin top property. I added it to leave a little space on top of each button. The first button has the most space because it would be too close to the logo. I didn’t add it in the style because each one varies (almost). I added values to the
It results to the screenshot below.
If you look carefully, the shadow is not rendered/shown in the main.xml graphical layout image representation mechanism thingamajig. I don’t know why but the shadow is present when I run it in my phone. I haven’t solved that yet.
Update: Making things easier
I reached out to Mr. Folkert Jongbloed, author of the tutorial I posted, and he gave a great tip. You can use the parent/child feature to make it easier to customize objects. With our code, we already setup the main_menu button style. I had 2 variations playing around with the marginTop attribute. There is another way to do this.
We go to the styles.xml and create a new style. See below.
If you notice, we’re inheriting all the attributes of the main_menu style we defined. We use the “parent” then add the objects name. When you go into your button code all you have to do is insert the new style.
Note: The final main.xml in the layout is below
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="@drawable/background"> <ImageView android:id="@+id/logo_imgView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/logo2" android:layout_marginTop="50dip"/> <Button android:id="@+id/play_btn" android:background="@drawable/blue_menu_btn" style="@style/main_menu_btnTop" android:text="@string/play_label"/> <Button android:id="@+id/player_data_btn" android:background="@drawable/blue_menu_btn" style="@style/main_menu_btnNormal" android:text="@string/player_data_label"/> <Button android:id="@+id/highscore_btn" android:background="@drawable/blue_menu_btn" style="@style/main_menu_btnNormal" android:text="@string/highscore_label"/> <Button android:id="@+id/options_btn" android:background="@drawable/blue_menu_btn" style="@style/main_menu_btnNormal" android:text="@string/options_label"/> </LinearLayout>
This is really useful if you’re creating different states and makes things even more reusable (awesome!). I’ll update the code soon when hopefully by the middle of the week and perform a couple of more experiments.
Thanks for the tip!
You can download part 4 source code here (now updated).
On the next part we’ll implement the buttons in the code and have it do something.