Focusable EditText in the ListView and onItemClick

The solution that worked for me was to use the EditText with TextView and a flag in adater indicating edit mode enabled / disabled.

I added the TextView and the EditText in the same position in a relative layout, meaning they would be overlapping one another. The EditText will be hidden by default and TextView will be displayed. In this the item click of listview works flawlessly.

Then I assigned touch listener for TextView and onTouch I hide the textview and display the EditText and requestfocus enabling the input. Even the entire view's on click will request focus for EditText. So no item click shall be enabled.

I have a button in actionbar "Done". Once I click it I update my flag in Adapter saying "modeEdit = false" and call notifydatasetchanges.

In GetView we have check for the flag and if modeEdit = false, then display TextView.

This was only best solution I got to be working!!!

Hope this helps. Let me know if anyone is interested in the working copy of source code.


My solution:

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    ViewHolder vh = (ViewHolder) view.getTag();
    //vh.row is the convertView in getView or you may call it the row item itself
    ((ViewGroup)vh.row).setDescendantFocusability(view instanceof EditText?ViewGroup.FOCUS_AFTER_DESCENDANTS:ViewGroup.FOCUS_BLOCK_DESCENDANTS);
    return false;
}

And add

android:descendantFocusability="blocksDescendants"

to the view group in the layout xml file for the list row item.


Thanks @user370305 for the idea with OnTouchListener. Now it is working for me by using setOnTouchListener():

public class AdapterListCards extends CursorAdapter implements View.OnTouchListener {
 public AdapterListCards(Context context) {
    super(context, null, true);
 }

 @Override
 public boolean onTouch(View view, MotionEvent motionEvent) {
    if (view instanceof EditText) {
        EditText editText = (EditText) view;
        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
    } else {
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.edtCode.setFocusable(false);
        holder.edtCode.setFocusableInTouchMode(false);
    }
    return false;
 }

 private class ViewHolder {
    TextView txtName;
    EditText edtCode;
}

 @Override
 public View newView(final Context context, Cursor cursor, ViewGroup parent) {
    View convertView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
    final ViewHolder holder = new ViewHolder();
    holder.txtName = (TextView) convertView.findViewById(R.id.txt_name);
    holder.edtCode = (EditText) convertView.findViewById(R.id.pass);
    holder.edtCode.setOnTouchListener(this);
    convertView.setOnTouchListener(this);
    convertView.setTag(holder);

    return convertView;
 }

@Override
public void bindView(View view, Context context, Cursor cur) {
    ViewHolder holder = (ViewHolder) view.getTag();
    if (cur!=null) holder.txtName.setText(cur.getString(cur.getColumnIndex("name")));
 }
}

and of course: android:windowSoftInputMode="adjustPan" for activity in the manifest.