Android Development Tutorial 4

Android Development Tutorial 4Welcome to part 4 of my Android Development Tutorial. In the last part, I showed you how to put together an Android User Interface. This time I will add to that app in a big way!

Over the course of this tutorial and the next I will cover RadioButtons, RadioGroups, CheckBoxes, DropDows (Spinners), Buttons, Chronometers, ChangeListeners, ItemSelectedListeners, onClickListeners and much more. All of the code below should help you along.

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

Code From the Video

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" >

    <requestFocus />

    <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" />

    <!-- NEW STUFF -->

    <TextView
        android:id="@+id/IntroTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/changeTipSeekBar"
        android:layout_below="@+id/changeTipSeekBar"
        android:layout_marginTop="16dp"
        android:text="@string/intro_text_view" />

    <CheckBox
        android:id="@+id/friendlyCheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/IntroTextView"
        android:layout_below="@+id/IntroTextView"
        android:text="@string/intro_friendly_text_view" />

    <CheckBox
        android:id="@+id/specialsCheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/friendlyCheckBox"
        android:layout_alignBottom="@+id/friendlyCheckBox"
        android:layout_alignRight="@+id/finalBillTextView"
        android:layout_marginRight="26dp"
        android:text="@string/intro_specials_text_view" />

    <CheckBox
        android:id="@+id/opinionCheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/specialsCheckBox"
        android:layout_alignBottom="@+id/specialsCheckBox"
        android:layout_toRightOf="@+id/specialsCheckBox"
        android:text="@string/intro_opinion_text_view" />

<RadioGroup
    android:id="@+id/availableRadioGroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/IntroTextView"
    android:layout_alignRight="@+id/finalBillTextView"
    android:layout_below="@+id/availabilityTextView"
    android:layout_marginTop="15dp"
    android:orientation="horizontal" >

    <RadioButton
        android:id="@+id/availableBadRadio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="@string/available_bad_radiobutton" />

    <RadioButton
        android:id="@+id/availableOKRadio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/available_ok_radiobutton" />

    <RadioButton
        android:id="@+id/availableGoodRadio"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/available_good_radiobutton" />
</RadioGroup>

<TextView
    android:id="@+id/availabilityTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/availableRadioGroup"
    android:layout_below="@+id/friendlyCheckBox"
    android:layout_marginTop="12dp"
    android:text="@string/available_text_view" />

<Spinner
    android:id="@+id/problemsSpinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/availableRadioGroup"
    android:layout_alignRight="@+id/opinionCheckBox"
    android:layout_below="@+id/availableRadioGroup"
    android:layout_marginTop="11dp"
    android:entries="@array/problem_solving" />

<TextView
    android:id="@+id/timeWaitingTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/problemsSpinner"
    android:layout_below="@+id/problemsSpinner"
    android:layout_marginTop="12dp"
    android:text="@string/time_waiting_text_view" />

<Chronometer
    android:id="@+id/timeWaitingChronometer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/timeWaitingTextView"
    android:layout_toRightOf="@+id/tipTextView"
    android:text="Chronometer" />

<Button
    android:id="@+id/startChronometerButton"
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/timeWaitingTextView"
    android:layout_below="@+id/timeWaitingChronometer"
    android:layout_marginTop="16dp"
    android:text="@string/start_chronometer_button" />

<Button
    android:id="@+id/pauseChronometerButton"
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/startChronometerButton"
    android:layout_toRightOf="@+id/availabilityTextView"
    android:text="@string/pause_chronometer_button" />

<Button
    android:id="@+id/resetChronometerButton"
    style="?android:attr/buttonStyleSmall"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/pauseChronometerButton"
    android:layout_toRightOf="@+id/changeTipSeekBar"
    android:text="@string/reset_chronometer_button" />

<!-- END OF NEW STUFF -->

</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>
    
    <string name="change_tip_text_view">Change Tip</string>
    
    <!-- END OF FIRST PART -->
    
    <string name="intro_text_view">Introduction</string>
    
    <string name="intro_friendly_text_view">Friendly</string>
    <string name="intro_specials_text_view">Specials</string>
    <string name="intro_opinion_text_view">Opinion</string>
    
    <string name="available_text_view">Availability</string>
    <string name="available_bad_radiobutton">Bad</string>
    <string name="available_ok_radiobutton">OK</string>
    <string name="available_good_radiobutton">Good</string>
    
    <string name="time_waiting_text_view">Time Waiting for Service</string>
    <string name="start_chronometer_button">Start</string>
    <string name="pause_chronometer_button">Pause</string>
    <string name="reset_chronometer_button">Reset</string>
    
    <!-- Spinner Options -->
    
	<string-array name="problem_solving">
	    <item>Problem Solving</item>
        <item>Bad</item>
        <item>OK</item>
        <item>Good</item>
    </string-array>

</resources>

CrazyTipCalc.java

package com.newthinktank.crazytipcalc;

import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.TextView;

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;
	
	// NEW PART ---------------
	
	// Sum of all radio buttons and check boxes
	
	private int[] checklistValues = new int[12]; 
	
	// Declare CheckBoxes
	
	CheckBox friendlyCheckBox;
	CheckBox specialsCheckBox;
	CheckBox opinionCheckBox;
	
	// Declare RadioButtons
	
	RadioGroup availableRadioGroup;
	RadioButton availableBadRadio;
	RadioButton availableOKRadio;
	RadioButton availableGoodRadio;
	
	// Declare Spinner (Drop Down Box)
	
	Spinner problemsSpinner;
	
	// Declare Buttons
	
	Button startChronometerButton;
	Button pauseChronometerButton;
	Button resetChronometerButton;
	
	// Declare Chronometer
	
	Chronometer timeWaitingChronometer;
	
	// The number of seconds you spent 
	// waiting for the waitress
	
	long secondsYouWaited = 0;
	
	// TextView for the chronometer
	
	TextView timeWaitingTextView;
	
	
	// END OF NEW PART ---------------
	
	@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
		
		// 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);
		
		// NEW PART ---------------
		
		// Initialize CheckBoxs
		
		friendlyCheckBox = (CheckBox) findViewById(R.id.friendlyCheckBox);
		specialsCheckBox = (CheckBox) findViewById(R.id.specialsCheckBox);
		opinionCheckBox = (CheckBox) findViewById(R.id.opinionCheckBox);
		
		setUpIntroCheckBoxes(); // Add change listeners to check boxes
		
		// Initialize RadioButtons
		
		availableBadRadio = (RadioButton) findViewById(R.id.availableBadRadio);
		availableOKRadio = (RadioButton) findViewById(R.id.availableOKRadio);
		availableGoodRadio = (RadioButton) findViewById(R.id.availableGoodRadio);
		
		// Initialize RadioGroups
		
		availableRadioGroup = (RadioGroup) findViewById(R.id.availableRadioGroup);
		
		// Add ChangeListener To Radio buttons
		
		addChangeListenerToRadios();
		
		// Initialize the Spinner
		
		problemsSpinner = (Spinner) findViewById(R.id.problemsSpinner);
		
		problemsSpinner.setPrompt("Problem Solving");
		
		// Add ItemSelectedListener To Spinner
		
		addItemSelectedListenerToSpinner();
		
		// Initialize Buttons
		
		startChronometerButton = (Button) findViewById(R.id.startChronometerButton);
		pauseChronometerButton = (Button) findViewById(R.id.pauseChronometerButton);
		resetChronometerButton = (Button) findViewById(R.id.resetChronometerButton);
		
		// Add setOnClickListeners for buttons
		
		setButtonOnClickListeners();
		
		// Initialize Chronometer
		
		timeWaitingChronometer = (Chronometer) findViewById(R.id.timeWaitingChronometer);
		
		// TextView for Chronometer
		
		timeWaitingTextView = (TextView) findViewById(R.id.timeWaitingTextView);
		
		// END OF NEW PART ---------------
	}
	
	// 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.
	
	@Override
	protected void onSaveInstanceState(Bundle outState){
		
		super.onSaveInstanceState(outState);
		
		outState.putDouble(TOTAL_BILL, finalBill);
		outState.putDouble(CURRENT_TIP, tipAmount);
		outState.putDouble(BILL_WITHOUT_TIP, billBeforeTip);
		
	}
	
	// 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
			
		}
		
	};

@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;
	}

}

44 Responses to “Android Development Tutorial 4”

  1. Hi Derek,

    My dad tried to copy/paste the activity xml file but the graphical layout was screwed up.

  2. Colten says:

    Hey Derek, if you can, could you please find a way to get rid of the line of numbers on the side of each line, or tell me an easy way to get rid of them if I copy them into eclipse. I have tried find and replace but that messes up the code and it is very difficult to fix it.

  3. Gennady says:

    Absolutely fabulous tutorial.
    I imagine how hard Derek works to create a comprehensive lecture and not being drown into details that always obscure the real goal of any tutorial.
    For example the case with declaring a static final variable then assigning value to it later in the code seems against the java logic and it begs to be explained.
    However it would be deviation from the target – to learn how to program Android apps.
    Tech details can be clarified by docs.
    I would recommend to anybody do not copy/paste but write the code manually even change the names of variables to accelerate the learning process.

    • Derek Banas says:

      Thank you very much for the kind message 🙂 I’m happy that you are enjoying them. Many more videos are coming

    • onetwopi says:

      I agree – these tutorials are wonderful. I have been doing what this comment suggests and manually building the apps, changing the variable names to suit my coding style, and looking back to Derek’s work as reference. I think it’s an amazing way to learn!
      I also find that adding a few new features forces me to make mistakes and then do research on how to fix my mistakes. On my version of this app, I added a “tip amount” that displays (and allows you to edit) the amount of the tip to write in on your credit card. Making these types of simple changes helps me to understand what I’m actually doing rather than just copying the code.
      Thanks again Derek for the stellar work!

  4. Weecow says:

    Derek, you are so awesome. The tutorials you make are like so good. You communicate, explain everything meanwhile creating an ENTIRE app. Unlike other you explain everything to create an actual app others explain Ie only listeners or other stuff. But you learn us how to use it in an app.

    I really appreciate your effort in this tutorials, I look over them, create a app and get smarter. I also have fun since I can see my result! Thank you so much. Keep on going!

    • Derek Banas says:

      Thank you for taking the time to tell me that you liked the videos 🙂 I plan on making many more Android tutorials. The only problem with them is that I have to try and make good apps that are also easy to understand. I just gave up on another today, because I couldn’t figure out how to simplify it. I promise I’ll make many more.

      Derek

  5. Anonymous says:

    Thanks for the tutorial, I have a problem, when I create the start, pause and reset button the text gets cut off how do I correct it and how do I change the font size

    • Derek Banas says:

      As the tutorial continues I cover all of that. The font size is changed in the xml file with something like this android:ems=”10″

      Keep going and you’ll get it. I’m covering everything in extreme detail.

  6. Sawsan says:

    can you help me..
    I do not know why in the graphical layout I don’t have the emulator for that I can not add the buttons and other things like you?!!

  7. Pamela says:

    I am just starting out though I have had many years in an education setting with Java. Eclipse is new to me… as is android anything. We always used a much simpler compiler so I just never had the opportunity to learn Eclipse. My issue is that in tutorial 3 for both bill and tip EditText I was unable to add in the Text or InputType via the properties box on the GUI. Those rows were grayed out for me and I was forced to add them in via code. Is this normal or was I doing something wrong?

    Loving your tutorials! Just amazing and so helpful. Exactly what I was looking for. Thanks so much for your time and effort!

    Pam

    • Derek Banas says:

      Hi Pam,

      Developing for Android is most definitely different from straight Java, but once you get used to it it becomes second nature.

      I learned by digging through the API a few years ago. By doing that I’d say it took me about 2 months to get comfortable with writing Android apps. I hope these videos speed up that process.

      As per your error, what version of Eclipse are you using and what OS are you using? Eclipse Kepler can be a bit buggy unless you use Java 1.6 on some computers. I show how to fix that problem in my latest tutorial.

      I hope that helps
      Derek

      • Pamela says:

        Derek,

        Thank you for your response. I am running win 7 64bit. Java is 7u45 and as for Eclipse I can only assume I am using Kepler. I just downloaded and started this Nov 10 and downloaded the latest versions offered. Looking at that tutorial you linked it looks as though I have to step back to 6u45 for the Java? Just did that. Will let you know if I have any more issues.

        I have to say that you have made it much easier to really get into the development. I have found myself working ahead slightly and then watching your vid to catch up and check myself. You putting out the files makes it much easier as well as I do not have to type it all out. The goal is to eventually make something (sneaky) for my son to get him to play and learn at the same time. We homeschool and he is so hyper that some days I can barely get him to stop spinning in circles much less do homework! (Will give you the shirt off his back as he chases a butterfly into the highway… =)) Your tutorials have really helped me feel that this is a possibility.

        Thank you so much.
        Pam

        • Derek Banas says:

          Wow, I could never home school. I have no idea how you do it. My 4 and 1 year old are completely crazy. I’m very impressed by your skill as well as by your devotion 🙂

          I hope to eventually start creating videos and apps that work together to teach Math, Science, etc. They will all be free just like now. I have been moving towards that goal for a while. I hope it will provide the tools needed to give a free education to all. It is a very exciting goal for me.

          If you need any more help setting up Eclipse tell me. I think if you downgrade Java though that you’ll be ok.

          Derek

          • Pamela says:

            Derek,

            I worked for about 5 years at the community college I received my associates. I wore a few different, but related, hats. TA (teaching assistant), tutor, and mentor. Subjects taught were computer science / math / language arts and college admission. I also worked as a tutor for the university I was attending for my (unfinished) BS – Computer Science. I had students come into the tutoring center (young* enough to be a grandparent of mine and teenagers having JUST graduated high school) that had difficulty adding and subtracting. Yes… these high schoolers couldn’t add yet had just graduated high school…. gotta love Texas education system. =( Wonder why I have chosen to home school???

            This just tore me up. It is discouraging to see all the difficulty these wonderful people had with (what I considered) simple math or writing. I decided then and there that one day I would come up with some program that was interactive, simple, and fun. One that would work for ages 3-103. Whatever it took, to develop a way for people to get the help they need for math. It is a dream of mine. I have searched high and low for the platform to do it… and well… the time.

            My kids are 9 and 11. After homeschooling them and everyday life it is difficult to find time. I can get done in one night what would take me a full week working with the code. If you are able to accomplish this before I can then heck yeah! I will scream it loud and often to these poor students. Anything to help them. I have seen some awesome, amazing people completely give up on their dreams because the concept of fractions stood in their way. I don’t have a ton of experience but I am a quick study and am a hard worker. If there is anything I can do to help YOU get to helping people education wise more quickly… just drop me an email and I will do what I can.

            Pam

            • Derek Banas says:

              Thank you very much for sharing. Like you I’m pretty disgusted by the education system. I don’t blame teachers, but instead I blame the general system. The schools near my house are terrible as well.

              I’m not big on trying to solve problems through political channels so instead I do hope to make a ton of educational apps. I will probably work the rest of my life trying to make them better and better. I don’t think they’ll ever be perfect, but I think they’ll help some people and that is good enough for me.

              Hopefully along the way I can make this whole programming thing easier as well. That way more people will be able to join in. I haven’t by any means perfected this area of teaching yet, but I’m getting better each time. I plan on covering Android for quite some time. I will also eventually start over from the beginning and improve on this tutorial.

              Thank you for offering to help. It may sound strange, but just knowing that there are people out there that enjoy these videos is enough for me. Always feel free to tell me where I can improve. I need some negative comments as well 🙂

              Thanks
              Derek

              • Martin says:

                As you said, you wanted some negative comments to improve yourself. So there is some: You are speaking so quick and sometimes it is a little bit obscure mostly for no native speakers as me. It is hard to pay attantion to understanding speech and the content at the same time. But this is very subjective i think.

  8. Martin says:

    Hi Derek, thank you very much for your videos. I have been so bored from webdeveloping and stuffs around web and this is a big opportunity for me to learn something new. The way you are teaching is more powerfull then reading book about android developing which i have. Realy good job.

    Sorry for my english, im not native speaker.

    • Derek Banas says:

      Hi Martin,

      Thank you I’m doing my best to teach Android development in a new way. I’m enjoying these videos so much that I plan to make them for many more months.

      Your English is very good as well. Thanks for taking the time to say hi 🙂

  9. kuldeep says:

    HI Derek,

    I have a one question. timeWaitingTextView is not being utilized or used anywhere in .java file. However, is that required to initialize it as we have done in statement
    timeWaitingTextView = (TextView)findViewById(R.id.timeWaitingTextView);

    Thanks in advance. I am really learning fast just because of your elaborative tutorials 🙂

  10. Daniel Kuznetsov says:

    Derek you can’t believe how much I am thankfull for this tutorials you are the only one that actually explain everything and show your own apps
    Basiclly I want to say a giant thanks and I am going to publish my own app with all those stuff I learnt from this “course”

    • Derek Banas says:

      Thank you 🙂 I’m very happy that you are enjoying them. I’ll keep making Android apps until anyone that wants to can learn to make most anything. They are great fun to make and quite profitable.

  11. Mic says:

    Hi derek i really love your tutorials. just wanted to find out if there is any particular tutorials showing how an app communicates over the internet. yeah i know it sounds strange am actually working on a final year project please help

  12. Nemanja says:

    I just want to say that this is by far the best Android tutorial series I’ve seen anywhere.
    You sir are really knowledgable and I appreciate very much you are taking the time to help the rest of us learn.
    Schools really became a business nowadays and don’t provide that good of an education (at least from my perspective as a student at UM).
    I’m hoping to start one of these educational websites myself eventually for my own country/language.
    Once again, thank you and big thumbs up 🙂

    • Derek Banas says:

      Thank you for the very nice compliment 🙂 I always treated my website as if it was a type of trade school. Especially in the last 2 years I aimed to teach people exactly what they need to know to go off on their own. I wish I could better simulate in person teaching and I think I’ll get there some day.

  13. Gidon says:

    Amazing tutorials!!!
    Great flow…professional and friendly.
    Your tone of voice makes me feel calm, as if i can learn everything- no panic.
    thanks man.

  14. Omega says:

    Hello Derek,

    your tutorials are very good and I understood a lot of things so far. And I really appreciate for that.

    But I have a problem with Java. If you compare it to C or similar programming languages, Java is so weird.
    There are so many identifiers and I didn’t figured out yet how I have to use them and so it is very complicated to follow all of your code.
    Do you know a good Java tutorial where I can learn it?

    Thank you in advance 😉

  15. Goran Veletic says:

    Good tutorial, you have bug in this code though
    when tip is updated with slidebar and than when you go back and enter new tip in text editor it does not work

    here is my code with a fix for it:

    package com.goxoft.crazytipcalc;

    import android.support.v7.app.ActionBarActivity;
    import android.support.v7.app.ActionBar;
    import android.support.v4.app.Fragment;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.EditText;
    import android.widget.SeekBar;
    import android.widget.SeekBar.OnSeekBarChangeListener;
    import android.os.Build;

    public class CrazyTipCalc extends Activity {

    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;
    private double tipAmount;
    private double finalBill;

    EditText billBeforeTipET;
    EditText tipAmountET;
    EditText finalBillET;

    SeekBar tipSeekBar;

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

    if(savedInstanceState==null){
    billBeforeTip = 0.0;
    tipAmount = 0.15;
    finalBill = 0.0;
    } else {
    billBeforeTip = savedInstanceState.getDouble(BILL_WITHOUT_TIP);
    tipAmount = savedInstanceState.getDouble(CURRENT_TIP);
    finalBill = savedInstanceState.getDouble(TOTAL_BILL);
    }

    billBeforeTipET = (EditText) findViewById(R.id.billEditText);
    tipAmountET = (EditText) findViewById(R.id.tipEditText);
    finalBillET = (EditText) findViewById(R.id.finalBillEditText);

    tipSeekBar = (SeekBar) findViewById(R.id.changeTipSeekBar);

    billBeforeTipET.addTextChangedListener(billBeforeTipListener);

    /* tipEditText not updating bug
    * ********************************************************************
    */

    // this line here calls tipEditTextListener which checks if tip edit thext bar have changed
    tipAmountET.addTextChangedListener(tipEditTextListener);
    /***********************************************************************/

    tipSeekBar.setOnSeekBarChangeListener(tipSeekBarListener);

    }

    private TextWatcher billBeforeTipListener = new TextWatcher(){

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before,
    int count) {

    try {
    billBeforeTip = Double.parseDouble(s.toString());
    } catch (NumberFormatException e){
    billBeforeTip = 0.0;
    }

    updateTipAndFinalBill();
    }

    @Override
    public void afterTextChanged(Editable s) {
    }
    };

    /* tipEditText not updating bug
    * ********************************************************************
    */
    private TextWatcher tipEditTextListener = new TextWatcher(){

    @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) {

    // This guy updates a tip anytime it have changed */
    try {
    tipAmount = Double.parseDouble(s.toString());
    } catch (NumberFormatException e) {
    tipAmount = 2.0;
    }

    // Updates seek bar after tipEditText have been changed
    tipSeekBar.setProgress((int) (tipAmount*100));

    // call to our update method
    updateTipAndFinalBill();
    }

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

    }

    };

    private OnSeekBarChangeListener tipSeekBarListener = new OnSeekBarChangeListener(){

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
    boolean fromUser) {
    tipAmount = tipSeekBar.getProgress()*0.01;
    tipAmountET.setText(String.format(“%.2f”, tipAmount));

    updateTipAndFinalBill();
    }

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

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub

    }
    };

    private void updateTipAndFinalBill() {
    double tipAmmount = Double.parseDouble(tipAmountET.getText().toString());

    double finalBill = billBeforeTip + (billBeforeTip*tipAmmount);

    finalBillET.setText(String.format(“%.2f”, finalBill));
    }

    protected void onSaveInstanceState(Bundle outState){

    super.onSaveInstanceState(outState);

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

    }

Leave a Reply

Your email address will not be published.

Google+