在Android ListView中重置背景颜色

3
在我的QuestionsActivity中,我展示了一个问题和一堆答案。问题显示在TextView上,答案显示在由多个TextViews组成的ListView上。有一个名为“检查答案”的ActionButton,当它被点击时,通过改变ListView中的TextView的背景颜色来显示正确答案。
背景颜色更改的代码如下:
if (allAnswers.get(i).isCorrect())
{
   mAnswerList.getChildAt(i).setBackgroundColor
               (getResources().getColor(R.color.correct_answer_background));
   return;
}

现在,在此“QuestionsActivity”的页脚部分,有两个名为“PreviousQuestionButton”和“NextQuestionButton”的按钮,它们基本上是问题之间的导航按钮。
问题在于,当我点击“Check Answer”按钮后进入下一个问题时,答案背景颜色并没有消失,仍然在下一个问题的答案选项中存在。我尝试了“ListView”的“invalidate()”、“refreshDrawableState()”方法,但都没有成功!
以下是显示给定问题答案的方法:
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个回答

2

好的,要重置颜色,您可以创建一个新的适配器来进行硬重置。因此,请不要使用clearadd,因为这可能会保留视图在之前的状态。我不太确定这一点,因为我没有从适配器中清除或添加,而是始终创建一个新适配器来满足我的新需求。

无论如何,事情不顺利的另一个原因是,视图可能会被回收,因为我们正在谈论一个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()中,它将根据适配器状态和正确答案决定要做什么。
希望这有意义...我一边喝啤酒一边写这些 :)

我想知道每次使用一个新的适配器是否会严重降低性能? - Tarik
取决于此适配器中通常有多少项?如果您计划仅在按钮点击时更改适配器并且其中没有太多项,我会说这是安全的。这不是最佳解决方案,但在今天的设备上可以很好地工作。 - daemontus
这应该可以在不删除和添加适配器的情况下工作,只要您清除并添加时,请确保将 showCorrectAnswer 设置为 false。也许可以重写 clear 并在其中将 showCorrectAnswer 设置为 false,然后调用 super.clear() - gunar

1
基本上,我同意来自payeli的答案 - 你应该更改“下一题/上一题”按钮中选定答案的背景色。
但是,这里有一个问题:“是否有任何方法可以将ListView重置为没有应用任何背景的状态?”
据我所知,对此的答案是:不能直接。但是有两个解决方法。
如果您调用notifyDataSetChange,则不会完全重新绘制所有视图。如果可能,只更改适当的值。这主要是出于性能原因。(想象一下有1000个带有图像和名称的联系人被倾倒并重新绘制)
那么你该怎么处理呢?(除了在onClick方法中重置背景)由于你说这些项目是问题的答案,我假设你不关心性能,因为它们不会太多。
然后你可以简单地:
A) 创建Adapter的新实例,而不是更改旧数据。当你切换适配器时,列表中的所有视图都被删除,所以在新适配器中无法进行回收。
B) 创建自定义Adapter,覆盖getView方法,并确保每次请求视图时,你都返回一个新视图,这样就不会发生回收。

再次强调:这确实不是“性能友好型”的,不应该在具有大量项目的大列表中使用!

如果您想了解更多信息,请随时在评论中询问或阅读Adapter类的参考资料,特别是getView方法的参数convertView。(http://developer.android.com/reference/android/widget/Adapter.html


0
根据我的理解,您需要更改列表视图行中的文本视图颜色,即包含正确答案的行。
如果这是您的问题,则在单击按钮时简单地清除列表视图并重新创建列表视图。当重新创建列表视图时,请检查包含正确答案的行的位置。获取行位置后,只需更改文本视图的颜色即可。
例如:在您的适配器类中,在getView()中检查如下内容;
for ( int i = 0; i < position.length ; i++ )
{
if(position == your_required_position){
{
textview.setColor(Color.BLUE);
}else{
textview.setColor(Color.BLACK);
}
}

0
在“检查答案”按钮的onClickListener中,您需要重置颜色:
void onClick (View v){
    ..............
    mAnswerList.getChildAt(currentQuestion).setBackgroundColor
                   (getResources().getColor(R.color.default_answer_background));
}

我觉得我没有很好地解释我的问题。我的意思是,当我点击“下一题”或“上一题”按钮时,我想重置颜色。 - Tarik

0

你可以将默认背景保存在某个地方,当你按下下一个/上一个问题按钮时,应用该颜色。例如:

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" 即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接