Как сделать редактирование на месте в просмотре списка Android?
В основном у меня есть просмотр списка с каждым элементом списка как (2 просмотра текста и флажок). Когда щелкают по определенному элементу списка, я хотел заменить эту строку новым видом редактирования текста и некоторыми кнопками. Как мне это реализовать? Должен ли я использовать целочисленные переменные для хранения текущей позиции выбранного элемента и загрузки другого представления ИЛИ использовать события движения действия для получения текущих выбранных элементов?
3 ответа
EditViews фактически разделены на подклассы из TextView, так что вы можете использовать EditText везде, а затем установить edditable=true\false в зависимости от ваших потребностей.
Еще одно возможное решение, но ответ Тима тоже уместен.
Одним из возможных решений было бы, чтобы ваш файл row.xml содержал оба (2 текстовых просмотра и флажок) и (EditText + некоторые кнопки), но по умолчанию для EditText и Buttons задайте значение android:visibility="gone"
Затем вы можете установить onItemClickListener() для ListView, который будет вызывать view.setVisibility() для соответствующих представлений, чтобы сделать их видимыми / невидимыми. Это будет выглядеть для пользователя, как будто новые элементы заменяют старые в этой строке списка.
Ваш onItemClick()
должен выглядеть так:
@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);
...
}
Теперь переопределить getViewTypeCount()
, getItemViewType()
а также getView()
методы в вашем адаптере:
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;
}
...
Если только один элемент может изменить вид одновременно, лучше сохранить выбранный флаг в вашем адаптере:
@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;
}
...
Не забудьте применить шаблон ViewHolder, который вы можете увидеть, например, здесь.