Android Development Tutorial 3

Android User InterfaceIn this part of my Android Development Tutorial, I will build an Android user interface.

I cover how to do numerous things: How to use the Android Visual Layout Editor, How to edit the GUI layout by editing the XML, How to use TextView, EditText and the SeekBar, How to catch events, How to save the apps state with onSaveInstanceState(), How to get values from components and how to change the values. The video and code below will teach you all you need to start making apps.

If you like videos like this, it helps to tell Google+ by clicking here

Special Note

I have received many questions about the lines:

private static final String TOTAL_BILL = “TOTAL_BILL”;
private static final String CURRENT_TIP = “CURRENT_TIP”;
private static final String BILL_WITHOUT_TIP = “BILL_WITHOUT_TIP”;

and then also lines:

billBeforeTip = savedInstanceState.getDouble(BILL_WITHOUT_TIP);
tipAmount = savedInstanceState.getDouble(CURRENT_TIP);
finalBill = savedInstanceState.getDouble(TOTAL_BILL);

and also lines:

outState.putDouble(TOTAL_BILL, finalBill);
outState.putDouble(CURRENT_TIP, tipAmount);
outState.putDouble(BILL_WITHOUT_TIP, billBeforeTip);

What I think is confusing everyone is the final in

private static final String TOTAL_BILL = “TOTAL_BILL”;

The value isn’t stored in TOTAL_BILL, TOTAL_BILL stores the name for the key that is associated with value. These are key value pairs. I should have pointed that out better.

Then when putDouble(String key, double value) is called it inserts a double value into the Bundle, and replaces the value for the given key.

I hope that clears that up. Sorry about any confusion.

If you are having trouble with the SeekBar

If your app is crashing when you use the seekbar it is because I don’t except commas in the price. Make sure you enter a period before the change amount and you should have anymore crashes. Sorry about that.

Code From the Video

Here is the whole Android App Package available for download!

Below is the code changes made to make this Android unser interface

activity_crazy_tip_calc.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".CrazyTipCalc" >

    <TextView
        android:id="@+id/billTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="14dp"
        android:layout_marginTop="14dp"
        android:text="@string/bill_text_view" />

    <!-- android:ems defines the width of the EditText box -->

    <EditText
        android:id="@+id/billEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_toRightOf="@+id/billTextView"
        android:ems="5"
        android:inputType="numberDecimal"
        android:text="@string/bill_edit_text" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/tipTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/billTextView"
        android:layout_marginLeft="15dp"
        android:layout_toRightOf="@+id/billEditText"
        android:text="@string/tip_text_view" />

    <EditText
        android:id="@+id/tipEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/finalBillTextView"
        android:layout_marginLeft="18dp"
        android:layout_toRightOf="@+id/tipTextView"
        android:ems="4"
        android:inputType="numberDecimal"
        android:text="@string/tip_edit_text" />

    <TextView
        android:id="@+id/finalBillTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/finalBillEditText"
        android:layout_below="@+id/billEditText"
        android:layout_marginTop="14dp"
        android:text="@string/final_bill_text_view" />

    <EditText
        android:id="@+id/finalBillEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/tipEditText"
        android:layout_below="@+id/finalBillTextView"
        android:ems="5"
        android:inputType="numberDecimal"
        android:text="@string/final_bill_edit_text" />

    <TextView
        android:id="@+id/changeTipTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/finalBillTextView"
        android:layout_alignLeft="@+id/billTextView"
        android:text="@string/change_tip_text_view" />

    <!-- android:progress="15" defines the default for the SeekBar -->
    
    <SeekBar
        android:id="@+id/changeTipSeekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/changeTipTextView"
        android:layout_alignTop="@+id/finalBillEditText"
        android:layout_marginTop="14dp"
        android:layout_toLeftOf="@+id/tipTextView" 
        android:progress="15" />

</RelativeLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">CrazyTipCalc</string>
    <string name="action_settings">Settings</string>
    
    <string name="bill_text_view">Bill</string>
    <string name="bill_edit_text">0.0</string>
    
    <string name="tip_text_view">Tip</string>
    <string name="tip_edit_text">.15</string>
    
    <string name="final_bill_text_view">Final Bill</string>
    <string name="final_bill_edit_text">0.0</string>
    
    <!-- END OF FIRST PART -->
    
    <string name="change_tip_text_view">Change Tip</string>

</resources>

CrazyTipCalc.java

package com.newthinktank.crazytipcalc;

import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class CrazyTipCalc extends Activity {
	
	// Constants used when saving and restoring
	
	private static final String TOTAL_BILL = "TOTAL_BILL";
	private static final String CURRENT_TIP = "CURRENT_TIP";
	private static final String BILL_WITHOUT_TIP = "BILL_WITHOUT_TIP";
	
	private double billBeforeTip; // Users bill before tip
	private double tipAmount; // Tip amount
	private double finalBill; // Bill plus Tip
	
	EditText billBeforeTipET;
	EditText tipAmountET;
	EditText finalBillET;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_crazy_tip_calc); // Inflate the GUI
		
		// Check if app just started, or if it is being restored
		
		if(savedInstanceState == null){
			
			// Just started
			
			billBeforeTip = 0.0;
			tipAmount = .15; 
			finalBill = 0.0; 
			
		} else {
			
			// App is being restored
			
			billBeforeTip = savedInstanceState.getDouble(BILL_WITHOUT_TIP);
			tipAmount = savedInstanceState.getDouble(CURRENT_TIP); 
			finalBill = savedInstanceState.getDouble(TOTAL_BILL); 
			
		}
		
		// Initialize the EditTexts
		
		billBeforeTipET = (EditText) findViewById(R.id.billEditText); // Users bill before tip
		tipAmountET = (EditText) findViewById(R.id.tipEditText); // Tip amount
		finalBillET = (EditText) findViewById(R.id.finalBillEditText); // Bill plus tip
		
		// SECOND PART ---------------
		
		// Initialize the SeekBar and add a ChangeListener
		
		tipSeekBar = (SeekBar) findViewById(R.id.changeTipSeekBar);
		
		tipSeekBar.setOnSeekBarChangeListener(tipSeekBarListener);
		
		// ---------------------------
		
		// Add change listener for when the bill before tip is changed
		
		billBeforeTipET.addTextChangedListener(billBeforeTipListener);
	}
	
	// Called when the bill before tip amount is changed
	
	private TextWatcher billBeforeTipListener = new TextWatcher(){

		@Override
		public void afterTextChanged(Editable arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
				int arg3) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onTextChanged(CharSequence arg0, int arg1, int arg2,
				int arg3) {
			
			try{
				
				// Change the billBeforeTip to the new input
				
				billBeforeTip = Double.parseDouble(arg0.toString());
				
			}
			
			catch(NumberFormatException e){
				
				billBeforeTip = 0.0;
				
			}
			
			updateTipAndFinalBill();
			
		}
		
	};
	
	// Update the tip amount and add tip to bill to
	// find the final bill amount
	
	private void updateTipAndFinalBill(){
		
		// Get tip amount
		
		double tipAmount = Double.parseDouble(tipAmountET.getText().toString());
		
		// The bill before tip amount was set in billBeforeTipListener
		
		// Get the bill plus the tip
		
		double finalBill = billBeforeTip + (billBeforeTip * tipAmount);
		
		// Set the total bill amount including the tip
		// Convert into a 2 decimal place String
		
		finalBillET.setText(String.format("%.02f", finalBill));
		
	}
	
	// Called when a device changes in some way. For example,
	// when a keyboard is popped out, or when the device is 
	// rotated. Used to save state information that you'd like
	// to be made available.
	
	protected void onSaveInstanceState(Bundle outState){
		
		super.onSaveInstanceState(outState);
		
		outState.putDouble(TOTAL_BILL, finalBill);
		outState.putDouble(CURRENT_TIP, tipAmount);
		outState.putDouble(BILL_WITHOUT_TIP, billBeforeTip);
		
	}
	
	// ---- END OF FIRST PART ----
	
	// ---- SECOND PART ----------
	
	// SeekBar used to make a custom tip
	
	private SeekBar tipSeekBar;
	
	private OnSeekBarChangeListener tipSeekBarListener = new OnSeekBarChangeListener(){

		@Override
		public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
			
			// Get the value set on the SeekBar
			
			tipAmount = (tipSeekBar.getProgress()) * .01;
			
			// Set tipAmountET with the value from the SeekBar
			
			tipAmountET.setText(String.format("%.02f", tipAmount));
			
			// Update all the other EditTexts
			
			updateTipAndFinalBill();
			
		}

		@Override
		public void onStartTrackingTouch(SeekBar arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onStopTrackingTouch(SeekBar arg0) {
			// TODO Auto-generated method stub
			
		}
		
	};
	
	// ---- END OF SECOND PART ----------

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.crazy_tip_calc, menu);
		return true;
	}

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.newthinktank.crazytipcalc"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.newthinktank.crazytipcalc.CrazyTipCalc"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

170 Responses to “Android Development Tutorial 3”

  1. Secc says:

    Hi, Absolutely loving the Android tuts, thanks so much – keep them coming….

    Secc

  2. conor says:

    Brilliant tutorial, nicely presented ..looking forward to your next Android tut !!

  3. JC26 says:

    I’m very happy that you begin android tutorials. I think it is the best course that you ever made from teaching prespective. You cover a wide range of things,you explain everything both theoritical and practical and you develop useful applications.
    You are a master,keep up this way.

    • Derek Banas says:

      Thank you very much πŸ™‚ I really want this series to completely teach everything. I think the need for programmers that can program for Android devices will continue to grow for some time. I hope I’ll be able to help

  4. Marko says:

    Hi Derek, are you familiar with PLC programming?

  5. Atif says:

    Hi , Derek Thank you so much . Great stuff btw .
    I noticed that there’s a link for downloadable source code , which is great .
    I asked you for that lately , so thank you for taking that into consideration .
    Keep it up

    You are the man !

  6. CrunchB says:

    Hi Derek,

    Thank You for these wonderful tutorials.

    Keep up the great work. πŸ™‚

  7. Gaston Aguirre says:

    Hi Derek, I’m new to your android course (lets face it, is not a “tutorial” is a whole class!) and I’m very glad that I came upon it. I already subscribed to your channel and hoked up with your videos. thank you for taking the time and effort to share you vast knowledge.
    Regards from Argentina.

  8. john says:

    Hi Derek loving your tutorials and the way you explain things.

    Have one slight problem maybe you could help me with. I’ve downloaded your code and everything works fine on the emulator
    and a actual device running 4.2.2. However if I try running it on a another device that has 4.0.3, everytime i touch the seekbar the i get the “Unfortunately. CrazyTipCalc has stopped.” message.

    How do I view errors, when running apps on the phone, in eclipse.

    Thanks for your time

    • Derek Banas says:

      That is strange. The logcat should show errors for the emulator and any Android device connected. You could try this app which can be used to look at your phones error log https://play.google.com/store/apps/details?id=ukzzang.android.app.logviewer&hl=en

      • john says:

        Hi again Derek, sorry to be a bother.

        Thanks for your help and quick reply.

        Just thought I’d let you know what I’ve found and maybe see if you have any ideas why this happens.

        I used this code to test(within onCreate method) after seeing the error NumberFormatException : Invalid Double :-

        EditText test = (EditText) findViewById(R.id.editText1);
        test.setText(String.format(“%.02f”, Double.parseDouble(tipAmountET.getText().toString())));

        On the device running 4.2.2 the test textfield displays 0.15, however on the device running 4.0.3 the same textfield displays 0,15. From this it is clear the comma is causing the problem when formatting.

        Thanks again for your help.

        • Derek Banas says:

          Thank you for bringing that to my attention. As the tutorial continues, I’ll cover how to make sure your app works on numerous devices. I have been holding back on that so far because I want to cover all the basics first. There is much work to do to make apps that run on 60% of devices in the world, but I’ll get through it eventually

          • Roger says:

            I’ve had the same problem trying to get the app to run on my htc sensation.

            It turns out the problem is with the locale your device is set to. If you’re from europe (as i am) your most likely to have a “,” as a number separator instead of a “.” This causes problems with setting the text and the code errors out.

            This is what i did to solve this problem.

            Instead of
            tipAmountET.setText(String.format("%.02f", tipAmount));

            i do

            NumberFormat formatter = NumberFormat.getInstance(Locale.US);
            tipAmountET.setText(formatter.format(tipAmount));

            and apply this everytime you set text via code. hope this helps

  9. wilfred says:

    Hi Derek i really love the tutorials

    i am having problem running the application on emulator i keep on getting this error Unfortunately, Tipcal has stopped. what should i do about it?

    • Derek Banas says:

      Look in the logcat console. In there it will point out all the errors. Feel free to post them here and I’ll take a look

      • wilfred says:

        Below is the Error i got from logcat

        06-14 14:18:21.485: E/AndroidRuntime(804): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wilfred.tipscal/com.wilfred.tipscal.TipcalActivityMainActivity}: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.widget.SeekBar

        • Derek Banas says:

          If you catch the ClassCastException that should handle that issue for now. I didn’t focus to much time on exception handling at this point because I wanted to teach as many different topics at once in each video. Sorry about the confusion

  10. Static says:

    Hey,

    I tried running the .apk on my Nexus 4 and it crashes everytime i try to open the app :s.

    It worked okay when i used the nexus4 emulator.

    Any ideas?

  11. Arif says:

    An error has occurred. See error log for more details.
    java.lang.NullPointerException.

    Hi Derek
    Best ever tutorial I came across with full code support.
    Only thin is when I tried to open “res-values-strings” Eclipse throws above error.
    Have done something wrong?
    Thanks
    Arif

    • Derek Banas says:

      Thank you very much πŸ™‚ Check out the code in the package I provide for download. A NullPointerException occurs when an object isn’t initialized. There is probably a typo some place

      • PetruBogdanPetrescu says:

        Hi Derek,

        Great work! Thank you!

        I had the same “NullPointerException” when trying to follow this episode.

        The cause was related to the ContentView’s name. Since I am using API 19 as opposed to your API 17, ADT creates two XML layout files (fragment_crazy_tip_calc.xml and activity_crazy_tip_calc.xml).

        In your code, you are setting the ContentView to the value “R.layout.activity_crazy_tip_calc” (as this is the file that holds the RelativeLayout).

        However, with the new version, it should be set to “R.layout.fragment_crazy_tip_calc” (or whatever is the file that actually contains the RelativeLayout).

        Thank you once again.

        Best regards,
        B

  12. Maneesh says:

    When I opened the CrazyTipCalc.java in the code it said (twice) “R cannot be resolved to a variable” any suggestions?

    • Derek Banas says:

      Eclipse sometimes likes to add an “import android.R” statement at the top of your files that use resources, especially when you ask Eclipse to sort or otherwise manage imports. This will cause your make to break. Look out for these erroneous import statements and delete them.

  13. e valens says:

    What if you have TWO editText’s? I want to validate both inputs, basically they are ranges and I want to update a textView based on the changes they made, for example:

    public void onTextChanged(CharSequence s, int start, int before,
    int count) {
    // TODO Auto-generated method stub

    try
    {
    //theFirst = Integer.parseInt(s.toString());
    theFirst = Integer.parseInt(firstText.getText().toString());
    theLast = Integer.parseInt(secondText.getText().toString());

    if (theFirst > theLast)
    {
    updateLabel.setText(“You must flip your integers”);
    }
    else if (theFirst < 0)
    {
    updateLabel.setText("You cannot enter a negative number!");

    }

    guess = (theFirst + theLast) / 2;
    updateLabel.setText("Did you think of " + guess + " ?");

    } catch (NumberFormatException nfe)
    {
    updateLabel.setText("You must enter an integer! ");
    }

    All I am trying to do is, transfer my GUI JAVA in to ANDROID. But I am having trouble how to use this text handler in android, thank you for your time

    • e valens says:

      Actually this is the whole thing so you can understand what I am doing. The problem is that, in my emulator when I enter the different ranges, it does nothing. BUT when I press on a button (like tooHigh or tooLow) the textView changes to “It appears you have changed your number!”

      package com.bignerdranch.android.guessinggame;

      import android.os.Bundle;

      import android.app.Activity;
      import android.text.Editable;
      import android.text.TextWatcher;
      import android.view.Menu;
      import android.view.View;
      import android.widget.Button;
      import android.widget.EditText;
      import android.widget.TextView;
      import android.view.View.OnClickListener;

      public class AlphaActivity extends Activity {

      private static final String TO_BOX = “TO_BOX”;
      private static final String FROM_BOX = “FROM_BOX”;
      // private String updateGuess;
      // private String update_label;

      private int guess, theFirst, theLast;
      //private int count;

      private String update_text;

      EditText firstText;
      EditText secondText;

      TextView updateLabel;

      Button tooHighButton;
      Button tooLowButton;
      Button correctButton;
      Button newGameButton;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_alpha);

      if(savedInstanceState == null){
      // Just started
      theFirst = 0;
      theLast = 100;
      }
      else
      {
      // App is being restored
      theFirst = savedInstanceState.getInt(TO_BOX);
      theLast = savedInstanceState.getInt(FROM_BOX);
      }

      //fromBox = (EditText) findViewById(R.id.firstText);
      //toBox = (EditText) findViewById(R.id.secondText);

      //fromBox.addTextChangedListener(fromBox);
      //toBox.addTextChangedListener(toBox);

      updateLabel = (TextView)findViewById(R.id.updateText);

      firstText = (EditText)findViewById(R.id.firstText);
      firstText.addTextChangedListener(fromBoxListener);

      secondText = (EditText)findViewById(R.id.secondText);
      secondText.addTextChangedListener(fromBoxListener);

      tooHighButton = (Button)findViewById(R.id.guiTooHigh);
      tooLowButton = (Button)findViewById(R.id.tooLowGui);
      correctButton = (Button)findViewById(R.id.correctGui);

      setButtonOnClickListeners();

      }

      private TextWatcher fromBoxListener = new TextWatcher()
      {

      @Override
      public void afterTextChanged(Editable arg0) {
      // TODO Auto-generated method stub

      }

      @Override
      public void beforeTextChanged(CharSequence s, int start, int count,
      int after) {
      // TODO Auto-generated method stub

      }

      @Override
      public void onTextChanged(CharSequence s, int start, int before,
      int count) {
      // TODO Auto-generated method stub

      try
      {
      //theFirst = Integer.parseInt(s.toString());
      theFirst = Integer.parseInt(firstText.getText().toString());
      theLast = Integer.parseInt(secondText.getText().toString());

      if (theFirst > theLast)
      {
      updateLabel.setText(“You must flip your integers”);
      }
      else if (theFirst < 0)
      {
      updateLabel.setText("You cannot enter a negative number!");

      }

      guess = (theFirst + theLast) / 2;
      updateLabel.setText("Did you think of " + guess + " ?");

      } catch (NumberFormatException nfe)
      {
      updateLabel.setText("You must enater an integer! ");
      }

      //updateLabel();

      }

      };

      private void setButtonOnClickListeners(){

      tooHighButton.setOnClickListener(new OnClickListener(){

      public void onClick(View arg0) {

      theLast = (guess – 1);
      guess = (theFirst + theLast) / 2;

      if (theFirst theLast)
      {
      updateLabel.setText(“It appears you changed your number!”);
      } else
      {
      updateLabel.setText(“Did you think of ” + guess + ” ?”);
      }

      }
      });

      tooLowButton.setOnClickListener(new OnClickListener(){

      @Override
      public void onClick(View arg0) {

      theFirst = (guess + 1);
      guess = (theFirst + theLast) / 2;

      if (theFirst theLast)
      {
      updateLabel.setText(“It appears you changed your number!”);
      } else
      {
      updateLabel.setText(“Did you think of ” + guess + ” ?”);
      }

      }
      });

      correctButton.setOnClickListener(new OnClickListener(){

      @Override
      public void onClick(View arg0) {
      updateLabel.setText(“Thank you for playing this game!”);
      }

      });

      }

      // private void updateLabel(){
      //
      // int currentFrom = Integer.parseInt(fromBox.getText().toString());
      // int currentTo = Integer.parseInt(toBox.getText().toString());
      //
      //
      // updateText.setText(“Did you think of ” + guess + ” ?”)
      //
      //
      // }

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.alpha, menu);
      return true;
      }

      }

      Any ideas?

      • e valens says:

        Wait nevermind! This works! I was expecting it to work like JAVA, I was expecting to see the label to change when I press enter, but it automatically changes once I change the EditText

  14. e valens says:

    My app crashes as soon as I press a button?

    package com.bignerdranch.android.guessinggame;

    import android.os.Bundle;

    import android.app.Activity;
    import android.graphics.Color;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.view.View.OnClickListener;

    public class AlphaActivity extends Activity {

    private static final String TO_BOX = “TO_BOX”;
    private static final String FROM_BOX = “FROM_BOX”;
    // private String updateGuess;
    // private String update_label;

    private int guess, theFirst, theLast, count;
    //private int count;

    private String update_text;

    EditText firstText;
    EditText secondText;

    TextView updateLabel;
    TextView currentGuessText;

    Button tooHighButton;
    Button tooLowButton;
    Button correctButton;
    Button newGameButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_alpha);

    count = 0;

    if(savedInstanceState == null){
    // Just started
    theFirst = 0;
    theLast = 100;
    }
    else
    {
    // App is being restored
    theFirst = savedInstanceState.getInt(TO_BOX);
    theLast = savedInstanceState.getInt(FROM_BOX);
    }

    //fromBox = (EditText) findViewById(R.id.firstText);
    //toBox = (EditText) findViewById(R.id.secondText);

    //fromBox.addTextChangedListener(fromBox);
    //toBox.addTextChangedListener(toBox);

    updateLabel = (TextView)findViewById(R.id.updateText);

    firstText = (EditText)findViewById(R.id.firstText);
    firstText.addTextChangedListener(fromBoxListener);

    secondText = (EditText)findViewById(R.id.secondText);
    secondText.addTextChangedListener(fromBoxListener);

    tooHighButton = (Button)findViewById(R.id.guiTooHigh);
    tooLowButton = (Button)findViewById(R.id.tooLowGui);
    correctButton = (Button)findViewById(R.id.correctGui);

    setButtonOnClickListeners();

    }

    private TextWatcher fromBoxListener = new TextWatcher()
    {

    @Override
    public void afterTextChanged(Editable arg0) {
    // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {
    // TODO Auto-generated method stub

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before,
    int count) {
    // TODO Auto-generated method stub

    try
    {
    //theFirst = Integer.parseInt(s.toString());

    theFirst = Integer.parseInt(firstText.getText().toString());
    theLast = Integer.parseInt(secondText.getText().toString());

    if (theFirst > theLast)
    {
    updateLabel.setText(“You must flip your integers”);
    }
    else if (theFirst < 0)
    {
    updateLabel.setText("You cannot enter a negative number!");

    }

    guess = (theFirst + theLast) / 2;
    updateLabel.setText("Did you think of " + guess + " ?");

    } catch (NumberFormatException nfe)
    {
    updateLabel.setText("You must enater an integer! ");
    }

    }

    };

    private void setButtonOnClickListeners(){

    tooHighButton.setOnClickListener(new OnClickListener(){

    public void onClick(View arg0) {

    theLast = (guess – 1);
    guess = (theFirst + theLast) / 2;

    if (theFirst <= theLast)
    {
    secondText.setText("" + theLast);
    updateLabel.setText("Did you think of " + guess + " ?");
    count++;
    currentGuessText.setText("Current guess number is " + count);
    currentGuessText.setTextColor(Color.BLUE);
    } else
    {
    updateLabel.setText("It appears you changed your number!");
    }

    }
    });

    tooLowButton.setOnClickListener(new OnClickListener(){

    @Override
    public void onClick(View arg0) {

    theFirst = (guess + 1);
    guess = (theFirst + theLast) / 2;

    if (theFirst <= theLast)
    {
    firstText.setText("" + theFirst);
    updateLabel.setText("Did you think of " + guess + " ?");
    count++;
    currentGuessText.setText("Current guess number is " + count);
    currentGuessText.setTextColor(Color.BLUE);
    } else
    {
    updateLabel.setText("It appears you changed your number!");
    }
    }
    });

    correctButton.setOnClickListener(new OnClickListener(){

    @Override
    public void onClick(View arg0) {
    updateLabel.setText("Thank you for playing this game!");
    }

    // I still need to remove action listeners

    });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.alpha, menu);
    return true;
    }

    }

  15. juan says:

    hi derek, sorry for bothering you, i’m having some problem with the code, is the same you put here but i feel more confortable implementing the interfaces, i’m having a numberformat exception only when i start the app and try to fill the bill edittext, but when i fill the tip first nothing happens, the app works normally, thanks for your attention, please let me know if you need the code.

    • Derek Banas says:

      I’m sorry if I didn’t explain this better. The idea behind making these videos was to cover as much as possible in each video. I didn’t catch all of the exceptions and other random things. You can make the numberformaterror go away by catching the exception. Sorry about that

  16. Noah Gumbert says:

    Hi Derek (or anyone) i have a question:

    why do we have to define


    if(savedInstanceState == null){
    036
    037 // Just started
    038
    039 billBeforeTip = 0.0;
    040 tipAmount = .15;
    041 finalBill = 0.0;

  17. Noah Gumbert says:

    ***EDIT
    Hi Derek (or anyone) i have a question:

    why do we have to define

    if(savedInstanceState == null){
    036
    037 // Just started
    038
    039 billBeforeTip = 0.0;
    040 tipAmount = .15;
    041 finalBill = 0.0;

    because if the app is just booting shouldn’t it just get the default values from strings.xml?

  18. Jimmy says:

    Hi Derek, I saw your video and coded up the whole thing as you explained. Whenever i run it on my device(android 4.0.4), It says “Unfortunately, …Stopped Working”. I basically get AndroidRuntime.
    Fatal Exception :MissingFormatWidthException -f.
    What should i do?? Let me know if you need my code.

  19. Jimmy says:

    Hi Derek, need some help.
    I was designing an app that would collect data from user, store it somewhere online to allow access to this data to other users of the app. Since SQLite wont work in this case, can you suggest something??

    • Jimmy says:

      A tutorial if possible on one such thing would be of tremendous help! πŸ™‚

    • Derek Banas says:

      You need to create a web service. Then your android app could use a http client to connect to the web service to get your data. I’m thinking about covering that soon. I already talked a bit about a rest service later in the tutorial

  20. Nabsuh says:

    Hi there!

    Firstly, I just want to say thank you for your tutorials and source-code, it’s all excellently taught πŸ™‚

    Now, on to the issue I have πŸ˜›

    Basically whenever I finish the app, I run into a major issue, where if I edit the bill value, the program crashes. I have pasted logcat below:

    07-04 12:23:23.136: W/dalvikvm(8071): threadid=1: thread exiting with uncaught exception (group=0x40e4fac8)
    07-04 12:23:23.146: E/AndroidRuntime(8071): java.lang.NumberFormatException: Invalid double: “”

    The peculiar item is that your code runs perfectly fine, and I’ve compared our code and the main difference is only formatting, which leaves me slightly confused. Could you please advise what error I am making? (Mind you, I have no experience in Java, although I’ve done most of the C’s,so I’m a bit bewildered why I’m experiencing error!)

    Thanks!

    • Nabsuh says:

      I should also clarify by saying on the device I’m testing on (Galaxy-S4) it prompts after the crash:

      “Unfortunately, TipCalculator has stopped”;

      Which is the main error I’m getting.

      • Nabsuh says:

        Nevermind!

        It apparently fixed itself after I had entered text values for tipEditText and finalEditText. How peculiar, does it cause a zero error due to a null input?

        • Derek Banas says:

          Yes that is the reason for the crash. I should have stated in the video that the goal isn’t to make a perfectly working app, but instead to introduce as many Android capabilities as possible. A few exception handlers here and there will fix all the errors that might pop up. I don’t really have time to properly test the apps if I want to make these videos quickly. There is always something strange that will pop up like how people in some countries use commas instead of decimals in currency. I hope that makes sense

  21. Carlos Moreira says:

    Awesome Tutorials, but I have a quick question about downloading the files from your site. When I do -> click on Import on Eclipse > Import from Existing Android Project > Finish, I get this Error “Invalid project Description” , Is there something I am doing wrong? How Do I run your downloaded code on my eclipse so I can run it on my droid? … I already asked this on youtube, not sure which you would see and respond to.

    • Derek Banas says:

      Thank you πŸ™‚ To import a project File – Import – General – Existing projects into workspace – next – check Select root directory – Browse – Select my package and Finish

      To run on device when you click run configuration then click and change the target to your Android device which is plugged into the computer.

      I hope that helps
      Derek

  22. Niels Buekers says:

    Hi. Small question: in the updateTipAndFinalBill function, why do you make new variables:

    double tipAmount = Double.parseDouble(tipAmountET.getText().toString());
    double finalBill = billBeforeTip + (billBeforeTip * tipAmount);

    in stead of saving them to your already existing variables in

    private double billBeforeTip; // Users bill before tip
    private double tipAmount; // Tip amount
    private double finalBill; // Bill plus Tip

    ? Is there a specific reason for this? In my opinion you are keeping things double (no pun intended), and not using the MVC model properly. Thanks for the videos btw!

    • Derek Banas says:

      Hi, I agree, but sometimes when I’m writing code I have to make a judgement call on whether writing unoptimized code sometimes makes it easier to understand what is going on. I always assume that advanced programmers such as yourself will spot the issue and optimize it, while true beginners will at least understand the basics of what I’m trying to teach.

      I hope that makes sense?

      • Niels Buekers says:

        yeah sure I understand now. I am only a beginning android developer so maybe there were some hidden tricks behind this i did not know of, that’s why i asked. Thanks for the reply.

        • Derek Banas says:

          Android is hard to understand in the beginning, but after you get past a few odd things it will make sense

          • Nirvana says:

            I want to build an offline android Dictionary English-Nepali app where there is a database of the words and its corresponding word in other. And, whenever the word is given for search it points out to the nearest match. Can you please explain on how can I build this. Is there any readymade libraries for this?

  23. waheed nazir says:

    Sir Derek Thanks a lot you have given Superb Lectures……

  24. fechar says:

    thank you very much,brilliant tutorial.

  25. Shpat says:

    Great Tutorial!

  26. Allan says:

    This is so great! It was a long time when I did programming. I thought I will not do it again because there’s so many languages and so many versions, and I thought mobile App development is complicated… until, I saw your videos. It’s so informative and for sure I will watch all of it. THANKS A LOT!

  27. Alan says:

    Sorry to bother you Derek, but i’ trying to find what i did wrong when Eclipse block me with this error message on:

    super.onSaveInstanceState(outState);

    error message is: The method onSaveInstanceState(Bundle) is undefined for the type Object

    i’m gona continu to check every line but if you have an idea and a couple of minutes to spare by writing something about that. that will be helpful. Thanks anyway for your work, it’s awesome.

  28. snehadeep says:

    shouldn’t the savedInsatanceState.getDouble(…) function be called in the onResume(…) function? because according to the Process Lifecycle when a background comes back to focus, onResume() in called.

  29. Alan says:

    Hey Derek,
    I just finish the tutorial (added the SeekBar) today and when i tried it, it crashes my app. So i check the log and find an error about
    tipAmountET.setText(String.format(“%.02f”, tipAmount));
    The log said: java.lang.NumberFormatException: invalid double: “0,10”
    I search about 30 min what i did wrong and finaly find out…
    My computer local settings are french and we type our number with a semicolone instade a dot so for those foreigners who are following your tutorials dont forget to add the local value for the string format like so:

    tipAmountET.setText(String.format(Locale.us, “%.02f”, tipAmount));

    Thanks again for your time and your good work.

    Alan

  30. Chris says:

    Great tutorials, I just finished this video and have the app built upto the seek bar. I tried adding an additional listener for the tip amount so that if the user directly edits the tip amount instead of using the seek bar the final bill will adjust accordingly, however the app crashes when I change the tip amount, it’s definitely the listener I added – If I comment out the listener I added it doesn’t crash. It works if I only change the ones/hundreths place but if I change the 10/10nths place it crashes.

    /** private TextWatcher tipAmountListener = new TextWatcher(){

    @Override
    public void afterTextChanged(Editable arg0) {
    // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
    int arg3) {
    // TODO Auto-generated method stub

    }

    @Override
    public void onTextChanged(CharSequence arg0, int arg1, int arg2,
    int arg3) {
    try {

    tipAmount = Double.parseDouble(arg0.toString());
    }

    catch(NumberFormatException e){

    tipAmount = 0.0;
    }

    updateTipAndFinalBill();

    }

    }; */

  31. mikey says:

    thank you very much for this turial Derek, I really learned a great deal. Theres just this one thing Im now sure about, in the method – updateTipAndFinalBill(). why did you have to declare the data type of the variables : tipAmount and finalBill. You already declared them as doubles at the beginning of the activity.

    • Derek Banas says:

      Sorry about the confusion. I was referring to local variables in those later functions and I made a judgement call to give them the same names as the global variables. In hind sight that was a bad idea, but technically it is still ok.

  32. KitKat says:

    Great vid Derek. Can you please explain a bit more about the key value pair? Still kinda confused on where the values(i.e.tip) are stored and retrieved. Thanks

    • Derek Banas says:

      Basically we need a unique name for our keys. Normally I would use a name like com.newthinktank.total.bill. I then would create a shortened variable name that would refer to this long key. That way I get a unique name, but it will also be short and easy to use. So any place I type totalBill, com.newthinktank.total.bill would actually be there.

      In this tutorial to try and simplify the idea I used private static final String TOTAL_BILL = β€œTOTAL_BILL”

      It is just the key part of the key / value pair. We need this so that we can pass this data between activities. Does that help?

  33. GMos says:

    Hello Derek, I am therry pleased by your tutorials, everything is therry clear and you explain it all so good, that even a fool would understand.
    I was wonderring if you would make a xamarin tutorial. Xamarin is an IDE which can be used for cross-platform programming using C#. It gives people an opportunity to make apps for Android, iOS, MacOS and Windows at the same time and if this is not enougth, it gives you the whole power of .NET
    So If you will do this, you’ll probably get a VIP palace in heavan.

    • Derek Banas says:

      Thank you πŸ™‚ I’m sorry, but I don’t expect to cover xamarin anytime soon. I prefer to make tutorials using free tools so that everyone can participate. Sorry about that.

  34. kisnon says:

    i am watching you tutorals great tuts but i need some advice i was trying to make a calculator on my own its a big task for me but when i put the numbers in the graphical view and the number signs like +-=/ it gives me an error asking to use strings what can i do

  35. Yves Fay says:

    Hi great tutorials.

    Just curious, your function “onSaveInstanceState” whats its use? If I keep or remove this function from your tutorial I do not see any difference when I flip my phone or if I go to another program and return to this one… If I close the app the values are not saved with or without this function.

    Yves

  36. Rigo says:

    Hey there, I’m really trying to figure this one out, checked my code against your code but I find my error nowhere.. Whenever I open the app on my phone, and I try to input something on the Bill amount the app crashes. If I try to put something in the Tip amount, then everything works correctly. But if I go to the bill amount from the beginning it just crashes… Can you spot the possible causes with this? I could copy paste part of the code if you’d like to see it, but I’m not sure if this will help.

    Thanks for the tutorials, they’re great

    • Rigo says:

      I see other people had my same error, somewhere I just probably didn’t read those well enough. I believe exception handlers and other things will be added… Thanks!

      • Derek Banas says:

        Yes I didn’t focus on catching every possible error because I wanted to focus on the Android code specifically in the beginning. As the tutorial continues I spend a great deal of time covering exception handling and such.

    • Derek Banas says:

      The most common reason for the crashes is the use of commas in the bill. I didn’t expect people would enter commas. Sorry about that.

  37. Marc says:

    I love you’re tutorials.

    But i have a problem. When i change the tip amount. It doesnt edit the final bil. The final bil stays the same. And i cant use the seekbar cuze when i try to my app crashes.

    I saw your post above with the commas problem. So i copy all the files here above and the app stil didnt work any idea what the problem could be?

    • Derek Banas says:

      Thank you πŸ™‚ The only reason I have seen that crashes the app is the comma issue. You can continue on with the tutorial. Through out the entire tutorial this seems to be the only circumstance in which there are errors. I’m sorry that I didn’t know about the comma issue πŸ™

  38. Jay Carlton says:

    Hi,

    I really liked the tutorial. One question on this blog as it appears in Chrome, though, is how do I select only the code without the line numbers in the samples? I think there’s a trick to using a table to do this, so that the line numbers would be a column by themselves. pastebin.com does it that way I think.

    But that’s a small irritation. Keep up the great tutorials.

    -Jay

    • Derek Banas says:

      Hi Jay,

      Thank you πŸ™‚ I’m glad you like the tutorials. To copy the code without the line numbers, put your mouse on the code and in the upper right hand corner 3 icons will appear. Click on the first one named View Source and the code will appear without line numbers.

      I hope that helps
      Derek

  39. Peter Baldwin says:

    Derek,

    The tutorials are incredibly easy to understand. I am very happy to have come across them when I did and I will no doubt watch the tutorials on OOD and Java Algorithms.

    Sincerely,
    Peter Baldwin

  40. Amjad says:

    Hello Derek
    Liked your fast paced tutorials covering many things in place.

    Is there a website or something where I can find a categorized list of these tutorials?

    Regards
    Amjad

  41. Jose says:

    Hey Derek, thanks so much for creating these. They are great! Quick question – is the data that you store in those 3 constants available once the application is closed, or only when it is paused? What would be the easiest way to permanently store data like this? I’m sure you’ve addressed this in later tutorials so feel free to direct me there. Thanks again!

  42. Anand Gupta says:

    Hi Derek,

    First of all “KUDOS” for this awesome series. I could have never thought that android programming would attract my fancy but thanks to your lectures! AWESOME!

    I built the same app but without the seek bar functionality. Now when I am trying to run my code while opening the app and trying to delete the ‘0.0’ value (which is by default) in the EditText field of the Bill through the inbuilt keyboard to give it a new value , the app crashes saying “CrazyTipCalc” app is not responding.

    I compared your code (minus the seek bar functionality) and it seems to be same.

    Can you please help me with this ?ο»Ώ

  43. Damon says:

    Hi, I felt like fiddling with it a little more than you demonstrated, and tried to figure out a way to update the final bill as you change the tip amount. I got as far as adding a change listener to the tip amount, but if you completely delete everything from the tip edit view (and leave not even a 0) it crashes.

    I was thinking there may have been something wrong with my tipAmountListener:

    // Called when the tip amount is changed
    private TextWatcher tipAmountListener = new TextWatcher() {

    @Override
    public void afterTextChanged(Editable arg0) {
    // TODO Auto-generated method stub
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
    int arg3) {
    // TODO Auto-generated method stub
    }

    @Override
    public void onTextChanged(CharSequence arg0, int arg1, int arg2,
    int arg3) {

    try {
    // Change tipAmount to the new input
    tipAmount = Double.parseDouble(arg0.toString());
    }
    catch(NumberFormatException e) {
    tipAmount = 0.0;
    }

    updateTipAndFinalBill();

    }
    };

  44. Bilgin Enis says:

    omg man you are the best teacher I’ve ever had =D thanks

  45. Mooker says:

    You are the one who makes this really clear and simpler!!!

    Like these videos!

  46. Lovera says:

    Very good!
    Thanks!

  47. Terrence says:

    So I followed the tutorial completely and eclipse reported no errors with any of the code. However, at the end when I attempted to run the app the emulator would crash instantly, every single time. I also made sure to leave hardware keyboard unchecked.

  48. James says:

    Derek – i just started with Android – your tutorials are fantastic. Thanks and keep up the great work.

  49. sam says:

    Hi Derek. Very good videos on android apps. Please teach us one app which needs a server as well like WhatsApp.

  50. ali says:

    hi sir would you like to upload some tutorial about GPS Development???????

  51. alak hitam says:

    hello sir,

    i’m very interesting with your tutorial…i would like to learn simple code for creating a dictionary app…can you give me a simple source code of a dictionary app…

    thank you

  52. Arya says:

    Hi Derek,

    Thank you for such a great android tutorial you have, i’m gonna go through all your android tutorial..

    I have a problem though, when i run CrazyTipCalc as android application it always respond ‘Unfortunately, CrazyTipCalc has stopped.’

    I use the latest ADT, and based on your ADT 26 tutorial.

    These are my log cat :

    04-14 23:34:46.002: W/dalvikvm(1263): threadid=1: thread exiting with uncaught exception (group=0xa4c41648)
    04-14 23:34:46.002: E/AndroidRuntime(1263): FATAL EXCEPTION: main
    04-14 23:34:46.002: E/AndroidRuntime(1263): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.blabla.crazytipcalc/com.blabla.crazytipcalc.CrazyTipCalc}: java.lang.NullPointerException
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread.access$600(ActivityThread.java:141)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.os.Handler.dispatchMessage(Handler.java:99)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.os.Looper.loop(Looper.java:137)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread.main(ActivityThread.java:5103)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at java.lang.reflect.Method.invokeNative(Native Method)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at java.lang.reflect.Method.invoke(Method.java:525)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at dalvik.system.NativeStart.main(Native Method)
    04-14 23:34:46.002: E/AndroidRuntime(1263): Caused by: java.lang.NullPointerException
    04-14 23:34:46.002: E/AndroidRuntime(1263): at com.blabla.crazytipcalc.CrazyTipCalc.onCreate(CrazyTipCalc.java:65)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.Activity.performCreate(Activity.java:5133)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    04-14 23:34:46.002: E/AndroidRuntime(1263): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
    04-14 23:34:46.002: E/AndroidRuntime(1263): … 11 more
    04-14 23:34:46.002: W/ActivityManager(467): Force finishing activity com.blabla.crazytipcalc/.CrazyTipCalc

    • Derek Banas says:

      The key error is NullPointerException. This is triggered when an object has the value of null. Did you by any chance type a comma in the tip part. That causes an error that I wasn’t expecting.

      • Bruce McLean says:

        I am also seeing this error. It looks like the latest eclipse SDK is creating the Android App with fragments that breaks getting a handle to edit controls using findViewById() in onCreate() of the app. Fragments seem to make coding overly complicated.

  53. Paul says:

    Hello Derek,

    Best tutorials I’ve found online for Android Development.

    I just had a question on an error I’m having. When I initialize the SeekBar in CrazyTipCalc.java, the id for the seek bar cannot be found. Here’s the xml for the seekbar

    And heres the java I’m using to initialize the SeekBar.
    tipSeekBar = (SeekBar) findViewById(R.id.changeTipSeekBar);

    When I type the above code, the id changeTipSeekBar cannot be found. When I changed the id in the graphical layout, it asked me if I wanted to update all references and I said yes.
    Do you know what the problem is?

    Thanks,
    Paul

    • Paul says:

      Here’s the xml.
      SeekBar
      android:id=”@+id/changeTipSeekBar”
      android:layout_width=”match_parent”
      android:layout_height=”wrap_content”
      android:layout_alignLeft=”@+id/changeTipTextView”
      android:layout_alignRight=”@+id/finalBillEditText”
      android:layout_below=”@+id/changeTipTextView”
      android:progress=”15″

    • Paul says:

      I found that if I go in and initialize another string in strings.xml and then set that string equal to android:text=”@string/newString” in the seek bar xml then it fixes the error.

      And for the tipEditText, if I set this to .15 using the tip_edit_text String then there’s trouble initializing the tipEditText. It has the same issue where it can’t find the id for the tipEditText. If I set the tip_edit_text String to 0.0, then there’s no trouble finding the id when initializing the tipEditText

    • Derek Banas says:

      Hi Paul,

      Thank you πŸ™‚ Sorry I couldn’t get to your problem quicker. I’m glad you found a fix and posted it.

  54. taher says:

    REALLY REALLY GOOD TUTORIAL SIMPLE AND GOOD THANK YOU..
    AND A REALLY GOOD TEACHER

  55. Mengchen Lin says:

    Hi Derek!
    Thank u soooooo much for ur tutorial! It really helps soooooo much!! I got a small problem that is hard to explain and I can’t understand it.

    So I know the key-value pair concept. For example String type TOTAL_BILL is the key of double type finalBill. So when u do “putDouble(TOTAL_BILL, finalBill);” the value which key is TOTAL_BILL will be replaced by finalBill, right?

    So my question is before u actually use this key-value pair, u must in somewhere pre-set the key-value pair in ur code. But I don’t see u did that. So how could Android know that ur TOTAL_BILL is associated with finalBill, not something else?
    In other words,
    TOTAL_BILL(key) -> finalBill(value),
    CURRENT_TIP(key) -> tipAmount(value),
    BILL_WITHOUT_TIP(key) -> billBeforeTip(value),
    Those association must be setup in Java code, but I can’t find where u did this.

    I really appeciate for any idea about my question.

    • Derek Banas says:

      finalBill gets assigned the stored value here finalBill = savedInstanceState.getDouble(TOTAL_BILL)

      outState.putDouble(TOTAL_BILL, finalBill) stores the value in finalBill to the key value pair.

      I hope that helps πŸ™‚

  56. Michael says:

    Hey there, thank you so much and as soon as i am able i will buy you more than a cup of coffee! In the mean time I was wondering if you could help with some questions I have I apologize in advance because I did not read all the comments above to make sure you haven’t already answered and this may not be the best arena for you to answer my questions but i do see the value for you and others for the answers being here. With that being said here it is, im getting a warning Description Resource Path Location Type
    No grammar constraints (DTD or XML Schema) referenced in the document. AndroidManifest.xml /freecreditapp/bin line 27 XML Problem. i have been playing around with some things and applying the tip app in somewhat of a different fashion as im sure you have noticed and I will happily explain further if we could google hangout sometime on air or off. then next would be when i go to upload a second version to the play store im getting apk errors and it fails not letting me upload a new version so i chanced a few things and attempted to upload a new application this didnt work either I know im forgetting something simple but having trouble figuring out what thank you so much for your time and consideration

    • Derek Banas says:

      You are very welcome πŸ™‚ I’m happy if I can help.

      To get rid of that error make sure you have this at the top of your manifast file < ?xml version="1.0" encoding="utf-8"?>

      If that doesn’t get rid of it, Right click on the error and delete it. It probably won’t come back.

      To update an app you upload a new apk file but make sure you have incremented the android:versionCode and android:versionName attributes in the element of the manifest file.

      I hope that helps πŸ™‚

  57. Karan says:

    Hello Derek,

    Thank you for your tutorials. They are great.

    My program works perfect except the listener part. I am getting errors in my logcat due to it and application gets crashed. When i comment out the
    tipSeekBar = (SeekBar) findViewById(R.id.changeTipseekBar);
    and
    billbeforetipET.addTextChangedListener(billBeforeTipListner);
    lines my program works fine. Else, it doesn’t. I have typed in exactly the same code you have used. But still the listener part is not working. In the previous comments you have mentioned that we need to include exceptions for the program to work correctly. As i am a beginner i couldn’t solve this error. I went through your successive tutorials but you haven’t mentioned about the exceptions. Could you kindly help me out with this by either providing me codes or links to get this resolved.

    Thanks in advance.

  58. Narain says:

    Great tutorials Derek. I usually dont write comments, but your tutorials are way too good!
    Thank you so much, I am glad i found your channel/website. I will be waiting for more of your videos!

  59. Edgar says:

    Thank you for the awsome tutorials.
    my main class always says extends ActionBarActivity while yours just says extends Activity.
    That is the only difference i found between mine and your code and once i changed it to yours it worked, and before the app would just crash. Do you know why? and how can i make it so it automatically just says extends Activity like yours.
    thanks

  60. Deep Ak says:

    Hi derek,

    First of all, thank you SO much for these tutorials. I’m a beginner and i wanna know that if i follow all your tutorials, do i need to read and learn more from developer.android.com??
    or are your tutorials enough?

    And and i ran your code, without the seek bar. Exactly the same, infact i even copy pasted your code to check if i did a mistake, even then when i run the app, even if i try to remove the 0.0 from bill, the app crashes. Any idea why?
    Thank you so much again!

    • Derek Banas says:

      Hi,

      I cover a lot while making one app after another in this tutorial series. My newest Android tutorial will finish up everything I missed here like interface design and such.

      What error do you see in the logcat panel for this app. The most common occurs if a comma is entered in the amount.

  61. ThaNoob says:

    I really appreciate the android tutorials! Except for when using this one i keep having a problem with the seekbar. I always get a NumberFormatException error. He can’t parse 0,2 for example to a double. He can only do that for 0.2 and it seems that my seekbar outputs his data with “,” any ideas how to solve this?

    Thanks!

  62. David says:

    Hi,

    Just want to ask on how to restore the R.java file? I’ve already encountered this 3 times and its frustrating to recreate everything again. Hope you could address this concern.

    Thanks.
    David

Trackbacks/Pingbacks

  1. Android Development Tutorial 3 - appgong - […] Android Development Tutorial 3 […]

Leave a Reply

Your email address will not be published.

Google+