A very open-ended, n00b-esque question about extending the Notepad tutorial in Android [closed]
I want to start off by asking for your collective patience... I am trying to learn to program for Android by trial-and-error type modification of the Google Sample code: "Notepad Tutorial" So far things have been very slow going. (I am also reading Head First Java :)
My goal is to add to the tutorial app an additional TextEdit field and a Button... I want the user to be able to enter text into the field, then press the button and have the text they just entered be appended to the database and then dropped down to a textView within a scrollView so that a record of the entries is visible to the viewer. Basically, my goal is to allow the user to add an indefinite number of data (depending on the number of times the button is clicked) into each database entry. I have gotten part of the way there (adding a new db field, creating the TextEdit and button etc..) but I am having trouble putting it all together... specifically how to make it work on the db end. I am not sure that I am explaining this properly... but i will attach the relevant source code to try to make it clearer.
(Note: KEY_HOUSE is the db field I added and house/mHouseText are the related variables in question)
NoteEdit.java
package com.android.demo.notepad3;
import android.R.string;
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.CheckBox;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.TableRow.LayoutParams;
public class NoteEdit extends Activity{
private EditText mTitleText;
private EditText mBodyText;
private Long mRowId;
private NotesDbAdapter mDbHelper;
Button btn;
int counter = 0;
private EditText mHouseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
setContentView(R.layout.note_edit);
setTitle(R.string.edit_note);
mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
mHouseText = (EditText) findViewById(R.id.house);
Button confirmButton = (Button) findViewById(R.id.confirm);
Button btn = (Button) findViewById(R.id.Button01);
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();
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setResult(RESULT_OK);
finish();
}
});
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
addrow();
}
});
}
private void populateFields() {
if (mRowId != null) {
Cursor note = mDbHelper.fetchNote(mRowId);
startManagingCursor(note);
mTitleText.setText(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
mBodyText.setText(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
mHouseText.setText(note.getString(
note.getColumnIndexOrThrow(NotesDbAdapter.KEY_HOUSE)));
}
}
@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();
}
private void saveState() {
String title = mTitleText.getText().toString();
String body = mBodyText.getText().toString();
String house = mHouseText.getText().toString();
if (mRowId == null) {
long id = mDbHelper.createNote(title, body, house);
if (id > 0) {
mRowId = id;
}
} else {
mDbHelper.updateNote(mRowId, title, body, house);
}
}
private void addrow(){
//mHouseText = (EditText) findViewById(R.id.house);
String house = mHouseText.getText().toString();
// get a reference for the TableLayout
TableLayout table = (TableLayout) findViewById(R.id.TableLayout02);
// create a new TableRow
TableRow row = new TableRow(this);
// create a new TextView
TextView t = new TextView(this);
// set the text to "text xx"
t.setText(house);
// create a CheckBox
CheckBox c = new CheckBox(this);
// add the TextView and the CheckBox to the new TableRow
row.addView(t);
row.addView(c);
// add the TableRow to the TableLayout
table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
}
NotesDbAdapter.java
package com.android.demo.notepad3;
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).
public class NotesDbAdapter {
public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_HOUSE = "house";
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, house 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 house) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
initialValues.put(KEY_HOUSE, house);
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_HOUSE}, 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_HOUSE}, 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 house) {
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
args.put(KEY_HOUSE, house);
return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
NoteEdit.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0">
<TableRow android:id="@+id/TableRow01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title" />
<EditText android:id="@+id/title"
android:layout_height="wrap_content"
android:layout_width="wrap_content" android:hint="Montague St."/>
</TableRow>
<TableRow android:id="@+id/TableRow02" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/body" />
<EditText android:id="@+id/body" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scrollbars="vertical" android:hint="44"/>
</TableRow>
</TableLayout>
<ScrollView android:id="@+id/ScrollView01" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TableLayout android:id="@+id/TableLayout02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="0">
<TableRow android:id="@+id/TableRow03" android:layout_width="wrap_content" android:layout_height="wrap_content">
<EditText android:id="@+id/house" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="House Number"></EditText>
<CheckBox android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content"></CheckBox>
</TableRow>
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add House"></Button>
</TableLayout>
</ScrollView>
<LinearLayout android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button android:id="@+id/confirm"
androi开发者_高级运维d:text="@string/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
I recognize that my issue is extremely open ended and "n00b"-esque, but any help, or even just a nudge in the right direction, would be greatly appreciated.
Thanks
Frank
Sounds like what you want is a one-to-many relationship in your data. For that, you'd create another table like "note_houses" where each record is a single text entry/"house" with a note_id column that acts as a foreign key, like this:
create table note_houses (
_id integer primary key autoincrement,
note_id integer not null references notes (_id),
entry text not null
)
When someone taps the button to add a new entry, it should insert a new record into this table (to do this you'll have to write a createHouse method similar to createNote). The scrolling list of entries appearing below could then be generated with a ListView. The Cursor for the ListView's adapter would need to be generated from a fetchHousesByNote method in the DbAdapter that would do a query like this:
select * from note_houses where note_id=?
...and you bind the note_id parameter to the ID of the note that's being edited.
Does that make sense? Is it what you're asking for?
Create a method in the database class that allows you to update a record. Then call that method in an onClickListener on the button which will read the values and pass it on to the database method for updating. That will not be perfect but should work.
精彩评论