【问题标题】:Filter rows from Cursor so they don't show up in ListView从 Cursor 中过滤行,这样它们就不会出现在 ListView 中
【发布时间】:2010-06-12 04:00:52
【问题描述】:

我有一个游标,它返回我使用 SimpleCursorAdapter 来填充 ListView 的行。我想过滤一些行,这样它们就不会显示在我的 ListView 中。我在 Activity 的其他地方使用行中的数据,因此我不想更改我的 SQL 以使用 WHERE 子句过滤它们。

保持一行不显示在我的 ListView 中的最佳方法是什么?理想情况下,我会检查行中的一列,然后只向 ListView 添加满足条件的行。

【问题讨论】:

标签: android


【解决方案1】:

创建一个CursorWrapper 并覆盖move...() 方法以转换过滤集中的位置(这是ListView 将看到的)和实际Cursor 中的位置。然后,在SimpleCursorAdapter 中使用您的CursorWrapper

【讨论】:

    【解决方案2】:

    谢谢,这对我很有帮助!如果需要,请使用它:

    private class FilterCursorWrapper extends CursorWrapper {     
        private String filter;
        private int column;
        private int[] index;
        private int count=0;
        private int pos=0;
    
        public FilterCursorWrapper(Cursor cursor,String filter,int column) {
            super(cursor);
            this.filter = filter.toLowerCase();
            this.column = column;
            if (this.filter != "") {
                this.count = super.getCount();
                this.index = new int[this.count];
                for (int i=0;i<this.count;i++) {
                    super.moveToPosition(i);
                    if (this.getString(this.column).toLowerCase().contains(this.filter))
                        this.index[this.pos++] = i;
                }
                this.count = this.pos;
                this.pos = 0;
                super.moveToFirst();
            } else {
                this.count = super.getCount();
                this.index = new int[this.count];
                for (int i=0;i<this.count;i++) {
                    this.index[i] = i;
                }
            }
        }
    
        @Override
        public boolean move(int offset) {
            return this.moveToPosition(this.pos+offset);
        }
    
        @Override
        public boolean moveToNext() {
            return this.moveToPosition(this.pos+1);
        }
    
        @Override
        public boolean moveToPrevious() {
            return this.moveToPosition(this.pos-1);
        }
    
        @Override
        public boolean moveToFirst() {
            return this.moveToPosition(0);
        }
    
        @Override
        public boolean moveToLast() {
            return this.moveToPosition(this.count-1);
        }
    
        @Override
        public boolean moveToPosition(int position) {
            if (position >= this.count || position < 0)
                return false;
            this.pos = position;
            return super.moveToPosition(this.index[position]);
        }
    
        @Override
        public int getCount() {
            return this.count;
        }
    
        @Override
        public int getPosition() {
            return this.pos;
        }
    
    }
    

    https://gist.github.com/ramzes642/5400792

    【讨论】:

    • 你能解释一下如何使用它吗?请
    • 只需添加一件事:将基本光标存储在构造函数中并覆盖 close():@Override public void close() { if (baseCursor != null) baseCursor.close();超级关闭(); }
    • 其他 2 件事:(this.filter != "") 不正确,并且 this.pos 从未更新,因此 getPosition() 已经返回 0。除此之外,这很好用。
    • @Gábor 关闭基本光标似乎是由 FilterCursorWrapper 用户而不是包装器本身完成的工作,但如果你没有像这样实例化基本光标本身,我明白你的意思:FilterCursorWrapper (resolver.query(...));我的意思是这真的取决于你的使用情况。也许包装器模式说明了一些可能使您的建议更严格(或不更严格)的内容。
    【解决方案3】:

    在 Romans 的解决方案中添加

    this.pos = position;
    

    在方法中

    @Override
    public boolean moveToPosition(int position) {
        if (position >= this.count || position < 0)
            return false;
        return super.moveToPosition(this.index[position]);
    }
    

    否则在使用 .moveToNext() 和 .moveToPrevious() 时会出现一些问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-27
      • 2020-11-29
      • 2020-05-09
      • 2021-04-03
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多