In this tutorial, we will be continuing from where we left off with the “hello world” application. This time adding a graphical user interface (GUI) and a “toast”. The GUI will consist of a button, textbox and a label. The “toast” will be issued onto the screen when the button is pressed.
Some may wonder what a toast is. Well, for non-programmers, a toast is a text notification that for the most part is used only to display an error on the screen (I am a big fan of using toasts instead of an alert on the screen as its less intrusive). For this article we will use a toast to display a message on the screen that will take the text in the textbox and issue a “Hello Greg” onto the bottom of the screen. After this article completed you will be able to successfully make toast commands, design the layout of the hello world program, and pull text from a textbox.
We are going to start off by copy our existing Hello World project so that we can use the original in every way but have two separate projects to show the difference and both can be used as references. To do this we will right click on the root of our HelloWorld project in the right hand pane (Navigation Explorer), navigate to copy (not Copy Qualified Name) and click it. Then find a blank space in the Navigation Explorer, right click again and click paste. You will be asked to supply a new name for this project and whether to use the default location. We will name the new project ImprovedHelloWorld and we will leave the checkbox checked that says “use default location”. Press OK and the new project will be generated from the old one.
The first thing we are going to accomplish is changing the strings.xml file to add another node under app_name. We will do this by copying the node above it and pasting the copied material directly under the last </string> element. Then we will change the name of the string to press and in between we will write Press Me!. Next we will alter the hello node and change the text to say Enter Your Name Here: instead of Hello Android, Hello World!. This being accomplished we now need to design the GUI (Graphical User Interface).
To do this navigate to main.xml and we are going to go over what everything does up to this point. We first off have a node called LinearLayout which essentially creates a space for adding objects such as textboxes, buttons and the like and will format the layout for us. So LinearLayout will organize one thing right after the other in a one column and one row type of deal. Next we have a TextView which in any other label we could call a label. Now to go over what all of the parameters are in the nodes we just mentioned. android:layout_width & android:layout_height are used to determine what will happen to an object when it is used within a layout. There are two options when using this and they are fill_parent or wrap_content. fill_parent will do exactly as it states, it will size the object so that it will fill the screen either vertically or horizontally. wrap_content will format the object to expand or shrink to the size of the content displayed within. Both of these variables can be used in many different objects including but not limited to Layouts, Text Views, Text Boxes, and Buttons. android:text is used in certain objects like TextViews and TextBoxes to display text to the user. As of right now, we are presenting the user with text but calling it from strings.xml instead of entering the text right in the node itself. To reference strings.xml all that is needed is to put @string/press, where press is the name of your variable, inside the quotations.
Now that we are familiar with the terms, we will need to modify this to first house a label, textbox and finally a button. To do this we will simply add a textbox and button since we already took care of the label in the string.xml. To add a Textbox we will start on a new line under ending of the <TextView /> node. Just to be clear I will add code inline and explain why we are adding it afterwards. <EditText android:id=”@+id/helloName” android:layout_width=”fill_parent” android:layout_height=”wrap_content” />. EditText will be our textbox in this instance. Also when giving items an ID it is best to follow these practises of adding @+id/ before your variable name which makes it possible to tie into your .java file later. Next we will add <Button android:id=”@+id/go” android:layout_width=”fill_parent” android:layout_height=”wrap_content” android:text=”@string/press” /> directly underneath the ending of our EditText node. Notice we are referencing the string.xml and calling the node that says Press Me! which will appear on our button now. If you were to run this project now you would be able to see the layout of the program we just made but we are unable to get it to do anything except enter text in the textbox.
This next section will contain a lot of code and I will provide most of the screenshots of the code to help you through. First, it is good to realize every time you would like to reference an object in your layout we need to import it. We will need to add imports for our button and textbox. We can do that bu adding these lines of code to the imports section at the top:
import android.widget.Button; import android.widget.EditText;
After that we will need to include four more imports, the first being for event listen to add to our button, the second will be for the toast that we will call when the event handler runs, the third being the context of the application and the fourth to get the view of the application and handle the layout and interaction. These imports can be added under the previous ones and will look like this:
import android.view.View.OnClickListener; import android.widget.Toast; import android.content.Context; import android.view.View;
After these are added to your imports we are ready to get into coding the event handler for our button and the onCreate functions, which is called when the program is started. To make things easier and to complement the screenshot, I will post the rest of the code and explain what the important lines are doing and why we are using them.
public class HelloMain extends Activity { EditText helloName;
We are creating a reference to our textbox above any function so that it only has to be declared once but instantiated many times if need be.
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Capture our button from layout Button button = (Button)findViewById(R.id.go); // Register the onClick listener with the implementation above button.setOnClickListener(mAddListener); }
Above we capture the button from the layout using a variable. With this variable we are going to assign it an onClick Event Handler as shown on the last line above. Below we are creating the Event Handler for it to be hooked in above. After creating this function it will be able to pull the text from the TextBox and display it with static text.
// Create an anonymous implementation of OnClickListener private OnClickListener mAddListener = new OnClickListener() { public void onClick(View v) { long id = 0; // do something when the button is clicked try { helloName = (EditText)findViewById(R.id.helloName);
Here we instantiate the TextBox we declared earlier and capture the Textbox in the layout by finding it by the ID that we gave it.
Context context = getApplicationContext(); CharSequence text = "Hello " + helloName.getText() + "!"; int duration = Toast.LENGTH_LONG; Toast toast = Toast.makeText(context, text, duration); toast.show();
The above code will take Context (the facet to our applications enviroment) and and add it to our Toast along with our dynamic CharSequence text and the length the Toast will appear onscreen, which in this case we want it to be longer. It is key to note how to make a Toast as it is more efficient that popping up textboxes to the user as well as it is less distracting.
} catch (Exception ex) { Context context = getApplicationContext(); CharSequence text = ex.toString() + "ID = " + id; int duration = Toast.LENGTH_LONG; Toast toast = Toast.makeText(context, text, duration); toast.show(); } } }; }
The last thing we are doing for this function is putting all the important stuff mentioned above into a try catch statement which will try our important code and if there is an error it will display a Toast letting us know there was an error and a message about that error. For functions such as these is it crucial to have precautions in place to catch errors and not have a program force close. It is important to put the user first in thinking about UI and any error messages that might occur. If an error somehow sneaks into your program try catch statements will catch the error and make it “cute and fuzzy” for the user.
Top half of code:
Bottom half of code, elapsed by previous view of code:
After we have coded the main content for our .java file, we can now proceed to run the application and view our completed Improved Hello World program. Notice that when you press the button and your textbox has not text in it that the program will still function correctly. This is a good feature to have so that you don’t start seeing Toasts containing error messages. The completed product should look like this when the button is pressed:
This would conclude our Improved Hello World example but the learning is far from over. Next post we will examine Databases and a look into some simple queries as well as building a database from the ground up. As always, if you have any problems with coding this article, feel free to leave a comment and I will assist in any way possible! If you can’t wait for the next post you can read up on databases before the next posting. Until next time, Happy Hacking!
Continue on to Part3: Introduction to Databases
I would love to do these tutorials, but for some reason your images are scaled down and don’t have larger versions. Any chance you could update this one, and the hello world tutorial with links to larger screenshots?
@Abyss Knight. Right click on image and copy link location. Paste in new window or download etc etc.
Nice tutorial. Not my cup of tea but appreciated nonetheless
@Abyss Knight – Pictures of code have been adjusted so you just have to click on them and they will enlarge. Hope this helps and happy hacking!
after all , “this is hack a day” not “tutorial a day”
@somebody:Most of the hacks on here come with a tutorial of some kind. Not to mention Android is open source which is totally about hacking.
Really? I thought it was “jackass comment a day.” Thanks for the articles, now I just need to ditch my VX9100 and get a worthy phone.
@Luke, you win.
I really like these tutorials. Too bad I don’t have an Android phone. :( I hope more tutorials for other topics come soon!
@:D – If you are interested in Android development then you can use the emulator that comes with the AndroidSDK until you convert to Android :)
While this may not be a hack within itself, it is a tutorial helping get non-phone-programming hackers get into the realm of taking advantage of these great new devices. Just by posting this, some reader is going to follow along, get inspired, and put together some new hacks that can interact with Android phones and utilize their features (easy access to bluetooth, wifi, compass, accelerometer) so who’s to say this sort of guide doesn’t belong here? Granted it doesn’t line up with the idea of “a new hack each day” blog but I feel this is definitely a great addition to this resource.
Two recommendations:
1. You really should indent your code properly
2. Rather than creating the OnClickListener a separate class, you should embed it withing the class. For example:
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
/*Do Stuff*/
}
)};
(I’m sorry if the tabbing is wrong on here…I’m not sure how wp.com sanatises it’s comments).
@Leif Andersen
Code formatting is one of the things when programming I look out for the most. Unfortunately WordPress doesn’t feel the same way as I do. I will include well formatted text documents for the next post :)
@leif, you should really indent your code properly.
These tutorials are gr8t. Keep them coming. As an analog n mci guy, I am interested in building accessories for these. Could you please do a tutorial on rs232 comm with android. So then android can talk to arduino or something.
I dont get the whole “not a hack” thing.
a load of stuff on HaD isnt a hack… a hack being repurposing hardware in a way that wasnt facilitated by the designer.
1)Nixie tubes are for displaying numbers on, nixie sudoku uses tubes to display number…not a hack.
2)Android dev – android designed so that people can write their own apps – not a hack.
3)Capacitor bank – stores a lot of charge – not a hack
4)Servo control board – programming an AVR to do stuff …like it was made to do – not a hack.
The site is probabily 50% hacks – and the rest is just normal design. give the “not a hack” stuff a break
@steaky: this thing has been discussed a lot; i don’t want to be rude, but if you don’t like the site, just don’t visit HaD.
Sure that hack links are the most interesting, but there are lots of people who also are interested in programming, and all that stuff.
And also take in mind that if they don’t publish hack articles maybe because simply there aren’t any.
Do you want hacks? then, do one yourself and send it here. I’m sure we all apreciate a lot. ;)
Are there any good UI editors available yet? The one that comes with the Eclipse plugin is atrocious, and DroidDraw seems to be quite limited as well.
In your code you are referencing @string, but shouldn’t it really be @strings? The file name is strings.xml. Or am I missing that the SDK just knows that you’re referring to the original strings XML file?
Jack,
You misinterpret what I was saying. I like the site – sure I hope there would be more hacking as it is interesting seeing how people modify kit etc, but at the same time I like seeing what people make too.
I cant stand it when people say “not a hack” and that was the ponit I was making – hence the give it a break.
also, I do work on my own projects – currently a USB PC fan controller, car stereo based erm.. stereo (?) etc, as well as a load of programming – plus I write articles here http://www.intuition-online.co.uk/profile.php?contrid=212 and here http://www.eruditiononline.co.uk/profile.php?contrid=32
I followed the tutorial and came up with errors on the build. Certain sections above do not accurately indicate which file code is being added to (paragraph 6&7). Nor does this tutorial ever mention which editor to open these files with (Java editor, text editor, xml editor). Here’s my code build in HelloMain.java and there’s errors so it will not build in the app.
package com.jspencersworld.helloworld;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class HelloMain extends Activity {
EditText helloName;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Capture our button from layout
Button button = (Button)findViewById(R.id.go);
// Register the onClick listener with the implementation above
button.setOnClickListener(mAddListener);
}
// Create an anonymous implementation of OnClickListener
private OnClickListener mAddListener = new OnClickListener()
{
public void onClick(View v)
{
long id = 0;
// do something when the button is clicked
try
{
helloName = (EditText)findViewById(R.id.helloName);
Here we instantiate the TextBox we declared earlier and capture the Textbox in the layout by finding it by the ID that we gave it.
Context context = getApplicationContext();
CharSequence text = “Hello ” + helloName.getText() + “!”;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
catch (Exception ex)
{
Context context = getApplicationContext();
CharSequence text = ex.toString() + “ID = ” + id;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
};
}
public class HelloMain extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Jesus f’in christ! Cant we all settle down with the stupid “this isn’t a hack” comments. Don’t like something, fuck off then. Read something else. Or, holy shit imagine this, come up with your own hack of some kind. I swear some of you retards must equate reading a hack on hack-a-day with actually doing it yourself. Your not even equivalent to a fucking script kiddie. at least they actually do something with the shit they read on the internet.
Thanks for this, I just got told yesterday I needed to learn to write android apps asap. Yours was the first tutorial I tried and (after a few dumb mistakes on my part) – it all worked – most of all because of your clarity and detail, I know what it all does and why.
Excellent article, I can’t wait for the next. The google docs seemed to gloss over the fundamental of “how to integrate a button” and just wanted to show you every type of layout available. Great for when you’re designing, as reference, but not so much for trying to build simple applications for demonstrative purposes.
Good post Greg.
If you follow this post though make sure to add those 2 lines in your import section otherwise you won’t be able to run the application. (here’s my full list of import)
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
thanks again Greg! keep’em going!
@John
I also came up with errors following the tutorial. I looked at the “top half” code screenshot and saw that there were two import statements that seem to have been forgotten about in the tutorial text.
~Line 6: import android.content.Context;
~Line 8: import android.view.View;
I added these two statements in and it compiled with no errors, and ran as intended.
Nice tutorial. Cant wait for 3D game programming tutorial in android :)
And yah, can we get some:
int i;
if comment[i]=”not a hack”
{
remove_comment(i); //how do we tab in our comments
}
Or maybe a filter we can enable. So we dont waste time and energy reading stupid peoples responses.
I like how you shown how to toast (great name by itself as well. Like how people say “google” it instead of generic search it. But I digress).
What I don’t like is how overly complicated this seems for coding compared to regular java. I’m not a programmer by trade, but am fairly competent in knowing how to work with java/javascript/bash, etc. Comparing this to the equivalent java code for a pc, and its just complicated for no reason.
ANyway, what I would like to see is a barebones project for downloading a webpage and then grepping through it, either from memory or from a cache file, in android. Then I could modify it from there.
I love this stuff, it just so happens to be that I am learning it at the same time you are doing tutorials. And it looks like you are about to catch up with me.
One thing that would help is syntax highlighting and all that jazz that makes code easier to look at.
I’ve been read HaD for a long time, so don’t think i’m coming here just for this, I still expect good hacks along with the tutorial.
@phishiphree,
Who are you directing that tirade towards. I clearly explained that I like the site, I appreciate the “non-hacks” and that I do my own projects – plus included evidence of such. Just because I dont go shouting about them and handing everything I do to the tips line doesnt mean I dont do projects – It just means they are targeted towards a different audience.
@admin, is there a way to enable voting on the comments so that they become self-moderating.
@John – not sure if you figured it out by now, but the article is missing a few imports – the images of the code are correct, but the steps are missing android.content.Context and android.view.View. The complete list of imports you need is:
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
Aside from that, the rest of the article seems correct and I was able to create the app as described and run it on the Android emulator.
@John – Please give me an email at greg@hackaday.com to let me know the issues and we will work through this and get you up an running!
@Everyone
There has been an error in the tutorial which would have made it so you couldn’t compile it is now fixed but i will show you before and afetr
Before:
import android.view.View.OnClickListener;
import android.widget.Toast;
After:
import android.view.View.OnClickListener;
import android.widget.Toast;
import android.content.Context;
import android.view.View;
@John Spencer:
I agree, it is slightly confusing on just reading the text, but if you look at the screenshots everything is perfectly clear.
As you worked out, the code does need to be edited in HelloMain.java. I just double-clicked it to invoke the default editor.
Your code isn’t working for following reasons I think:
1) you need to add 2 more imports:
import android.content.Context;
import android.view.View;
2) all the changes should be made in the existing public class HelloMain – you’ve ended up with 2 of them.
@Nick – Sorry about not replying to your comment earlier, the noise was getting in the way of answering your question. It would appear that at first glance this wouldn’t make sense because main.xml and strings.xml have no relation. They need a common ground on which to reference each other and I have avoided mentioning this class as it could completely ruin any project your working on if you dont know how to modify it correctly. The file R.java located in the Root of your project under gen/ contains all the information to pull your application together and make it work. You will notice that one of the classes here is layout and one is string. Layout references main.xml and the string class references all of our string entries. Because of R.java these 2 xml files are able to communicate even though the XML file strings.xml doesnt use @string anywhere in it. Hopefully this clears that up and that was actually a great question. Any more feel free to ask and I will hopefully have an answer!
@Greg – Thanks! That makes sense… not to have resources set in stone and there to actually be a link file, it was just a little unclear that there was a reference file that linked out to all of these other files. I suppose if you really wanted, you could rename @string to be something shorter, but it probably just muds up the ability for others to read your code.
I’ve made a Hello World app off the Android Developers walk-through, but never really went into understanding /how/ the whole deal works together.
What Marco said — is there a good graphical editor for doing UIs? I like that the UI is defined in a static XML file, not assembled in procedural code… more like a markup language, which is nice. But some kind of WYSIWYG would be handy, and I didn’t see any references for that yet.
@Nick, @Greg: The “R” class is like duct tape and “the force”; it’s an unseen entity that holds the universe together! :-)
Love the tutorials thus far. One note: Starting off with the process of making a copy of the last “Hello World” project really threw me off — I ended up screwing up a bunch of things and having to start the whole project over from scratch. Might’ve just been my programming inexperience, but still.
Second thing — I had to create a brand-new Android VM to run this properly. Not sure why. Anyone have any ideas?
Greg, Something wrong with my set up? When I create the String resouce to be used as text on the button of the Improved Hello World, things seem to be OK, However, using it is another matter, an error is always generated indicating –
error: Error: No resource found that matches the given name (at ‘text’ withvalue ‘@string/press’).main.xml /HelloWorld/res/layout line 17 Android AAPT Problem
if I hardcode the text in no such error is generated. Any idea?
Ramon
@Saragon:
For your second thing: I’ve had similar issues where sometimes the emulator ignores the current project, and insists on running *the last* project I was working on. Usually, cleaning the current project makes the problem go away:
– Select Project>Clean…
– Choose “Clean projects selected below”
– Select the project you want to clean.
– Check “Start a build immediately”.
– Select “Build only the selected projects”.
– Click OK.
That worked for me, YMMV.
@Everyone Thank you for the helpful tips. I apologize as I’m pretty green to this. I also copy and pasted from the tutorial which meant I needed to go back and adjust my quotations and such. I worked myself down from 8 errors to 2 last night before going to bed.
@Greg I’ll email you later tonight if I get the chance. I also want to tell you how empowering this Tutorial is to a new user. Thank you very much! And thank you for making yourself available to help!
Thanks to the Author and thanks to all that posted the missing imports!
This was fun and I look forward to the next one.
@Greg,
I noticed that if I copy your code verbatim the quotes are seen as something else, not sure what.
Anyway, I found that deleting them and typing them in fixes the problem. Must be some weird copy paste bug? I am using chrome on win7.
Hi Greg,
I’ve copied the program exactly as you’ve put it up, except for two small changes. I named my Activity “HelloWorldMain” and the target is Android 2.2.
Now, I get errors whenever I run the app. The errors occur at lines where R.id is used, and the error thrown by eclipse is “R.id cannot be resolved”. I checked the autogenerated R.java file, and there seems to be no id field. I’ve pasted its contents below.
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package com.testworld.helloworld;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}
What am I doing wrong?
I have two lines with errors.
-> Button button = (Button)findViewById(R.id.go);
go cannot be resolved or is not a field
and
-> helloName = (EditText)findViewById(R.id.helloName);
helloName cannot be resolved or is not a field
Any ideas?
Thanks,
John
Found my answer. If you copied the code from this page, go to the main.xml and replace the quotation marks. :) Now to build!
again thanks for the tutorial, I can’t wait to try more. also thanks @john I was having the same issue as you
@Apoorva
You are getting the R.id error because you copied the main.xml content from here directly. As the contents of R.java file is auto generated, it depends on what you type in the xml file and copying usually creates the problem.
To solve this issue, open the main.xml file again. Click wherever you have used “@+id/”. Press Ctrl+space and select the value again from the list it pops up.
OR
Delete the id value and type the same thing again.
Hope this helps.
i am getting the R.id error also, and i didnt copy and paste the text :[. anyone know why?
at this section:
“This next section will contain a lot of code and I will provide most of the screenshots of the code to help you through. First, it is good to realize every time you would like to reference an object in your layout we need to import it. We will need to add imports for our button and textbox. We can do that bu adding these lines of code to the imports section at the top:”
I found confusing, because this section, I think, means to refer to the “HelloMain.java” file, but doesn’t seem to explain this transition from editing the “main.xml” to the “HelloMain.java” file. That is, I first assumed that the above quoted commands for adding imports to the “imports secton at the top” where meant in the “main.xml” file. Kinda confusing…
Otherwise awesome though, thanks!
Nice Tutorial,specially for beginner. I appreciate. But can this be scale down to Dialogbox instead of using Toast?
Thank you for the great tutorials. They are helping a lot in helping me to learn how to use this Android dev environment.
For the folks that keep getting the r.id errors, make sure that you modify the right “HelloMain.java” file. I got the error at first as well, and realized that I added the code to the HelloMain from the first HelloWorld app. A good mistake to learn from though. Good to know that Eclipse keeps files open from multiple projects at the same time. :)