I am making an Android app that uses a sqlite database
to store the app data, an activity
class to edit / insert data, a DbHelper
to manage the database creation and version, and a content provider
which manages access to the database.
I have managed to get data to be queried, inserted, deleted and edited from the database. However, I'm not too sure on how to add visual feedback to the user. I've tried adding a Toast
in place where I have put an IllegalArgumentException
but the app will simply add the content to the database.
If I omit the Name, the app will trigger the defined IllegalArgumentException
and then crash the application.
This is a snippet for the insert
method in the content provider
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
final int match = sUriMatcher.match(uri);
switch (match) {
case PATIENT:
return insertPatient(uri, contentValues);
default:
throw new IllegalArgumentException("Insertion is not supported for " + uri);
}
}
/**
* Insert a patient into the database with the given content values.
*/
private Uri insertPatient(Uri uri, ContentValues values) {
String name = values.getAsString(PatientEntry.COLUMN_PATIENT_NAME);
if (name == null || name.length()==0) {
//Toast.makeText(getContext(), "Patient requires a name", Toast.LENGTH_SHORT).show();
throw new IllegalArgumentException("Patient requires a name");
}
Integer weight = values.getAsInteger(PatientEntry.COLUMN_PATIENT_WEIGHT);
if (weight != null && weight < 0) {
throw new IllegalArgumentException("Patient requires valid weight");
}
SQLiteDatabase database = mDbHelper.getWritableDatabase();
long id = database.insert(PatientEntry.TABLE_NAME, null, values);
if (id == -1) {
Log.e(LOG_TAG, "Failed to insert row for " + uri);
return null;
}
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
This is a snippet from the activity file
private void savePatient() {
String nameString = mNameEditText.getText().toString().trim();
String weightString = mWeightEditText.getText().toString().trim();
if (mCurrentPatientUri == null &&
TextUtils.isEmpty(nameString) && TextUtils.isEmpty(weightString) {
Toast.makeText(this, "Data was not saved", Toast.LENGTH_SHORT).show();
return;
}
ContentValues values = new ContentValues();
values.put(PatientEntry.COLUMN_PATIENT_NAME, nameString);
int weight = 0;
if (!TextUtils.isEmpty(weightString)) {
weight = Integer.parseInt(weightString);
}
values.put(PatientEntry.COLUMN_PATIENT_WEIGHT, weight);
// Determine if this is a new or existing Patient by checking if mCurrentPatientUri is null or not
if (mCurrentPatientUri == null) {
// This is a NEW patient
Uri newUri = getContentResolver().insert(PatientEntry.CONTENT_URI, values);
if (newUri == null) {
Toast.makeText(this, getString(R.string.editor_insert_patient_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getString(R.string.editor_insert_patient_successful),
Toast.LENGTH_SHORT).show();
}
} else {
// Otherwise this is an EXISTING patient
int rowsAffected = getContentResolver().update(mCurrentPatientUri, values, null, null);
if (rowsAffected == 0) {
Toast.makeText(this, getString(R.string.editor_update_patient_failed),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getString(R.string.editor_update_patient_successful),
Toast.LENGTH_SHORT).show();
}
}
}
Could someone kindly lend a hand?
.................................................................
This is the menu in the activity
which calls savePatient
:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
case R.id.action_save:
savePatient();
finish();
return true;
case R.id.action_delete:
showDeleteConfirmationDialog();
return true;
case android.R.id.home:
if (!mPatientHasChanged) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
return true;
}
// Otherwise if there are unsaved changes, setup a dialog to warn the user.
DialogInterface.OnClickListener discardButtonClickListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
NavUtils.navigateUpFromSameTask(EditorActivity.this);
}
};
showUnsavedChangesDialog(discardButtonClickListener);
return true;
}
return super.onOptionsItemSelected(item);
}
For visual feedback validations are to be done as early as possible. For example before you call save patient on some user action just call validatePatient() which if fails save will not be called.
For Visual feedback you can have error texts below your fields that will become visible only if validation related to that field fails.