Обновление ListView
Я работаю над программой, которая использует ListView
который содержит строки, которые вводит пользователь. Я хочу, чтобы он перечислял каждую строку после того, как пользователь нажимает кнопку. Также я хочу, чтобы каждое строковое значение отображалось в ListView
также быть в массиве, чтобы я мог управлять списком позже. Вот что у меня сейчас:
public ArrayList<String> choices = new ArrayList<String>();
public String[] choicesArray;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView = (ListView) findViewById(R.id.listView1);
choicesArray = new String[] { "You have not entered a choice yet" };
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
choicesArray);
listView.setAdapter(adapter);
final Button addButton = (Button) findViewById(R.id.Button1);
addButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
adapter.add(message);
//choices.add(message);
//choicesArray = choices.toArray(choicesArray);
//listView.setAdapter(adapter);
}
});
}
Этот код создает ошибку:
FATAL EXCEPTION: main
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:404)
at java.util.AbstractList.add(AbstractList.java:425)
at android.widget.ArrayAdapter.add(ArrayAdapter.java:179)
at MainActivity$1.onClick(MainActivity.java:38)
2 ответа
Причина, по которой ваш список не обновляется, заключается в том, что вы никогда не добавляете свои элементы данных в адаптер. Вы только добавляете их в choicesArray
это массив, который вы передали в новый конструктор ArrayAdapter().
Этот конструктор не привязывает адаптер к массиву, но в основном копирует массив в адаптер (во время вызова конструктора). Изменения, внесенные в массив после этого, не будут отражены в ArrayAdapter.
Мне нравится думать, что ArrayAdapter<> - это то же самое, что ArrayList<>, с дополнительным бонусом возможности генерировать дочерние представления для некоторого родителя AdpaterView. Вы можете передать это array[]
для начала, и он инициализирует себя значениями в этом массиве, но он не связывает массив с адаптером или ListView. После этого первоначального вызова конструктора любые изменения одного из них не будут отражены в другом.
Поэтому вы должны изменить свой код, чтобы он выглядел так:
addButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
adapter.add(message);
//adapter.notifyDataSetChanged(); //<-- you might need to call this, but I think it might work without if you do it this way.
//listView.setAdapter(adapter); //<-- you shouldn't need to call this each time. Once at the begining is enough.
}
});
Редактировать:
измените ваш конструктор ArrayAdapter и удалите параметр choiceArray, чтобы вы остались с этим:
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1);
после этого я думаю, что тебе следует идти. По сути, проблема заключалась в том, что, поскольку вы передавали массив, и поскольку массивы имеют фиксированный размер (у вас была длина = 1), он не позволял вам что-либо добавлять. Я подозреваю, что вы могли бы использовать ArrayList<String>
вместо String[]
если вы хотите, но, честно говоря, для вашей ситуации, я думаю, будет проще просто пропустить этот параметр все вместе и добавлять элементы непосредственно в ваш адаптер всякий раз, когда вам нужно будет добавить новые.
После добавления нового String
в ваш список вы просто используете notifyDataSetChanged()
вашего адаптера, который говорит адаптеру обновить дисплей, и он будет обновлять ListView
с новой строкой
addButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
EditText editText = (EditText) findViewById(R.id.edit_choice);
String message = editText.getText().toString();
choices.add(message);
choicesArray = choices.toArray(choicesArray);
adapter.notifyDataSetChanged();
}
});
Обновить
Вы должны рассмотреть возможность внесения этого изменения тоже
choicesArray = new String[choices.size()];
choicesArray = choices.toArray(choicesArray);