Сбросить цвет фона в Android ListView
В моем QuestionsActivity
Я показываю вопрос и кучу ответов. Вопрос отображается на TextView
и ответы отображаются на ListView
который состоит из TextViews
, Есть ActionButton
называется "Проверить ответ", и при щелчке на нем отображается правильный ответ путем изменения цвета фона TextView
в ListView
,
Код изменения фона выглядит так:
if (allAnswers.get(i).isCorrect())
{
mAnswerList.getChildAt(i).setBackgroundColor
(getResources().getColor(R.color.correct_answer_background));
return;
}
и теперь есть два Button
с в нижней части этого QuestionsActivity
называется PreviousQuestionButton
а также NextQuestionButton
и они в основном кнопки навигации между вопросами.
Проблема в том, что когда я перехожу к следующему вопросу после нажатия кнопки "Проверить ответ", цвет фона ответа не исчезает и остается в параметрах ответа на следующий вопрос. Я старался invalidate()
, refreshDrawableState()
метод ListView
но не повезло!
Это метод, который отображает ответы на данный вопрос:
private void showAnswers(int questionLocation)
{
int questionId = mAllQuestions.get(questionLocation).getQuestionId();
List<Answer> answers = mAnswerRepository.getAllByQuestionId(questionId);
mAnswerAdapter.clear();
for (int i = 0; i < answers.size(); i++)
{
mAnswerAdapter.add(mOptionLetters[i] + ". "
+ answers.get(i).getAnswerText());
}
mAnswerAdapter.notifyDataSetChanged();
}
Мой вопрос
Я хочу, чтобы при нажатии на кнопки "Далее" или "Предыдущий" цвет фона правильного ответа в ListView исчезал, так что кнопка "Следующий" и "Предыдущий вопрос" может показывать пользователю список невыбранных вариантов ответа. Есть ли метод, который сбрасывает ListView в состояние, к которому не применяется какой-либо фон?
Для выбранного варианта ответа я использую mAnswerList.clearChoices()
чтобы отменить выбор, но это не относится к правильному цвету фона ответа.
5 ответов
Что ж, для сброса цвета вы можете очень сильно сбросить адаптер, создав новый. Так что не clear
а также add
поскольку это может сохранить взгляды в том состоянии, в котором они были раньше. Я не слишком уверен в этом, так как я не очищаю и не добавляю из адаптера, но всегда создаю новый для удовлетворения моих новых потребностей.
В любом случае, еще одна причина, по которой все может пойти не так, как вы хотите, состоит в том, что представления могут быть переработаны, так как мы говорим о ListView
, Поэтому, если вы хотите выделить элемент списка, вы должны сохранить в модели данных информацию о выделении, установив для него значение false, и если пользователь выбирает один, установите для состояния выделения значение true. Я полагаю Answer
класс имеет как минимум следующее:
public class Answer {
private String data;
private boolean correct;
public String getData() {
return data;
}
public boolean isCorrect() {
return correct;
}
@Override
public String toString() {
return data;
}
}
Таким образом, ваш адаптер может выглядеть близко к этому - getView
метод является наиболее важным, чтобы заметить (не забудьте установить фон по умолчанию, если ответ неправильный или адаптер не должен выделять правильный ответ):
public class MyAdapter extends ArrayAdapter<Answer> {
private boolean showCorrectAnswer;
private List<Answer> modelAnswers;
public MyAdapter(Context context, List<Answer> answers) {
super(context, android.R.layout.simple_list_item_1, answers);
this.modelAnswers = answers;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if(showCorrectAnswer && modelAnswers.get(position).isCorrect()) {
view.setBackgroundColor(getContext().getResources().getColor(R.color.correct_answer_background));
} else {
view.setBackgroundColor(getContext().getResources().getColor(R.color.default_background));
}
}
public void setShowCorrectAnswer(boolean showCorrectAnswer) {
this.showCorrectAnswer = showCorrectAnswer;
notifyDataSetChanged();
}
}
Что вам нужно сделать, это сохранить ссылку на этот пользовательский адаптер и, если вам нужно выделить правильный ответ или просто позвонить setShowCorrectAnswer(true / false);
, Это вызовет перерисовку и в getView()
он будет решать, что делать, основываясь на состоянии адаптера и правильном ответе.
Надеюсь, это имеет смысл... Я написал все это, попивая пиво:)
В принципе, я согласен с ответом от Payeli - вы должны изменить фон выбранного ответа в кнопке "следующий / предыдущий вопрос".
Но тогда возникает вопрос: "Есть ли метод, который сбрасывает ListView в состояние, к которому не применяется какой-либо фон?"
Ответ на это (насколько я знаю): не напрямую. Но есть два обходных пути.
Если вы вызываете notfiyDataSetChange, не все представления полностью перерисовываются. Если возможно, меняются только соответствующие значения. Это в основном по причинам производительности. (Представьте, что у вас есть 1000 контактов с изображениями и именами, сброшенными и перерисованными)
Так как вы можете справиться с этим? (Если не считать сброса фона в методе onClick) Поскольку вы сказали, что эти элементы являются ответами на вопрос, я предполагаю, что вы не беспокоитесь о производительности, поскольку их не будет слишком много.
Тогда вы можете просто:
A) Создайте новый экземпляр Adapter вместо изменения данных в старом. При переключении адаптеров все представления в списке удаляются, поэтому в новом адаптере переработка невозможна.
Б) Создайте пользовательский адаптер, переопределите метод getView и убедитесь, что каждый раз, когда запрашивается представление, вы возвращаете новое представление, поэтому повторное использование невозможно.
Опять же: это действительно не "дружественно к производительности" и не должно использоваться с большими списками с большим количеством элементов!
Если вы хотите узнать больше, не стесняйтесь спрашивать в комментариях или читать ссылку на класс Adapter, особенно параметр convertView метода getView. ( http://developer.android.com/reference/android/widget/Adapter.html)
В onClickListener кнопки "Проверить ответ" вам нужно сбросить цвет:
void onClick (View v){
..............
mAnswerList.getChildAt(currentQuestion).setBackgroundColor
(getResources().getColor(R.color.default_answer_background));
}
Согласно моему пониманию, вам нужно изменить цвет текста в одной строке списка, то есть в строке, содержащей правильный ответ.
Если это ваша проблема, то при нажатии кнопки просто очистите представление списка и заново создайте представление списка. Не, когда представление списка воссоздается, тогда проверьте положение строки, которая содержит правильный ответ. После получения положения строки просто измените цвет текста.
Например: в вашем классе Adapter отметьте как пара в вашем getView();
for ( int i = 0; i < position.length ; i++ )
{
if(position == your_required_position){
{
textview.setColor(Color.BLUE);
}else{
textview.setColor(Color.BLACK);
}
}
Вы можете сохранить фон по умолчанию где-нибудь, и когда вы нажимаете кнопку следующего / предыдущего вопроса, вы должны применить этот цвет. Пример:
TypedArray array = getTheme().obtainStyledAttributes(new int[] {
android.R.attr.colorBackground,
android.R.attr.textColorPrimary,
});
int backgroundColor = array.getColor(0, 0xFF00FF);
int textColor = array.getColor(1, 0xFF00FF);
array.recycle();
Я нашел этот код в Интернете, чтобы получить фон и цвет текста (вы можете просто сохранить фоновую часть), когда активируется onClick, просто установите фон вашего представления в "backgroundColor"