Android Development Tutorial 7

Android Development TutorialWelcome to part 7 of my Android Development Tutorial! Today I will continue what I started in the last Android tutorial.

I cover how to do all of the following: Pass values between activities : Save key value pairs : Use OnClickListeners : Retrieve saved data : Use ScrollViews : Use Alert Dialog Boxes : Use Intents to Open Applications : Use Intents to Open Activities : Force Close the Keyboard : Much More… Download all the code here

If you like videos like this, it helps to tell Google+ with a click here [googleplusone]

Code From the Video

package com.newthinktank.stockquotes;

import java.util.Arrays;

import android.os.Bundle;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class MainActivity extends Activity {
	// Store a unique message using your package name to avoid conflicts
	// with other apps. This stores the stock symbol I plan on displaying
	public final static String STOCK_SYMBOL = "com.example.myfirstapp.STOCK";
	// Manages key valued pairs associated with stock symbols
	private SharedPreferences stockSymbolsEntered;
	// Table inside the scroll view that holds stock symbols
	// and buttons
	private TableLayout stockTableScrollView;
	// Where the user enters a new stock symbol
	private EditText stockSymbolEditText;
	// Button that enters a new stock and another that
	// deletes all of them
	Button enterStockSymbolButton;
	Button deleteStocksButton;

	// Set up the activity
	protected void onCreate(Bundle savedInstanceState) {
		// Retrieve saved stocks entered by the user. 
		// MODE_PRIVATE: Only accessible by your app (Most Common)
		// MODE_WORLD_READABLE: Any app can read (Can OR with Following)
		// MODE_WORLD_WRITABLE: Any app can write to this
		stockSymbolsEntered = getSharedPreferences("stockList", MODE_PRIVATE);
		// Initialize Components
		stockTableScrollView = (TableLayout) findViewById(;
		stockSymbolEditText = (EditText) findViewById(;
		enterStockSymbolButton = (Button) findViewById(;
		deleteStocksButton = (Button) findViewById(;
		// Add ClickListeners to the buttons
		// Add saved stocks to the Stock Scrollview
	// Either adds a new stock or if null is entered the stock
	// list is updated with saved stocks
	private void updateSavedStockList(String newStockSymbol){
		// Get the saved stocks
		String[] stocks = stockSymbolsEntered.getAll().keySet().toArray(new String[0]);
		// Sort the stocks in alphabetical order
		Arrays.sort(stocks, String.CASE_INSENSITIVE_ORDER);
		// If the attribute sent to this method isn't null
		if(newStockSymbol != null){
			// Enter the new stock in sorted order into the array
			insertStockInScrollView(newStockSymbol, Arrays.binarySearch(stocks, newStockSymbol));
		} else {
			// Display saved stock list
			for(int i = 0; i < stocks.length; ++i){
				insertStockInScrollView(stocks[i], i);
	private void saveStockSymbol(String newStock){
		// Used to check if this is a new stock
		String isTheStockNew = stockSymbolsEntered.getString(newStock, null);
		// Editor is used to store a key / value pair
		// I'm using the stock symbol for both, but I could have used company
		// name or something else
		SharedPreferences.Editor preferencesEditor = stockSymbolsEntered.edit();
		preferencesEditor.putString(newStock, newStock);
		// If this is a new stock add its components
		if(isTheStockNew == null){
	private void insertStockInScrollView(String stock, int arrayIndex){
		// Get the LayoutInflator service
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		// Use the inflater to inflate a stock row from stock_quote_row.xml
		View newStockRow = inflater.inflate(R.layout.stock_quote_row, null);
		// Create the TextView for the ScrollView Row
		TextView newStockTextView = (TextView) newStockRow.findViewById(;
		// Add the stock symbol to the TextView
		Button stockQuoteButton = (Button) newStockRow.findViewById(;
		Button quoteFromWebButton = (Button) newStockRow.findViewById(;
		// Add the new components for the stock to the TableLayout
		stockTableScrollView.addView(newStockRow, arrayIndex);
	public OnClickListener enterStockButtonListener = new OnClickListener(){

		public void onClick(View theView) {
			// If there is a stock symbol entered into the EditText
			// field
			if(stockSymbolEditText.getText().length() > 0){
				// Save the new stock and add its components
				stockSymbolEditText.setText(""); // Clear EditText box
				// Force the keyboard to close
				InputMethodManager imm = (InputMethodManager)getSystemService(
					imm.hideSoftInputFromWindow(stockSymbolEditText.getWindowToken(), 0);
			} else {
				// Create an alert dialog box
				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
				// Set alert title 
				// Set the value for the positive reaction from the user
				// You can also set a listener to call when it is pressed
				builder.setPositiveButton(R.string.ok, null);
				// The message
				// Create the alert dialog and display it
				AlertDialog theAlertDialog = builder.create();;
	private void deleteAllStocks(){
		// Delete all the stocks stored in the TableLayout
	public OnClickListener deleteStocksButtonListener = new OnClickListener(){

		public void onClick(View v) {
			// Editor is used to store a key / value pairs
			SharedPreferences.Editor preferencesEditor = stockSymbolsEntered.edit();
			// Here I'm deleting the key / value pairs

	public OnClickListener getStockFromWebsiteListener = new OnClickListener(){

		public void onClick(View v) {
			// Get the text saved in the TextView next to the clicked button
			// with the id stockSymbolTextView

			TableRow tableRow = (TableRow) v.getParent();
            TextView stockTextView = (TextView) tableRow.findViewById(;
            String stockSymbol = stockTextView.getText().toString();
            // The URL specific for the stock symbol
            String stockURL = getString(R.string.yahoo_stock_url) + stockSymbol;
            Intent getStockWebPage = new Intent(Intent.ACTION_VIEW, Uri.parse(stockURL));
	public OnClickListener getStockActivityListener = new OnClickListener(){

		public void onClick(View v) {
			// Get the text saved in the TextView next to the clicked button
			// with the id stockSymbolTextView

			TableRow tableRow = (TableRow) v.getParent();
            TextView stockTextView = (TextView) tableRow.findViewById(;
            String stockSymbol = stockTextView.getText().toString();
            // An intent is an object that can be used to start another activity
            Intent intent = new Intent(MainActivity.this, StockInfoActivity.class);
            // Add the stock symbol to the intent
            intent.putExtra(STOCK_SYMBOL, stockSymbol);
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(, menu);
		return true;


48 Responses to “Android Development Tutorial 7”

  1. Pradeep says:

    Awesome Derek, No words for all your tutorials, I have already followed your Design Patterns and Object Oriented Design,

    It is really amazing a person expert on each and every area.

    I am perfectly following very closely Android Tutorial, and waiting for rest of them also.

    Also Derek, is it possible for you, to teach us on any ESB such as, Mule-ESB


    • Derek Banas says:

      Thank you very much for the kind words. I do the best I can to make the videos quick and to cover as much information as possible. Sorry, but I have never used Mule-ESB, so I can’t help with it

  2. Dorothy says:

    I’m stopping mid tutorial to tell you how awesome you are! I love your tutorials. This is exactly the stuff I need to know right now – so lucky I found you. You’re fast and thorough. The second a question pops in my head, you answer it. Best tutorials I’ve ever seen and normally I can’t sit through five minutes πŸ™‚

    • Derek Banas says:

      Thank you very much πŸ™‚ I greatly appreciate you taking the time to say such nice things. I do my best to constantly improve. The input I have received from my community has really helped a lot.

  3. Oren says:

    Great tutorials, I’ve been flowing along the Java tutorials and now the Android ones and I really appreciate the effort you put into them.

    I tried to compile the code, but it crushed on the line –
    stockTableScrollView = (TableLayout) findViewById(;

    I looked for – stockTableScrollView ID in the previous tutorial, but didn’t find it.

    One more thing, I think it’s better to use the list view and an adapter instead of the scroll view. That way each view will be recycle once it’s not on the screen.

    Thank you for all the great tutorials!

  4. Matt says:

    Hey Derek,

    I’m really enjoying the videos and I really love the methods of teaching that you have adopted. While following along with this tutorial I noticed I was getting an error with the


    and the error reads

    Call requires API level 9 (current min is 8): android.content.SharedPreferences.Editor#apply

    I noticed there are several suppress warnings that could be applied.

    What would be the best way to deal with this? Or how would one go about updating the min API level?

    With great appreciation,


  5. Chi says:

    Your tutorials have really helped me with my school projects, Thanks you very much. Please would it be possible to provide advice on how to send details entered by a user from an android app to a Microsoft Access database, a tutorial on it would be great!!

  6. Thaddeus says:

    These are the best tutorials for android development. I am running into a problem though. I when I use add unimplemented methods for the OnClickListener the parameters for the onClick() method are completely different from whats in the tutorial. Instead of getting onClick(View v), I get onClick(DialogueInterface dialogue, int which). Any idea why that’s happening?

    • Derek Banas says:

      Thank you for the kind words πŸ™‚ I’m not sure about the problem your having. Does everything run after you put in the code?

    • Jeff says:

      I had the same issue, eclipse imported the wrong item. Check your imports for any onclicklisteners and delete them and add import android.view.View.OnClickListener;
      Mine was pulling a listener for the Dialog interface package.

  7. Richard Lucas says:

    At 4:06, what is the difference between these two lines. I know they both allow for the saving and restoring of data when the app is closed, but how are they different?

    public final static String STOCK_SYMBOL = “com.example.myfirstapp.STOCK”;

    private SharedPreferences stockSymbolsEntered;

    At 10:06, can you better explain what each method call on this line is doing, I especially do not understand that newString[0] part:

    String[] stocks = stockSymbolsEntered.getAll().keySet().toArray(new String[0]);

    Thank you very much Derek

    • Derek Banas says:

      SharedPreferences store many key / valued pairs of data that can be accessed by all activities. You can put many values in it. STOCK_SYMBOL on the other hand will only store one value.

      stockSymbolsEntered is of type SharedPreferences. getAll() retrieves all values that are stored. keySet() returns all keys from the map. toArray() puts them in an Array. String[0] gets the very first key in the Array.

      I hope that helps πŸ™‚

      • Nadeem says:

        I still can’t figure out one thing in this line:

        stockSymbolsEntered = getSharedPreferences(“stockList”, MODE_PRIVATE);

        “stockList” – you’re using this list name, but I don’t know where did you declare it? It seems it just came from nowhere!?

        • Derek Banas says:

          stockList is just a name that is actually being created by getSharedPreferences.

          public abstract SharedPreferences getSharedPreferences (String name, int mode)

          Retrieve and hold the contents of the preferences file ‘name’, returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other’s edits as soon as they are made.


          name Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).

          mode Operating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targetting Gingerbread (Android 2.3) and below, and off by default in later versions.

          The single SharedPreferences instance that can be used to retrieve and modify the preference values.

          Source :, int)

  8. Cbin says:

    Your videos are awesome,Before watching your videos i was following a lot of other tutorial videos.let me tell you the truth you are the best

  9. Shasha says:

    Getting error @ line 245 in

    Intent intent = new Intent(MainActivity.this,StockInfoActivity.class);

    “StockInfoActivity” cannot be resolved to a type.

    • Derek Banas says:

      Make sure you try my exact code and it will work. This is normally an error that comes up when the package isn’t imported. The first line should be import package

      • Aldi says:

        Say, i encountered the exact same error and when i hover to it, the only possible fix is create class,enum,interface and fix project setup, no import.

        Maybe i’m wrong but is StockInfoActivity related to stock_quote_row?

  10. One question to you: In which cases is better to use ListView than TableLayout with TableRows, for example if you need to make a schedule of data, What you would use the list view or table view to present data?

    • Derek Banas says:

      It really depends on what you want to do.

      You could create a scrolling list of items with a LinearLayout in a ScrollView. You could also use a ListView with an Adapter.

      You’d get similar results with a TableLayout inside a ScrollView. You could do the same with a GridView with an Adapter.

      LinearLayout and TableLayout require an XML layout definition. ListView and GridView require an Adapter to bind data to them.

      I hope that helps πŸ™‚

  11. Domenico says:

    Hi Derek,
    In your finished app there is an annoying behavior I don’t know how to fix.
    If I rotate the screen, the TextViews are randomly repopulated, or maybe, as I noticed, all the stocks in the list became like the last stock that was in the list prior to rotating the device.
    I guess this has something to do with the ‘Bundle savedInstance’ you covered in the previous part of the tutorial, but I am not sure.
    Also, if click the various buttons, the browser page is the same.
    However, if I put the app in background, and then I reopen it, all seem as the confusion between the TextViews was never happened.
    What do you think I should look into, to solve this kind of problem?
    What’s happening when I rotate my device?

    Thank you for this awesome series, good luck πŸ™‚

    • Derek Banas says:

      I should have made a horizontal layout for the app. I cover how to do that later in the tutorial. My approach in this series was to cover as much as possible, but not to necessarily create a perfect app. If I did that it would take forever to make just one app and it would be very overwhelming. Just move to the next tutorial and I cover everything you need if you want to go back and fix it up later. Sorry about any confusion I caused.

  12. Sothearith Sreang says:

    Hi Derek, awesome tutorials. You are a really good explainer. Anw, I have a question for the last part. I quite don’t get how the Intent object, getStockWebPage is able to go to a web browser to link to the url. To be specific, how does this object know that it has to start the web browsing activity? by Intent.ACTION_VIEW??

    • Derek Banas says:

      Thank you πŸ™‚ Yes ACTION_VIEW is used when you want to perform an action on data, which in this case is to parse the provided URL. I cover Intents in great detail as the tutorial continues.

  13. DewaldvS says:

    I followed your tutorials and have not yet encountered an issue up an till now.
    So first off thanks for the great work.

    I have tried to follow each step and even looked at your source files but for some reason when I try and run the StockQuote app on the device I get the message Unfortunately, Get Stock Quotes has stopped.

    I am very new to mobile development.
    But I cant figure out if this is an environment setting or a code issue causing the app to crash?

    Thank you for your help.

  14. Walter Reyes says:

    Hi, Derek

    I just want to ask you something

    In the method: saveStockSymbol
    Would not it be better, in terms of performance, if we put the string newStock in the SharedPreference after we check if it already exists?

    I mean something like this:

    private void saveStockSymbol(String newStock){

    String isTheStockNew = stockSymbolsEntered.getString(newStock,null);

    if(isTheStockNew == null){

    SharedPreferences.Editor preferencesEditor = stockSymbolsEntered.edit();




    Instead of:

    private void saveStockSymbol(String newStock){

    String isTheStockNew = stockSymbolsEntered.getString(newStock,null);

    SharedPreferences.Editor preferencesEditor = stockSymbolsEntered.edit();

    if(isTheStockNew == null){



    I know it does not affects the funcionality because it just overwrites the key.

    I understand you do not stop in performance matters because you cover a lot!
    But i just wanted to ask (=

    Regards, and thanks for the awesome tutorials!

    • Derek Banas says:

      Yes I think that would be a good idea. As you said I pretty much write this code out of my head and so it isn’t optimized. I appreciate you taking the time to help πŸ™‚

  15. Mel says:

    Hey Derek,

    i have problems at the following code lines:

    stockTableScrollView = (TableLayout) findViewById(;
    stockSymbolEditText = (EditText) findViewById(;

    Intent intent = new Intent(MainActivity.this, StockInfoActivity.class);

    the first two lines give error because there seem to be no stockTableScrollView and stockSymbolEditText in R. and the last code line complains that the class StockInfoActivity hasn’t been created.

    thanks in advance! great work btw.


  16. Sangram Gupta says:

    Hey Derek,

    I am big fan of yours and really like your tutorials. Most succinct tutorials on Android online.

    Also, you helping each and replying each person even through your PR staff shows the humility you posses. Seriously you have earned my earnest respect.


    • Derek Banas says:

      Hey Sangram,

      I wish I had a PR staff πŸ™‚ I do my best. Thank you very much for taking your time to show your appreciation. The new Android tutorials will come out very soon.

  17. Mohit Saxena says:

    hey Derek, Thanks again man for the wonderful, wonderful tutorials. I actually started with your tutorials in Android Studio, but moved to Eclipse Studio once I completed all the tutorials there.

    Now I am using these tutorials to learn the things in Android Studio, hope that I am not messing around, both the IDEs are almost same, and you have already covered a lot of content here.

    So, while trying out things designed from something and testing on others, I faced my first show stopper kind of issue. Its difficult to explain in words, but still I’ll try.

    So, consider a scenario of table layout where I have added a table row and added 3 components (say a textView, EditText & a button, much like your EnterSymbol, , Enter button). Now I added another table row just below the last one. I added just one component here (say a TextView, much like Stock Symbols and Quotes), this TextView takes up just first cell of the 2nd row (a table will be created with 3 columns on entire screen). I tried your layout_span trick, but it didn’t gave very satisfactory result. On landscape mode, text is not centred.

    The main problem is coming with ScrolableText area where everything is trying to fit in just first column. Don’t know what to do.

    I know I explained my problem pathetically, but please do help me. I genuinely need your help to sort this out. Please do tell me if you need more clarification on this.

    PS. I tried to run your code on Android Studio. Same result, so you can try same on your own. πŸ™‚

    Thanks a ton buddy in adavance πŸ˜›

    • Derek Banas says:

      Hey Mohit,

      Sorry about any confusion I caused. I made this video a long time ago. (I’m continuing the Android Studio tutorial next week) I may not have covered making a separate layout for horizontal in this tutorial. When I was making the first Android tutorials I didn’t make complete optimized apps. Either way to fix that issue you’d need to just make a horizontal layout and it would fix everything.

      • Mohit Saxena says:

        hey Derek, thanks for solution. I’ll try that. however, meanwhile I tried adding tablelayout in table row and creating table rows in inner table layout. not the best solution I guess. I think if I remember well, you have once told in some video that multiple layouts will make ui slower as more code will be there to parse…so anyways I’ll try your approach. not in best of health so may be delayed a bit πŸ˜€

        Also, I got a request for you. If you can make some tutorial for AsynTask and other methods to interact with UI thread from application thread, that will make a clear a lot of things. Also a background threads like of process.

        And another request is for MediaStore and its nested classes. Totally confused by android docs πŸ™

        For now, anxiously waiting for your new video.

        Cheers!!! πŸ™‚

Leave a Reply

Your email address will not be published.