I have a ListView with one EditText on each row (in addition to a couple of non-editable TextView's). When I'm editing the text in the EditText, the soft keyboard has "Next" button - and pressing it moves the focus to the next field - this is great. On the last row, the button changes to "Done".
I'm using EditText.setImeOptions
to set the button to "Done" or "Next" based on whether this is the last row or not.
The problem is that the listview can have more rows that can fit on the screen. When that happens, pressing "Next" on the next visible row moves the focus onto the first row again. How can I make it scroll the list and go to the next row instead?
For reference, here's what I'm doing in my adapter:
public class AuditAdapter extends BaseAdapter {
private Context context;
private int layoutResourceId;
private Audit audit;
...
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
final AuditItemHolder holder = (row == null ? new AuditItemHolder() : (AuditItemHolder)row.getTag());
if(row == null)
{
LayoutInflater inflater = ...;
row = inflater.inflate(layoutResourceId, parent, false);
...
holder.qtyf = (EditText)row.findViewById(R.id.item_quantity);
}
AuditItem item = audit.getItemAt(position);
holder.qtyf.setText("" + item.getQuantity());
holder.qtyf.setImeOptions(position == audit.size() - 1 ? EditorInfo.IME_ACTION_DONE : EditorInfo.IME_ACTION_NEXT);
...
row.setTag(holder);
return row;
}
private static class AuditItemHolder {
...
EditText qtyf;
}
}
Ok, after struggling for a long time, I finally found a hack (not a proper solution) that works for my case. In the getView
of my adapter, I add the onEditorActionListener
and inside it:
ediField.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
ListView lv = (ListView)parent;
if(actionId == EditorInfo.IME_ACTION_NEXT &&
lv != null &&
position >= lv.getLastVisiblePosition() &&
position != audit.size() - 1) { //audit object holds the data for the adapter
lv.smoothScrollToPosition(position + 1);
lv.postDelayed(new Runnable() {
public void run() {
TextView nextField = (TextView)holderf.qtyf.focusSearch(View.FOCUS_DOWN);
if(nextField != null) {
nextField.requestFocus();
}
}
}, 200);
return true;
}
return false;
}
});