UnsupportedOperationException в setOnItemClickListener
Вылетает UnsupportedOperationException. Подскажите, пожалуйста в чем проблема? Может ли это быть связано с тем, что создаю массив, у которого фиксированный размер? Заранее спасибо и всем хороших выходных!
public class MainActivity extends AppCompatActivity {
final String ATTRIBUTE_NAME_TEXT = "text";
final String ATTRIBUTE_NAME_QUANTITY = "quantity";
ListView lvSimple;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] texts = {Util.text1, Util.text2, Util.text3, Util.text4,
Util.text5, Util.text6, Util.text7, Util.text8 };
int[] quantity2 = {texts[0].length(), texts[1].length(), texts[2].length(),
texts[3].length(), texts[4].length(), texts[5].length(), texts[6].length() , texts[7].length()};
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
texts.length);
Map<String, Object> m;
for (int i = 0; i < texts.length; i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_NAME_TEXT, texts[i]);
m.put(ATTRIBUTE_NAME_QUANTITY, quantity2[i]);
data.add(m);
}
String[] from = { ATTRIBUTE_NAME_TEXT, ATTRIBUTE_NAME_QUANTITY};
int[] to = { R.id.tvText, R.id.tvText2 };
final SimpleAdapter sAdapter = new SimpleAdapter(this, data, R.layout.item,
from, to);
lvSimple = findViewById(R.id.lvSimple);
lvSimple.setAdapter(sAdapter);
lvSimple.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
lvSimple.getItemAtPosition(position);
lvSimple.removeViewAt(position);
}
});
}
}
Ответы (2 шт):
UnsupportedOperationException
Часто эта ошибка возникает, когда мы используем метод asList() из java.util.Arrays:
public static List asList(T... a)
Возвращает:
фиксированный размер List от размера данного array
элемент того же типа, что и в оригинальном array , и это
должен быть Object элементы в том же порядке как в исходном массиве
список, который Serializable и реализует RandomAccess
Поскольку T является ссылкой:/java-varargs[ varargs ], мы можем передать массив или элементы непосредственно в качестве параметров, и метод создаст инициализированный список фиксированного размера:
List<String> flowers = Arrays.asList("Ageratum", "Allium", "Poppy", "Catmint");
Мы также можем передать фактический array :
String[]flowers = { "Ageratum", "Allium", "Poppy", "Catmint" };
List<String> flowerList = Arrays.asList(flowers);
Поскольку возвращенный List является List фиксированного размера, мы не можем добавлять/удалять элементы.
Попытка добавить больше элементов вызовет UnsupportedOperationException:
String[]flowers = { "Ageratum", "Allium", "Poppy", "Catmint" };
List<String> flowerList = Arrays.asList(flowers);
flowerList.add("Celosia");
Корень этого Exception заключается в том, что возвращаемый объект не реализует операцию _add() , поскольку он не совпадает с java.util.ArrayList._
Это ArrayList , из java.util.Arrays.
Другой способ получить то же исключение - попытаться удалить элемент из полученного списка.
С другой стороны, есть способы получить изменяемый List на тот случай, если он нам понадобится.
Одним из них является создание ArrayList или любого вида списка непосредственно из результата asList() :
String[]flowers = { "Ageratum", "Allium", "Poppy", "Catmint" };
List<String> flowerList = new ArrayList<>(Arrays.asList(flowers));
В вопросе следует указывать какая строка выбивает ошибку. Подозреваю что эта:
lvSimple.removeViewAt(position);
потому что в ListView нельзя управлять элементами напрямую в обход адаптера.
https://developer.android.com/reference/android/widget/AdapterView#removeViewAt(int)
Вместо этого нужно изменить коллекцию данных, связанную с адаптером и уведомить адаптер об изменении, чтобы он обновил вывод на экране.
В данном примере это нужно делать так:
lvSimple.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
data.remove(position);
sAdapter.notifyDataSetChanged();
}
});