Simple notepad for Android
My development environment is
jdk1.7, android 4.2, and eclipse 4.2.1 (Juno). It's the first android
application I created. Precisely I created it referring to the sample that
Android provides in the Android SDK and the notepad lesson that Android
developers have provided. For more details about the notepad lesson, here's the
link.
** 2013/4/1 - For those who
are having bug on return from NoteEdit activity to NoteList activity. Tried to
download again for update to new version. I have updated the latest version to
link. Before debug latest version to android, old version must be uninstalled
first.
Here's how it looks like:
Left side is the note list and the
right side is the note editor. It's not really difficult to write this program
if you have certain experienced to android apps program. Basically what I have
used on this program mostly is fundamentally things like intent, SQLite
database, options menu, list activity and of course life-cycle. If you are
already tried the notepad exercise that I mentioned above basically you can
understand what I'm writing about.
I'm going to show what I have
written on this project.
Here's the java code for note list
Collapse | Copy
Code
package
com.example.note;
import
android.os.Bundle;
import
android.app.AlertDialog;
import
android.app.ListActivity;
import
android.content.DialogInterface;
import
android.content.Intent;
import
android.database.Cursor;
import
android.view.ContextMenu;
import
android.view.ContextMenu.ContextMenuInfo;
import
android.view.Menu;
import
android.view.MenuItem;
import
android.view.View;
import
android.widget.Button;
import
android.widget.ListView;
import
android.widget.SimpleCursorAdapter;
import
android.widget.TextView;
import
android.widget.AdapterView.AdapterContextMenuInfo;
public
class NoteList extends ListActivity {
private static final int DELETE_ID =
Menu.FIRST;
private int mNoteNumber = 1;
private NotesDbAdapter mDbHelper;
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notelist);
mDbHelper = new NotesDbAdapter (this);
mDbHelper.open();
fillData();
registerForContextMenu(getListView());
Button addnote =
(Button)findViewById(R.id.addnotebutton);
addnote.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
createNote();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the
action bar if it is present.
getMenuInflater().inflate(R.menu.notelist_menu,
menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem
item) {
switch (item.getItemId()) {
case R.id.menu_about:
AlertDialog.Builder dialog = new
AlertDialog.Builder(NoteList.this);
dialog.setTitle("About");
dialog.setMessage("Hello! I'm
Heng, the creator of this application. This application is created based on
learning." +
" Used it on trading or any
others activity that is related to business is strictly forbidden."
+"If there is any bug is
found please freely e-mail me. "+
"\n\tedisonthk@gmail.com"
);
dialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
return true;
default:
return
super.onOptionsItemSelected(item);
}
}
private void createNote() {
Intent i = new Intent(this, NoteEdit.class);
startActivityForResult(i,
ACTIVITY_CREATE);
}
@Override
protected void onListItemClick(ListView l,
View v, int position, long id) {
super.onListItemClick(l, v, position,
id);
Intent i = new Intent(this, NoteEdit.class);
i.putExtra(NotesDbAdapter.KEY_ROWID,
id);
startActivityForResult(i,
ACTIVITY_EDIT);
}
private void fillData() {
// Get all of the notes from the
database and create the item list
Cursor notesCursor =
mDbHelper.fetchAllNotes();
startManagingCursor(notesCursor);
String[] from = new String[] { NotesDbAdapter.KEY_TITLE
,NotesDbAdapter.KEY_DATE};
int[] to = new int[] { R.id.text1
,R.id.date_row};
// Now create an array adapter and set
it to display using our row
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this,
R.layout.notes_row, notesCursor, from, to);
setListAdapter(notes);
}
@Override
public void onCreateContextMenu(ContextMenu
menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v,
menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override
public boolean
onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info =
(AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteNote(info.id);
fillData();
return true;
}
return
super.onContextItemSelected(item);
}
@Override
protected void onActivityResult(int
requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode,
resultCode, intent);
fillData();
}
}
Here's the XML code for note list
Collapse | Copy
Code
<?xml
version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/notelist">
<TextView
android:id="@+id/textViewTop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingBottom="35dp" />
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/btmLayout"
android:layout_below="@+id/textViewTop"
android:background="#FFF9C8"
android:divider="#D3D3D3"
android:dividerHeight="1sp"
android:footerDividersEnabled="true"
/>
<LinearLayout
android:id="@+id/btmLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:layout_alignParentBottom="true"
android:layout_marginBottom="3dp"
android:layout_marginTop="10dp">
<Button
android:id="@+id/addnotebutton"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:background="@drawable/create_note"
/>
</LinearLayout>
</RelativeLayout>
The name written on background for
instance notelist and create_note is the png image files. You can download it
at the top of this blog.
Here's the XML code for list row
Collapse | Copy
Code
<?xml
version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10sp"
android:textSize="25sp"
android:hint="@string/no_title"
android:id="@+id/text1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize = "25sp"
android:id="@+id/date_row"
android:layout_alignParentRight="true"
android:layout_marginRight="10sp"/>
</RelativeLayout>
Here's the java code for note edit
Collapse | Copy
Code
package
com.example.note;
import
java.text.SimpleDateFormat;
import
java.util.Date;
import
android.app.Activity;
import
android.app.AlertDialog;
import
android.content.ContentValues;
import
android.content.Context;
import
android.content.DialogInterface;
import
android.content.Intent;
import
android.database.Cursor;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.graphics.Rect;
import
android.os.Bundle;
import
android.util.AttributeSet;
import
android.view.Menu;
import
android.view.MenuItem;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.EditText;
import
android.widget.TextView;
public class NoteEdit extends Activity {
public static int numTitle = 1;
public static String curDate = "";
public static String curText = "";
private EditText mTitleText;
private EditText mBodyText;
private TextView mDateText;
private Long mRowId;
private Cursor note;
private NotesDbAdapter mDbHelper;
public static class LineEditText extends
EditText{
// we need this constructor for
LayoutInflater
public LineEditText(Context context,
AttributeSet attrs) {
super(context, attrs);
mRect = new Rect();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(Color.BLUE);
}
private Rect mRect;
private Paint mPaint;
@Override
protected void onDraw(Canvas canvas) {
int height = getHeight();
int line_height = getLineHeight();
int count = height / line_height;
if (getLineCount() > count)
count = getLineCount();
Rect r = mRect;
Paint paint = mPaint;
int baseline = getLineBounds(0, r);
for (int i = 0; i < count; i++) {
canvas.drawLine(r.left, baseline +
1, r.right, baseline + 1, paint);
baseline += getLineHeight();
super.onDraw(canvas);
}
}
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
setContentView(R.layout.note_edit);
setTitle(R.string.app_name);
mTitleText = (EditText)
findViewById(R.id.title);
mBodyText = (EditText)
findViewById(R.id.body);
mDateText = (TextView)
findViewById(R.id.notelist_date);
long msTime =
System.currentTimeMillis();
Date curDateTime = new Date(msTime);
SimpleDateFormat formatter = new
SimpleDateFormat("d'/'M'/'y");
curDate = formatter.format(curDateTime);
mDateText.setText(""+curDate);
mRowId = (savedInstanceState == null) ?
null :
(Long)
savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
if (mRowId == null) {
Bundle extras =
getIntent().getExtras();
mRowId = extras != null ?
extras.getLong(NotesDbAdapter.KEY_ROWID)
: null;
}
populateFields();
}
@Override
protected
void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
}
@Override
protected void onPause() {
super.onPause();
saveState();
}
@Override
protected void onResume() {
super.onResume();
populateFields();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the
action bar if it is present.
getMenuInflater().inflate(R.menu.noteedit_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem
item) {
switch (item.getItemId()) {
case R.id.menu_about:
/*
Here is the introduce about myself */
AlertDialog.Builder dialog = new
AlertDialog.Builder(NoteEdit.this);
dialog.setTitle("About");
dialog.setMessage("Hello! I'm
Heng, the creator of this application. This application is created for
learning." +
" Using it on trading or any
others activity that is related to business is strictly forbidden."
+"If there is any bug is
found please freely e-mail me. "+
"\n\tedisonthk@gmail.com"
);
dialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
return true;
case R.id.menu_delete:
if(note != null){
note.close();
note = null;
}
if(mRowId != null){
mDbHelper.deleteNote(mRowId);
}
finish();
return true;
case R.id.menu_save:
saveState();
finish();
default:
return super.onOptionsItemSelected(item);
}
}
private void saveState() {
String title =
mTitleText.getText().toString();
String body =
mBodyText.getText().toString();
if(mRowId == null){
long id = mDbHelper.createNote(title,
body, curDate);
if(id > 0){ mRowId = id; }
}else{
mDbHelper.updateNote(mRowId, title,
body, curDate);
}
}
private void populateFields() {
if (mRowId != null) {
note = mDbHelper.fetchNote(mRowId);
startManagingCursor(note);
mTitleText.setText(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
mBodyText.setText(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
curText = note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY));
}
}
}
Here's the XML code for note edit
Collapse | Copy
Code
<?xml
version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF9C8">
<RelativeLayout
android:id="@+id/toplayout"
android:background="@drawable/notetop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingTop="5dp" >
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="@string/title"
android:id="@+id/title_text1" />
<EditText android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:hint="@string/no_title"
android:layout_toRightOf="@+id/title_text1"
android:background="@android:color/transparent"
android:layout_marginLeft="5dp"
android:singleLine="true"
android:imeOptions="actionNext"/>
<TextView
android:id="@+id/notelist_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingRight="10sp"
android:textSize="18sp" />
</RelativeLayout>
<view
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toplayout"
class="com.example.note.NoteEdit$LineEditText"
android:background="@android:color/transparent"
android:capitalize="sentences"
android:fadingEdge="vertical"
android:gravity="top"
android:padding="5dp"
android:scrollbars="vertical"
android:textSize="22sp" />
</RelativeLayout>
Here's the java code for note
adapters that provided by android developers. It's almost same but I did some
edit on it that I added the one more parameter for date.
Collapse | Copy
Code
import
android.content.ContentValues;
import
android.content.Context;
import
android.database.Cursor;
import
android.database.SQLException;
import
android.database.sqlite.SQLiteDatabase;
import
android.database.sqlite.SQLiteOpenHelper;
import
android.util.Log;
/**
* Simple notes database access helper class.
Defines the basic CRUD operations
* for the notepad example, and gives the
ability to list all notes as well as
* retrieve or modify a specific note.
*
* This has been improved from the first
version of this tutorial through the
* addition of better error handling and also
using returning a Cursor instead
* of using a collection of inner classes
(which is less scalable and not
* recommended).
*/
/*
It is not original code that notepad exercise provided.
*
* I did some edit on this code by adding date
parameter on it.
*/
public
class NotesDbAdapter {
public static final String KEY_TITLE = "title";
public static final String KEY_DATE = "date";
public static final String KEY_BODY = "body";
public static final String KEY_ROWID = "_id";
private static final String TAG = "NotesDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
/**
* Database creation sql statement
*/
private static final String DATABASE_CREATE
=
"create table notes (_id integer
primary key autoincrement, "
+ "title text not null, body text
not null, date text not null);";
private static final String DATABASE_NAME =
"data";
private static final String DATABASE_TABLE
= "notes";
private static final int DATABASE_VERSION =
2;
private
final Context mCtx;
private static class DatabaseHelper extends
SQLiteOpenHelper {
DatabaseHelper(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 oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database
from version " + oldVersion + " to "
+ newVersion + ",
which will destroy all old data");
db.execSQL("DROP TABLE IF
EXISTS notes");
onCreate(db);
}
}
/**
* Constructor - takes the context to allow
the database to be
*
opened/created
*
* @param ctx the Context within which to
work
*/
public NotesDbAdapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the notes database. If it cannot be
opened, try to create a new
* instance of the database. If it cannot
be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing
this to be chained in an
*
initialization call)
* @throws SQLException if the database
could be neither opened or created
*/
public NotesDbAdapter open() throws
SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
/**
* Create a new note using the title and
body provided. If the note is
* successfully created return the new
rowId for that note, otherwise return
* a -1 to indicate failure.
*
* @param title the title of the note
* @param body the body of the note
* @return rowId or -1 if failed
*/
public long createNote(String title, String
body, String date) {
ContentValues initialValues = new
ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
initialValues.put(KEY_DATE, date);
return mDb.insert(DATABASE_TABLE, null,
initialValues);
}
/**
* Delete the note with the given rowId
*
*
@param rowId id of note to delete
* @return true if deleted, false otherwise
*/
public boolean deleteNote(long rowId) {
return mDb.delete(DATABASE_TABLE,
KEY_ROWID + "=" + rowId, null) > 0;
}
/**
* Return a Cursor over the list of all
notes in the database
*
* @return Cursor over all notes
*/
public Cursor fetchAllNotes() {
return mDb.query(DATABASE_TABLE, new String[]
{KEY_ROWID, KEY_TITLE,
KEY_BODY,KEY_DATE}, null, null,
null, null, null);
}
/**
* Return a Cursor positioned at the note
that matches the given rowId
*
* @param rowId id of note to retrieve
* @return Cursor positioned to matching
note, if found
* @throws SQLException if note could not
be found/retrieved
*/
public Cursor fetchNote(long rowId) throws
SQLException {
Cursor mCursor =
mDb.query(true, DATABASE_TABLE, new
String[] {KEY_ROWID,
KEY_TITLE,
KEY_BODY,KEY_DATE}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Update the note using the details provided.
The note to be updated is
* specified using the rowId, and it is
altered to use the title and body
* values passed in
*
* @param rowId id of note to update
* @param title value to set note title to
* @param body value to set note body to
* @return true if the note was
successfully updated, false otherwise
*/
public boolean updateNote(long rowId, String
title, String body,String date) {
ContentValues args = new
ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
//This lines is added for personal
reason
args.put(KEY_DATE, date);
//One more parameter is added for data
return mDb.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
Here's the manisfest code for this
project
Collapse | Copy
Code
<?xml
version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.note"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16"
/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
>
<activity
android:name="com.example.note.NoteList"
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="com.example.note
.NoteEdit"
android:label="@string/app_name"
android:windowSoftInputMode="adjustUnspecified"/>
</application>
</manifest>
Code above I shows is not completely
all of this project. There is some files I didn't put on here due to I want to
show the main files of this project.
Comments
Post a Comment