Basically I have a listview with with each list item as (2 textviews and a checkbox). When a particular list item is clicked, I wanted to replace that row with a new edit-text view and some buttons. How do I implement this ? Should I use integer variables to store the current position of the selected item and load a different view OR use action motion events to get the current selected items ?
3 Answers
EditViews are actually subclassed from TextView, so you could actually use an EditText everywhere, and then set edditable=true\false depending on your needs.
Just another possible solution, but Tim's answer is also appropriate.

- 18,579
- 7
- 55
- 72
One possible solution would be to have your row.xml file contain both (2 textviews and a checkbox) and (EditText + some Buttons) But make the EditText and Buttons default to android:visibility="gone"
Then you could set an onItemClickListener() for the ListView that will call view.setVisibility() on the proper views to make them visible / invisible. This would appear to the user as though the new items are replacing the old ones in that row of the list.

- 46,603
- 18
- 125
- 156
-
Thanks for your answer. Yes, I can play with the visibility, but I still have to store the position of which list item is currently selected, so as to know at which position, the visibility has to be changed. – Mayuri Khinvasara Mar 30 '12 at 10:49
Your onItemClick()
should look like this:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyAdapter myAdapter = (MyAdapter) parent.getAdapter();
MyItem myItem = (MyItem) myAdapter.getItem(position);
myItem.setSelected(true); // set selected flag
// notify the data has been changed and the view should refresh itself
myAdapter.notifyDataSetChanged();
// you can obtain the item view type by calling
// myAdapter.getItemViewType(position);
...
}
Now override getViewTypeCount()
, getItemViewType()
and getView()
methods in your adapter:
class MyAdapter extends ArrayAdapter<MyItem> {
private LayoutInflater mInflater;
private static final int VIEW_ITEM_NORMAL = 0;
private static final int VIEW_ITEM_SELECTED = 1;
...
@Override
public int getItemViewType(int position) {
return getItem(position).isSelected() ? VIEW_ITEM_SELECTED : VIEW_ITEM_NORMAL;
// implement isSelected()
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
int layoutId;
int viewType = getItemViewType(position);
if (v == null) {
switch (viewType) {
case VIEW_ITEM_NORMAL:
layoutId = R.layout.list_item;
break;
case VIEW_ITEM_SELECTED:
layoutId = R.layout.list_item_selected;
break;
default:
layoutId = R.layout.list_item;
break;
}
v = mInflater.inflate(layoutId, parent, false);
} else {
v = convertView;
}
...
If only one item can change the view at the same time, it's better to store selected flag in your adapter:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyAdapter myAdapter = (MyAdapter) parent.getAdapter();
myAdapter.setSelected(position);
myAdapter.notifyDataSetChanged();
...
}
class MyAdapter extends ArrayAdapter<MyItem> {
private int mSelected = -1;
...
public void setSelected(int position) {
mSelected = position;
}
@Override
public int getItemViewType(int position) {
return (mSelected == position) ? VIEW_ITEM_SELECTED : VIEW_ITEM_NORMAL;
}
...
Don't forget to apply ViewHolder pattern you can see e.g. here.

- 13,179
- 11
- 45
- 52
-
Thanks @biegleux. Your solution of setting selected item for the adapter worked :) :) – Mayuri Khinvasara Mar 30 '12 at 10:47