ListView:通过Filterable进行过滤,使用新URI重新启动CursorLoader

时间:2013-08-09 10:14:33

标签: android android-listview android-cursoradapter

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

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

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

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

由于

P.S。这个问题与之前两者结合的How the system of URIs should be designed?分开了。

2 个答案:

答案 0 :(得分:2)

你可以从中受益。设置Filter,但在runQuery()的{​​{1}}中,不要对数据库运行全新的查询。只需使用原始光标周围的包装来过滤掉您不需要的内容。这个包装器很容易创建,在SO上也是mentioned

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

runQuery()

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

ListView/RecyclerView

作为替代方案,如果您不想扩展,可以为每个支持适配器的视图从您的活动@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); ((CursorAdapter) getAdapter()).changeCursor(null); } 中调用相同内容,但我更喜欢set-it-and -forget-it接近第一个提供。

答案 1 :(得分:0)

  

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

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

  

应该使用Filterable并且应该传递过滤器   不使用ListView过滤器的SQL查询?有没有   应该使用这种或那种方法的建议吗?

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

  

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

测量东西。使用更大的约束来创建新查询将减少数据集,但代价是用户看到结果较慢。如果时间不可接受,那么制作单个查询(对于初始约束)然后在没有额外的sqlite查询的情况下过滤该数据集会更有意义。