ListView项目背景不改变

发布于 2024-11-17 21:58:34 字数 1354 浏览 8 评论 0原文

我的 ListView 有一个不寻常的问题。我目前有一个“deselectAll()”方法,它循环访问 ListView 中的项目并将它们设置为未选中状态(这些项目实现了 Checkable 接口)。 “checked”变量被正确更改(视图报告为未检查),但视觉指示器(在本例中为背景更改)不会将视图显示为未检查(背景保持检查项目的颜色)。

我像这样迭代和取消选择我的列表视图(我还添加了我的声明):

private ListView vw_entryList;

private void deselectAll() {
    for (int i = 0; i < sAdapter.getCount(); i++) {
        ((Entry)vw_entryList.getItemAtPosition(i)).setChecked(false);
    }
}

我实现的 setChecked() 的代码如下:

public void setChecked(boolean checked) {
    _checked = checked;
    if (checked) {
        setBackgroundResource(R.drawable.listview_checked);
    }
    else  {
        setBackgroundResource(R.drawable.listview_unchecked);
    }
    invalidate();
}

应该注意的是,当单击项目时,它们是在 OnItemClickListener 中在选中和未选中之间切换,并且随着背景更改和所有内容,这可以正常工作。切换的代码非常相似:

public void toggle() {
    _checked = !_checked;
    setBackgroundResource(_checked ? 
            R.drawable.listview_checked : R.drawable.listview_unchecked);
    invalidate();
}

我能看到的唯一区别是调用方法的位置。 toggle() 是从 OnItemClickListener.onClick() 方法中调用的,而我的 deselectAll() 是从按钮的标准 中调用的>OnClickListener,两者在同一个类中。 有人知道为什么当我调用 deselectAll() 函数时背景没有改变吗?

I have an unusual issue with my ListView. I currently have a "deselectAll()" method which iterates through the items in my ListView and sets them to unchecked (the items implement the Checkable interface). The "checked" variable gets changed correctly (the view reports as not being checked), but the visual indicator (in this case, a background change) does not show the view as unchecked (the background stays the color of a checked item).

I am iterating and deselecting through my listview like so (I also added my declerations):

private ListView vw_entryList;

private void deselectAll() {
    for (int i = 0; i < sAdapter.getCount(); i++) {
        ((Entry)vw_entryList.getItemAtPosition(i)).setChecked(false);
    }
}

The code for my implemented setChecked() is as follows:

public void setChecked(boolean checked) {
    _checked = checked;
    if (checked) {
        setBackgroundResource(R.drawable.listview_checked);
    }
    else  {
        setBackgroundResource(R.drawable.listview_unchecked);
    }
    invalidate();
}

It should be noted that when the items are clicked, they are toggled between checked and unchecked in the OnItemClickListener, and this works ok, with the background change and everything. The code for toggling is very similar:

public void toggle() {
    _checked = !_checked;
    setBackgroundResource(_checked ? 
            R.drawable.listview_checked : R.drawable.listview_unchecked);
    invalidate();
}

The only difference I can see is where the methods are called from. toggle() is called from within the OnItemClickListener.onClick() method, while my deselectAll() is called from within a button's standard OnClickListener, both in the same class. Does anyone have any ideas as to why the background doesn't change when I call my deselectAll() function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

塔塔猫 2024-11-24 21:58:34

您有自定义的非标准背景颜色吗?如果是这样,您可以看看 http://www.curious-creature.org/2008/12/22/why-is-my-list-black-an-android-optimization/ - 它归结为设置android:cacheColorHint 属性为你的列表设置背景颜色。也许这会有所帮助。

经过进一步讨论后编辑:

我认为您需要在列表上调用 getAdapter().notifyDataSetChanged() 而不是 invalidate()。列表实际上是通过适配器来提供数据的方式构建的。实际上,您正在做的事情有一个隐式适配器 - 条目实际上保存在适配器中,并且通过设置检查,您实际上正在更改数据模型,但是如果您不调用notifyDataSetChanged(),则列表并不真正知道该模型已更改并且不会重新创建视图(invalidate() 只会重绘现有视图)。

Do you have custom, non-standard color for the background? If so you might take a look at http://www.curious-creature.org/2008/12/22/why-is-my-list-black-an-android-optimization/ - it boils down to setting android:cacheColorHint attribute of your list to the background color. Maybe that will help.

Edited after further discussion:

I think you need to call getAdapter().notifyDataSetChanged() on the List rather than invalidate(). List is really build in the way that it is relying on adapter to provide the data. What you are doing in fact you have an implicit adapter - Entry is really kept in the adapter and by setting checked, you are changing the data model really, but if you do not call notifyDataSetChanged() the list does not really know that the model has changed and will not recreate the views (invalidate() will only redraw the existing ones).

岁月染过的梦 2024-11-24 21:58:34

在尝试了一切之后(感谢 Jarek 的帮助),我找到了一个适合我的目的的解决方案。我没有在单击的视图中隐式调用 setChecked() ,而是将其留给 ListView 类中的 setItemChecked() 方法。

我更新的代码:

private void deselectAll() {        
    for (int i = 0; i < sAdapter.getCount(); i++) {
        vw_entryList.setItemChecked(i, false);
    }
}

我最好的猜测是 ListView 知道它的项目实现了 Checkable 类,因此要求它自己成为所有项目操作的处理程序。沿着这些思路。如果有人可以更详细地解释为什么这个解决方案有效而其他解决方案无效,我将用答案和投票来奖励他们。

After trying everything (thanks for your help Jarek), I found a solution that works for my purposes. Instead of implicitly calling the setChecked() within the view that was clicked, I leave it up to the setItemChecked() method within the ListView class.

My updated code:

private void deselectAll() {        
    for (int i = 0; i < sAdapter.getCount(); i++) {
        vw_entryList.setItemChecked(i, false);
    }
}

My best guess is that the ListView knows that its items implement the Checkable class, and thus requires itself to be the handler of all item operations. Something along those lines. If anyone can explain in more detail why this solution works while the others did not, I'll reward them with the answer and an upvote.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文