Сбросить цвет фона в 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"

Другие вопросы по тегам