3

ListView实现过滤内容的方法。你能详细说明什么时候应该使用它吗?

据我了解,这种过滤适用于基于数组的适配器——所有数据都已经在内存中。这样,过滤器只会帮助跳过不应显示的数据。

但是,如果ListView与游标适配器(SQLite 数据库)一起使用以显示大量项目,则数据可能不在内存中。另一方面,过滤值可以嵌入到 SQL 查询中,从而有效地得到缩减的数据集。

ListView是否也为基于游标的数据设计了过滤机制?什么时候Filterable应该使用,什么时候应该在不使用 ListView 过滤器的情况下将过滤器传递给 SQL 查询?什么时候应该使用这种或那种方法,有什么建议吗?

谢谢

PS 问题与应如何设计 URI 系统?将两者结合在一起。

4

2 回答 2

2

您可以同时享受两者的好处。设置Filter但在runQuery()您的 中FilterQueryProvider,不要对数据库运行全新的查询。只需在原始光标周围使用包装器即可过滤掉不需要的内容。这个包装器创建起来相当简单,在 SO 上也提到过。

根据最近的经验:不要同时使用两者。Filterable做自己的后台处理,所以如果你使用它,根本不需要任何CursorLoader。实际上,同时使用两者并没有真正的危害,但会导致不必要的查询和性能下降。您的runQuery()查询应该处理两种情况,未过滤(约束为空)和过滤(约束不为空),这意味着所有查询操作都通过过滤器并且仅通过过滤器运行。启动它所需要做的就是在适配器的构造函数中调用它:

setFilterQueryProvider(this);
getFilter().filter(null);

一个令人讨厌的惊喜让我有些头疼。CusorLoader很好地管理光标,即使在严格模式下,也没有问题,但是使用Filterable,情况不太完美。正常操作没有问题,它确实处理了旧的游标,但活动生命周期的变化可以抓住它。我找到的解决方案是扩展ListView/RecyclerView与这些适配器一起使用的视图,并确保最终销毁光标:

@Override
protected void onDetachedFromWindow() {
  super.onDetachedFromWindow();
  ((CursorAdapter) getAdapter()).changeCursor(null);
}

作为替代方案,如果您不想扩展,您可以从您的活动中onDestroy()为每个适配器支持的视图调用相同的方法,但我更喜欢第一个提供的设置并忘记它的方法。

于 2014-12-29T11:26:10.207 回答
0

ListView 的过滤机制是否也是为基于游标的数据设计的?

通过Filter类的过滤机制是为适配器实现的(与适配器有关的逻辑操作),ListView只是该适配器的简单用户。

什么时候应该使用 Filterable 以及什么时候应该在不使用 ListView 过滤器的情况下将过滤器传递给 SQL 查询?什么时候应该使用这种或那种方法,有什么建议吗?

我认为没有关于使用哪一个的建议(或者我自己没有看到它们)。然而,Filter该类是专门为优化过滤过程而设计的(例如,如果初始过滤操作需要一些时间并且用户在这段时间内发出了其他请求,那么Filter该类将只执行最后一次安排的过滤操作(其他不会进行有意义的事情))。令我感到羞耻的是,如果在那个时候调用回调,我不知道是否CursorLoader会取消加载onLoaderReset(),如果它不这样做会很糟糕,因为你会做所有这些(如果用户进行过滤在 abcd fast 之后,你不想做 abcd,你想做广告)。您可以对其进行优化,但与过滤器相比的麻烦是没有意义的。

但是,如果 ListView 与光标适配器(SQLite 数据库)一起使用以显示大量项目,则数据可能不在内存中。另一方面,过滤值可以嵌入到 SQL 查询中,从而有效地得到缩减的数据集。

测量东西。进行具有更大约束的新查询将减少数据集,但代价是用户看到结果的速度较慢。如果时间不可接受,则进行单个查询(对于初始约束)然后过滤该数据集而不需要额外的 sqlite 查询可能会更有意义。

于 2013-08-11T09:14:26.553 回答