Saturday, February 6, 2010

Tutorial: Listview

Android "To Do" Application Tutorial

This is Part 1 in a series of tutorials. Each will build on the previous covering concepts which should be transferable to many applications. In order to cover many typical coding requirements, we are going to create a simple "To Do" application. Each tutorial part will conclude with a functioning application, albeit incomplete. In these series of tutorials we will cover adding, editing, and deleting items in a ListView. Here is what this series of tutorials will cover:
  • Start a new Android application.
  • Add, edit, and delete items in a ListView.
  • Edit "To Do" form.
  • We will start with a simple "one line" ListView. Then we will upgrade it so we can customize and dress up each row.
  • We will add some graphics to the ListView.
  • To improve performance and encapsulation we will move To Do items into a separate class that can  cache the TextView and ImageView widgets.
  • Create a landscape layout.
  • Create a database and table to store our tasks.
 Part 1: Create a new project



1. Create new project

     
2. Select "Android Application". Select "Next"

3. Set new project properties the click "Finish"
  • Project Name: To Do Tutorial
  • Build Target: Select Android 2.1 (you may select any build target, but this tutorial is 2.1)
  • Application Name: To Do Tutorial
  • Package Name: org.androidcodemonkey.todo
  • Create Activity: DetailForm
  • Min SDK: 7 (leave the default)

4. Open layout "main.xml"

5. Right click on "Hello World, DetailForm!" and select "Remove"
6. Now we are going to modify our layout. You can drag controls onto the layout in "Layout" mode, but I prefer to edit the XML directly. It provides me greater control. I am going to add the following controls in the XML mode (add the code from lines 2-26):
  • TableLayout
    • TableRow
      • TextView
      • EditText
    • TableRow
      • TextView
      • RadioGroup
        • RadioButton
        • RadioButton
        • RadioButton
    • TableRow
      • TextView
      • Button

 
  
   
   
  
  
   
   
     
     
     
   
  
  
   
   
 



  
   
  



7. Change to LayoutView and it should look like this. Feel free to change settings on the display to see how it affects the controls.
 
8. Now we need an "entity" class. To keep our class files organized, let's create package.
  • In the Package Explorer > Right click on "src" > "New" > "Package"

  • Name: "org.androidcodemonkey.entities" Then click "Finish"
9. Let's add the a class for our "Task"
  • In the Package Explorer > Right click on "org.androidcodemonkey.entities" > "New" > "class"
  • Name: TaskBE. Click "Finish"
10. Create the following properties and methods.
  • Create string "item"
  • Create string "priority"
  • Create getItem() 
  • Create setItem()
  • Create getPriority()
  • Create setPriority()
  • Implement "toString()". 
Your TaskBE class should look like this:

package org.androidcodemonkey.entities;

public class TaskBE {
 private String item="";
 private String priority="";
 
 public String getItem() {
  return(item);
 }
 
 public void setItem(String value) {
  this.item = value;
 }
 public String getPriority() {
  return(priority);
 }
 public void setType(String value) {
  this.priority = value;
 }
 public String toString() {
  return(getItem());
 }
}
11. Open DetailForm.java. We are going to add an "onSave" method that will be called when the save button is pressed. When the save button is pressed we are going to retrieve the information from the View.
  • Import reference to entities (line #3)
  • Create a new TaskBE object. (line #20)
  • Create an EditText to retrieve the item entered into the view (line #21)
  • Set the item property of the Task (line #22)
  • Create a RadioGroup to retrieve the priority (line #23)
  • Set the priority property of the task (lines #24-#34)
  • (In the next post we will implement adding the task to an adapter) (line #35)
  • Clear the controls on View (lines #37-#38)
package org.androidcodemonkey.todo;

import org.androidcodemonkey.entities.*;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioGroup;

public class DetailForm extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
private View.OnClickListener onSave=new View.OnClickListener() {
 public void onClick(View v) {
  TaskBE newTask =new TaskBE();
  EditText taskItem=(EditText)findViewById(R.id.txtTask);
  newTask.setItem(taskItem.getText().toString());
  RadioGroup priorityGroup=(RadioGroup)findViewById(R.id.priority);
  switch (priorityGroup.getCheckedRadioButtonId()) {
   case R.id.highPriority:
    newTask.setType("high_priority");
    break;
   case R.id.medPriority:
    newTask.setType("med_priority");
    break;
   case R.id.lowPriority:
    newTask.setType("low_priority");
    break;
  }
  //To do - Add task to adapter. To be implemented in next post
  //Clear form
  taskItem.setText("");
  priorityGroup.clearCheck();
  }
 };    

}


12. Now when the form is created we need instantiate a button and set it to the save button (line #18) and register a callback for when the button is pressed (line #19).
package org.androidcodemonkey.todo;

import org.androidcodemonkey.entities.*;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;

public class DetailForm extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button btnSave = (Button)findViewById(R.id.btnSave);
        btnSave.setOnClickListener(onSave);
        
    }
private View.OnClickListener onSave=new View.OnClickListener() {
 public void onClick(View v) {
  TaskBE newTask =new TaskBE();
  EditText taskItem=(EditText)findViewById(R.id.txtTask);
  newTask.setItem(taskItem.getText().toString());
  RadioGroup priorityGroup=(RadioGroup)findViewById(R.id.priority);
  switch (priorityGroup.getCheckedRadioButtonId()) {
   case R.id.highPriority:
    newTask.setType("high_priority");
    break;
   case R.id.medPriority:
    newTask.setType("med_priority");
    break;
   case R.id.lowPriority:
    newTask.setType("low_priority");
    break;
  }
  //To do - Add task to adapter. To be implemented in next post
  //Clear form
  taskItem.setText("");
  priorityGroup.clearCheck();
  }
 };    

}
13. You can now run the program. When you click "Save" your controls should be cleared. Your screen should look like this


Following is the complete code

Download zip file of complete Eclipse project





DetailFrom.java
package org.androidcodemonkey.todo;

import org.androidcodemonkey.entities.*;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;

public class DetailForm extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button btnSave = (Button)findViewById(R.id.btnSave);
        btnSave.setOnClickListener(onSave);
        
    }
private View.OnClickListener onSave=new View.OnClickListener() {
 public void onClick(View v) {
  TaskBE newTask =new TaskBE();
  EditText taskItem=(EditText)findViewById(R.id.txtTask);
  newTask.setItem(taskItem.getText().toString());
  RadioGroup priorityGroup=(RadioGroup)findViewById(R.id.priority);
  switch (priorityGroup.getCheckedRadioButtonId()) {
   case R.id.highPriority:
    newTask.setType("high_priority");
    break;
   case R.id.medPriority:
    newTask.setType("med_priority");
    break;
   case R.id.lowPriority:
    newTask.setType("low_priority");
    break;
  }
  //To do - Add task to adapter. To be implemented in next post
  //Clear form
  taskItem.setText("");
  priorityGroup.clearCheck();
  }
 };    

}
TaskBE.java

package org.androidcodemonkey.entities;

public class TaskBE {
 private String item="";
 private String priority="";
 
 public String getItem() {
  return(item);
 }
 
 public void setItem(String value) {
  this.item = value;
 }
 public String getPriority() {
  return(priority);
 }
 public void setType(String value) {
  this.priority = value;
 }
 public String toString() {
  return(getItem());
 }
}

 
  
   
   
  
  
   
   
     
     
     
   
  
  
   
   
 



16 comments:

Anonymous said...

HI,
this is ayyanababu ur tutorial is good by executing it showing error ur To do tutorial is stopped unexpectedly....so can u tell me how to solve that.............................i am very much intrested to ur posts.........

Anonymous said...

Hi its again me if you can how to create a database in sqlite for adding tables to it and follow all the CRUD rules to the database.......and also how to collect data from edittext and add it to list view.....can you.plz my email id is ayyanababu@yahoo.co.in

Greg Zimmers said...

I am working on another post that will store the tasks in a SQLlite db.

Kyle said...

Thanks for this tut Greg, great post. I came across your blog last night, while searching for "Beginning Android App Development". I am a college student in TN, my major is Computer Science, I want to focus on Web and Mobile development(Android, iPhone, etc.)
I know this may be a bit unusual, but I wanted to ask if you would be available for Job-Shadowing, sometime next week. My brother-in-law lives in Denver and is introducing me to a few friends of his for the same reason. I'm flying in tomorrow(3/15) and I'm leaving on Thurs 3/18. I know this is short notice, and perhaps a bit out of the ordinary. I have references available if necessary. @kylelippard or kylalipp@gmail.com

Anonymous said...

I was wondering if part 2 was created.

zak said...

I was wondering if part 2 was created?

Anonymous said...

k.good .

Anonymous said...

Where are the subsequent parts ?

Anonymous said...

I can't even download the source code anymore...

Tony said...

where is part 2?

vikas-patidar said...

Link of the eclipse project is broken. Update it. Thanks for nice tutorial.

Alex P said...

I have your exact code for main.xml, but the graphical view does not display any of the elements, and gives me:

error!
ClassCastException: com.android.layoutlib.bridge.MockView cannot be cast to android.view.ViewGroup
Exception details are logged in Window > Show View > Error LogThe following classes could not be found:
- tablelayout
- tablerow

There are no errors in the actual main.xml code. When I run the application, it just crashes instantly. Ideas?

Greg Zimmers said...

I have moved the zip file to another server. You can now download the project.

quachvidat said...

Show how to add task to adapter . where is the part2 tutorial

Anonymous said...

ok

Amit Bhaliya said...

Hello Dear,
My name is Amit Bhaliya i developing a simple andorid app but i have some problem in my app so if you can help me.i

explain my problem is there i cant give the hyperlink in my code so.you can provide me help then send me your email id then

i will send you my code.

Thanx
Amit Bhaliya
Android Developer
amit.potent@gmail.com

Post a Comment