Android Development 20

Android Development 20In this part of my Android Development Tutorial I will continue talking about Fragments. If you missed parts 18 and 19 watch them first or you will be confused.

We will also cover how to use CheckBoxs and OnCheckChangedListener. Will explore how to generate unique IDs for all our contacts using UUID. Will create a Singleton that will hold all our contacts in an ArrayList and more. All of the code is available below.

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

Code From the Video

Contact.java

package com.newthinktank.censusapp;

import java.util.UUID;

import android.util.Log;

public class Contact {
	
	private String name;
	private String phoneNumber;
	private String streetAddress;
	private String city;
	
	// NEW Add a Unique ID number for each person
	
	private UUID idNumber;
	private boolean contacted = false;
	
	public Contact(){
		
		// Generates a type 4 pseudo randomly generated UUID
		// Wiki : 1 billion UUIDs every second for the next 
		// 100 years, the probability of creating just one 
		// duplicate would be about 50%
		
		idNumber = UUID.randomUUID();
		
	}
	
	// END OF NEW

	public String getName() {
		return name;
	}

	public void setName(String name) {
		
		Log.e("CENSUS", "NAME CHANGED TO " + name);
		
		this.name = name;
	}

	public String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		
		Log.e("CENSUS", "PHONE CHANGED TO " + phoneNumber);
		
		this.phoneNumber = phoneNumber;
	}


	public String getStreetAddress() {
		return streetAddress;
	}

	public void setStreetAddress(String streetAddress) {
		
		Log.e("CENSUS", "STREET CHANGED TO " + streetAddress);
		
		this.streetAddress = streetAddress;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		
		Log.e("CENSUS", "CITY CHANGED TO " + city);
		
		this.city = city;
	}
	
	// NEW
	
	public boolean getContacted() {
		return contacted;
	}

	public void setContacted(boolean contacted) {
		
		Log.e("CENSUS", "CONTACTED CHANGED TO " + contacted);
		
		this.contacted = contacted;
	}

	public UUID getIdNumber() {
		return idNumber;
	}

	public void setIdNumber(UUID idNumber) {
		this.idNumber = idNumber;
	}
	
	// END OF NEW

	
}

AllContacts.java

package com.newthinktank.censusapp;

import java.util.ArrayList;
import java.util.UUID;

import android.content.Context;

public class AllContacts {

	// This class will only have one instance that will
	// contain an arraylist with all contacts in it.
	// Singleton

	private static AllContacts allContacts;

	// By creating a Context you gain access to the 
	// current state of the complete application.
	// With it you can get information about all the Activitys
	// in the app among other things.

	// By accessing the Context you control every part of
	// the application along with everything that app
	// is allowed to access on the device.

	private Context applicationContext;

	// This ArrayList will hold all the Contacts

	private ArrayList<Contact> contactList;

	private AllContacts(Context applicationContext){

		this.applicationContext = applicationContext;

		contactList = new ArrayList<Contact>();

		// TODO
		// This goes away when app is ready

		Contact paulSmith = new Contact();
		paulSmith.setName("Paul Smith");
		paulSmith.setStreetAddress("123 Main St");
		paulSmith.setContacted(true);
		contactList.add(paulSmith);
		
		Contact sallySmith = new Contact();
		sallySmith.setName("Sally Smith");
		sallySmith.setStreetAddress("125 Main St");
		sallySmith.setContacted(false);
		contactList.add(sallySmith);
		
		Contact markSmith = new Contact();
		markSmith.setName("Mark Smith");
		markSmith.setStreetAddress("127 Main St");
		markSmith.setContacted(false);
		contactList.add(markSmith);

	}

	// Checks if an instance of allContacts exists. If it does
	// the one instance is returned. Otherwise the instance is
	// created.

	public static AllContacts get(Context context){

		if(allContacts == null){

			// getApplicationContext returns the global Application object
			// This Context is global to every part of the application

			allContacts = new AllContacts(context.getApplicationContext());

		}

		return allContacts;

	}

	public ArrayList<Contact> getContactList(){

		return contactList;

	}

	public Contact getContact(UUID id){

		for(Contact theContact : contactList){

			if(theContact.getIdNumber().equals(id)){

				return theContact;

			}

		}

		return null;

	}

}

fragment_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/TableLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/app_outer_margin" >

    <EditText
        android:id="@+id/contactNameEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/component_bottom_margin"
        android:ems="10"
        android:hint="@string/contact_name_hint"
        android:inputType="textCapWords|textPersonName" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/contactStreetEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/component_bottom_margin"
        android:ems="10"
        android:hint="@string/contact_street_hint"
        android:inputType="textPostalAddress" />

    <EditText
        android:id="@+id/contactCityEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/component_bottom_margin"
        android:ems="10"
        android:hint="@string/contact_city_hint"
        android:inputType="textCapWords" />

    <EditText
        android:id="@+id/contactPhoneEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/component_bottom_margin"
        android:ems="10"
        android:hint="@string/contact_phone_hint"
        android:inputType="phone" />

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <CheckBox
            android:id="@+id/contactedCheckBox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contact_contacted_checkbox" />

    </TableRow>

</TableLayout>
<!--
A Fragment is sort of a mini Activity which you can add
or remove from another Activity.
 
You can use them to create reusable pieces you can add
to your interface.

They are often used so that depending on your screen size
you can add more or less fragments 
-->

ContactFragment.java

package com.newthinktank.censusapp;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;

public class ContactFragment extends Fragment {

	private Contact contact;
	private EditText contactNameEditText;

	private EditText contactStreetEditText;
	private EditText contactCityEditText;
	private EditText contactPhoneEditText;
	
	// NEW 
	
	private CheckBox contactedCheckBox;
	
	// END OF NEW

	// Generate this with Right Click - Source - Override/Implement methods
	// This method is called when the Fragment is called for.
	// We initialize everything here.

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		contact = new Contact();
	}

	// Used to inflate the Fragment, or show it on the screen

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		// Pass in the layout to inflate, the views parent and whether
		// to add the inflated view to the parent.
		// We mark this false because the Activity will add the view.

		View theView = inflater.inflate(R.layout.fragment_contact, container, false);

		// Get a reference to the EditText

		contactNameEditText = (EditText) theView.findViewById(R.id.contactNameEditText);

		// If text in the EditText box is edited it will change the
		// name.
		
		contactStreetEditText = (EditText) theView.findViewById(R.id.contactStreetEditText);
		contactCityEditText = (EditText) theView.findViewById(R.id.contactCityEditText);
		contactPhoneEditText = (EditText) theView.findViewById(R.id.contactPhoneEditText);
		
		// All the EditText components will use just one TextWatcher
		// which auto updates Contact.java

		TextWatcher editTextWatcher = new TextWatcher() {

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

				if (contactNameEditText.hasFocus() == true){

					contact.setName(arg0.toString());

				} else if (contactStreetEditText.hasFocus() == true){
					
					contact.setStreetAddress(arg0.toString());
					
				} else if (contactCityEditText.hasFocus() == true){
					
					contact.setCity(arg0.toString());
					
				} else if (contactPhoneEditText.hasFocus() == true){
					
					contact.setPhoneNumber(arg0.toString());
					
				}

			}

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

			}

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

			}
		};

		
		contactStreetEditText.addTextChangedListener(editTextWatcher);
		contactCityEditText.addTextChangedListener(editTextWatcher);
		contactPhoneEditText.addTextChangedListener(editTextWatcher);

		contactNameEditText.addTextChangedListener(editTextWatcher);
		
		// NEW 
		// Create CheckBox Listener
		
		contactedCheckBox = (CheckBox) theView.findViewById(R.id.contactedCheckBox);
		
		contactedCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){

			@Override
			public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
				
				contact.setContacted(true);
				
			}
			
		});
		
		// END OF NEW


		// Pass in the layout to inflate, the views parent and whether
		// to add the inflated view to the parent.
		// We mark this false because the Activity will add the view.

		return theView;

	}

}

CensusApp.java

package com.newthinktank.censusapp;

//We will use the android.support.v4.app.Fragment
//support library so our app runs on older versions
//of Android

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

//Change Activity to FragmentActivity

// The FragmentManager ads Fragments to an Activity's view

public class CensusApp extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_census_app);
		
		FragmentManager fragManager = getSupportFragmentManager();
		
		// Check if the FragmentManager knows about the Fragment 
		// id we refer to
		
		Fragment theFragment = fragManager.findFragmentById(R.id.fragmentContainer);
		
		// Check if the Fragment was found
		
		if(theFragment == null){
			
			// If the Fragment wasn't found then we must create it
			
			theFragment = new ContactFragment();
			
			// Creates and commits the Fragment transaction
			// Fragment transactions add, attach, detach, replace
			// and remove Fragments.
			
			// add() gets the location to place the Fragment into and
			// the Fragment itself.
			
			fragManager.beginTransaction()
				.add(R.id.fragmentContainer, theFragment)
				.commit();
			
		}
	}

	
}

4 Responses to “Android Development 20”

  1. John Paul says:

    Hi Derek,

    won’t you store all of the contacts into database? Just the way you did it in ContactApp.

    Thanks

  2. gary says:

    Derek, thanks for the solid effort in all video tutorial.
    I have learned a great deal of android programming.
    Would you be discussing on any interface controls like eye gazing ?
    Would be interested in location sensing application too.
    once again thanks for your great work!

    • Derek Banas says:

      Hi Gary, Thank you I’m very happy that you’re enjoying them. I have no idea where this tutorial will go and it is possible I could go down the road of covering location sensing, but I have never done that stuff. Thank you for the request 🙂

Leave a Reply

Your email address will not be published.

Google+