I have a ListView with an EditText on each row working.
I need to select this text on click the edittext to write numbers without erasing or moving the cursor.
On the getView method of your adapter, get your EditView (in this code, edittxt) and do:
edittxt.post(new Runnable() {
public void run() {
edittxt.requestFocusFromTouch();
edittxt.selectAll();
InputMethodManager lManager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
lManager.showSoftInput(edittxt, 0);
}
});
I can't tell what it is that you are trying to do. Perhaps it'd help if you can post some of your relevant source code...
But the fact that it gets crazy when you start scrolling makes me thing you aren't handling the convertView correctly in your adapter getView() method.
I dealt with exactly the same problem by doing the following:
Subclassed EditText
public class TrickyEditText extends EditText {
private boolean mFocused = false;
private boolean mTouched = false;
public TrickyEditText(Context context) {
super(context);
}
public TrickyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr, int style) {
super(context, attrs, defStyleAttr, style);
}
@Override
public boolean didTouchFocusSelect() {
if (mTouched && mFocused) {
return true;
} else {
return super.didTouchFocusSelect();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mTouched = true;
return super.onTouchEvent(event);
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
mFocused = focused;
if (!focused) {
mTouched = false;
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
Adapter code
public class TrickyAdapter extends ArrayAdapter {
.............
@Override
public View getView(int childPosition, View convertView, final ViewGroup parent) {
.........
TrickyEditText et = ..... //initialize edittext
et.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(final View v, boolean hasFocus) {
if (hasFocus) {
v.post(new Runnable() {
@Override
public void run() {
((EditText)v).selectAll();
}
});
}
}
});
.........
}
}
Although it's working pretty well, it's not the code I'm proud of... If somebody knows a prettier solution, please tell me!
If you're having problem after scrolling it's the view recycling that's messing you up. You basically need to set up an array to hold the contents of the EditTexts so when you scroll they don't get messed up. You didn't say what was backing your list, but I've got a list with edittexts contained and here's how I handle it (from a cursor, but you could adapt it for an ArrayAdapter):
public class CursorAdapter_EditText extends SimpleCursorAdapter {
private static Cursor c;
private Context context;
public static String[] quantity;
private int layout;
public CursorAdapter_EditText(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
CursorAdapter_EditText.c = c;
this.context = context;
this.layout = layout;
initializeQuantity(); // Call method to initialize array to hold edittext info
}
public static void initializeQuantity() {
quantity = new String[c.getCount()]; // Initialize array to proper # of items
int i = 0;
while (i < c.getCount()) {
quantity[i] = ""; // set all EditTexts to empty
i++;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = View.inflate(context, layout, null);
final int pos = position;
View row = convertView;
c.moveToPosition(position);
TextView name = (TextView) row.findViewById(R.id.ListItem1);
EditText qty = (EditText) row.findViewById(R.id.qty);
qty.setOnFocusChangeListener(new View.OnFocusChangeListener() { // Set so EditText will be saved to array when you leave it
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
LinearLayout parent = (LinearLayout) v.getParent();
EditText qtyTemp = (EditText) parent.findViewById(R.id.qty); // Get a reference to EditText (you could probaly use v here)
quantity[pos] = qtyTemp.getText().toString(); // Save contents of EditText to array
}
}
});
name.setText(c.getString(1));
unit.setText(c.getString(3));
qty.setText(quantity[position]);
return (row);
}
}
Then I have a button outside the array that processes it back into my database like this:
commit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int i = 0;
itemCursor.moveToFirst();
while (itemCursor.isAfterLast() == false) {
if (CursorAdapter_EditText.quantity[i].equals("")) {
CursorAdapter_EditText.quantity[i] = "0";
}
;
int tempQty = Integer
.parseInt(CursorAdapter_EditText.quantity[i]);
if (tempQty != 0) {
mDbHelper.createListItem(listId, itemCursor
.getInt(itemCursor
.getColumnIndex(GroceryDB.ITEM_ROWID)),
tempQty, 0);
}
i++;
itemCursor.moveToNext();
}
}
});
What I can say about what I asked is that trying to select all text of the listview edittexts don't work properly. So instead of select the text, I show a dialog where the user selects the number or whatever.
Not sure if you are still looking for a solution, but I found a way to do it. Add a focus change listener to the edittext in the getView method of your adapter and select all text when focus is received.
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
// blah blah blah
EditText edit = (EditText) view.findViewById(R.id.editTextId);
edit.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus)
((EditText) view).selectAll();
}
});
return view;
}
I had set windowSoftInputMode to adjustPan for the activity, although I don't think it has any bearing on this matter.
I have tested this on Android 2.3 and 4 and it works.