I have a simple ListActivity
that uses the SimpleCursorAdapter
. I allow users to change one of the values using an EditText
. I perform simple validation to make sure that the number entered is less than 100. If the user entered value fails validation, I want to put the old value back.
I've tried a few different ways. My current approach is to requery it out of the database, but this isn't working. I'm always getting the value associated with the last entry in the ListActivity
, regardless of which one was actually changed. I noticed in LogCat
that onTextChanged
and afterTextChanged
are firing multiple times for each row in the ListActivity
and not just the one that changed.
Here's the code:
public class MySimpleCursorAdapter extends SimpleCursorAdapter {
Context lcontext;
boolean changed;
String lastval;
private PortfolioData pfdata;
public MySimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
lcontext = context;
}
@Override
public View getView(final int pos, View v, ViewGroup parent) {
v = super.getView(pos, v, parent);
final EditText et = (EditText) v.findViewById(R.id.classpercentage);
final TextView tv = (TextView) v.findViewById(R.id._id);
et.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Log.d("TEST", "In afterTextChanged s=" + s.toString() + " "
+ tv.getText() + " POS = " + Integer.toString(pos));
lastval = tv.getText().toString();
if (changed == true) {
String enteredValue = s.toString();
if (checkNullValues(enteredValue)) {
if (Float.parseFloat(enteredValue.trim()) > 100.0f) {
AlertDialog.Builder builder = new AlertDialog.Builder(
lcontext);
builder.setMessage("Percentage Value should be Less than 100");
builder.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface arg0, int arg1) {
String sql = "select c.percentage as PERCENTAGE " +
"from asset_classes c WHERE c._id = " + lastval + ";";
pfdata = new PortfolioData(lcontext);
SQLiteDatabase db = pfdata.getReadableDatabase();
Cursor cursor = db.rawQuery(sql, null);
if (cursor != null)
{
cursor.moveToFirst();
et.setText(cursor.getString(0));
}
cursor.close();
pfdata.close();
}
});
// End of the Alert
if (changed == true)
{
builder.show();
}
}
}
changed = false;
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// Log.d("TEST", "In beforeTextChanged start=" +
// Integer.toString(start) +" count="+ Integer.toString(count) +
// " after=" + Integer.toString(after) + " s=" + s + " " + tv);
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
Log.d("TEST", "In onTextChanged start=" +
Integer.toString(start) + " count=" + Integer.toString(count)
+ " before=" + Integer.toString(before) + " s=" + s + " " +
tv);
changed = true;
}
});
return v;
}
}
I would really appreciate a fresh perspective on this. As always, thanks in advance.
Try to use an onFocusChangeListener. When it gets focus, save the current text into field of the class.
Something like:
String oldText - Would be your old text field.
Then you do:
et.setOnFocusChangeListener(new OnFocusChangeListener()) { @Override public void onFocusChange(View whatever, boolean hasFocus) { if (hasFocus) { //code } else { //code or maybe empty } } }
Then if the number is > 100 you just get the oldText value and put in the EditText.