Wednesday, May 9, 2012

Android To Do List

The To Do List application described in this tutorial  supports add new tasks, update and delete them. User can add new tasks using Options menu and delete them using Context menu

Download the complete project

main.xml

[sourcecode language="xml"]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>

</LinearLayout>
[/sourcecode]

new_task.xml

[sourcecode language="xml"]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/task"
android:textAppearance="?android:attr/textAppearanceMedium" />

<EditText
android:id="@+id/txtTask"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp" >

<requestFocus />
</EditText>

<TextView
android:id="@+id/textView3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/task"
android:textAppearance="?android:attr/textAppearanceMedium" />

<EditText
android:id="@+id/txtDesc"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginBottom="10dp"
android:layout_weight="0.40" >
</EditText>

<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/add" />

</LinearLayout>
[/sourcecode]

row.xml

[sourcecode language="xml"]
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/row"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

</TextView>
[/sourcecode]

Strings.xml

[sourcecode language="xml"]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ToDo List</string>
<string name="add">Add</string>
<string name="delete">Delete</string>
<string name="task">Task</string>
<string name="desc">Description</string>

</resources>
[/sourcecode]

AndroidManifest.xml

[sourcecode language="xml"]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.biz"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="10" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ToDo"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>
[/sourcecode]

DBHelper.java

[sourcecode language="java"]
package com.my.biz;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "tasks";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = "CREATE TABLE task_data (_id integer primary key autoincrement,task text not null,description text not null );";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);

}

@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
db.execSQL("DROP TABLE IF EXISTS task_data");
onCreate(db);

}

}

[/sourcecode]

DBAdapter.java

[sourcecode language="java"]
package com.my.biz;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class DBAdapter
{
private static final String DATABASE_TABLE = "task_data";
public static final String KEY_ROW_ID = "_id";
public static final String KEY_TASK = "task";
public static final String KEY_DESCRIPTION = "description";

SQLiteDatabase mDb;
Context mCtx;
DBHelper mDbHelper;

public DBAdapter(Context context)
{
this.mCtx = context;
}

public DBAdapter open() throws SQLException
{
mDbHelper = new DBHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}

public void close()
{
mDbHelper.close();
}

public long createTask(String task,String desciption)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TASK, task);
initialValues.put(KEY_DESCRIPTION, desciption);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}

public boolean deleteTask(long id)
{
return mDb.delete(DATABASE_TABLE, KEY_ROW_ID + " = " + id, null) > 0;
}

public boolean updateTask(long id,String task,String desciption)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TASK, task);
initialValues.put(KEY_DESCRIPTION, desciption);
return mDb.update(DATABASE_TABLE, initialValues, KEY_ROW_ID + " = " + id, null) > 0;
}

public Cursor fetchAllTasks()
{
return mDb.query(DATABASE_TABLE, new String[]{KEY_ROW_ID,KEY_TASK,KEY_DESCRIPTION}, null, null, null, null, null);
}

public Cursor fetchTask(long id)
{
Cursor c = mDb.query(DATABASE_TABLE, new String[]{KEY_ROW_ID,KEY_TASK,KEY_DESCRIPTION}, KEY_ROW_ID + " = " + id, null, null, null, null);
if(c != null)
{
c.moveToFirst();
}
return c;
}
}

[/sourcecode]

NewTask.java

[sourcecode language="java"]
package com.my.biz;

import com.my.biz.DBAdapter;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;

public class NewTask extends Activity {
DBAdapter mDbAdapter;
Long mRowId;
EditText mTask;
EditText mDesc;
DatePicker mDate;
Spinner mCategorry;
Button mAdd;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbAdapter = new DBAdapter(this);
mDbAdapter.open();
setContentView(R.layout.new_task);

mTask = (EditText)findViewById(R.id.txtTask);
mDesc = (EditText)findViewById(R.id.txtDesc);
mAdd = (Button)findViewById(R.id.btnAdd);

mRowId = (savedInstanceState == null) ? null :
(Long) savedInstanceState.getSerializable(DBAdapter.KEY_ROW_ID);
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(DBAdapter.KEY_ROW_ID)
: null;
}

populateFields();

mAdd.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
setResult(RESULT_OK);
finish();

}
});
}

private void populateFields() {
if (mRowId != null) {
Cursor c = mDbAdapter.fetchTask(mRowId);
startManagingCursor(c);
mTask.setText(c.getString(
c.getColumnIndexOrThrow(DBAdapter.KEY_TASK)));
mDesc.setText(c.getString(
c.getColumnIndexOrThrow(DBAdapter.KEY_DESCRIPTION)));

}
}

@Override
protected void onPause() {
super.onPause();
saveState();
}

@Override
protected void onResume() {
super.onResume();
populateFields();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putSerializable(DBAdapter.KEY_ROW_ID, mRowId);
}

private void saveState() {
String task = mTask.getText().toString();
String desc = mDesc.getText().toString();
if (mRowId == null) {
long id = mDbAdapter.createTask(task, desc);
if (id > 0) {
mRowId = id;
}
} else {
mDbAdapter.updateTask(mRowId, task, desc);
}
}

}

[/sourcecode]

ToDo.java

[sourcecode language="java"]
package com.my.biz;

import com.my.biz.DBAdapter;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class ToDo extends ListActivity {
DBAdapter mDbAdapter;
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;

public static final int INSERT_ID = Menu.FIRST;
public static final int DELETE_ID = Menu.FIRST + 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDbAdapter = new DBAdapter(this);
mDbAdapter.open();
fillData();
registerForContextMenu(getListView());
}

public void create()
{
Intent i = new Intent(this,NewTask.class);
startActivityForResult(i, ACTIVITY_CREATE);
}

public void fillData()
{
Cursor c = mDbAdapter.fetchAllTasks();
startManagingCursor(c);
String []from = new String[]{DBAdapter.KEY_TASK,DBAdapter.KEY_DESCRIPTION};
int [] to = new int[]{R.id.row};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.row, c, from, to);
setListAdapter(adapter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
fillData();
}

@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId())
{
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbAdapter.deleteTask(info.id);
fillData();
return true;
}
return super.onContextItemSelected(item);


}


@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.delete);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.add);
return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case INSERT_ID:
create();
return true;


}


return super.onOptionsItemSelected(item);
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this,NewTask.class);
i.putExtra(DBAdapter.KEY_ROW_ID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}


}
[/sourcecode]

Download the complete project

8 comments:

  1. Hey Rajitha, can you please help me,I have some problems running this app..
    I would be very thankful, i really need it.

    ReplyDelete
  2. Hi,
    Sorry for late reply. Could you be specific on your problems?

    ReplyDelete
  3. hey,
    Never mind i solved it myself. Thank you anyway :)

    ReplyDelete
  4. Hey Rajitha, May I know where do the images and default texts come from??

    ReplyDelete
  5. Sorry for late reply. The text is fetched from database table if there are any tasks. Please check populateFields() method.

    ReplyDelete
  6. Hey Rajitha, I have some problems.
    There is no response when i press the add button.

    ReplyDelete
  7. hey ser can i ask something why is it black

    ReplyDelete

How to enable CORS in Laravel 5

https://www.youtube.com/watch?v=PozYTvmgcVE 1. Add middleware php artisan make:middleware Cors return $next($request) ->header('Acces...