使用 EditText 过滤 SimpleCursorAdapter 支持的 ListView

Posted

技术标签:

【中文标题】使用 EditText 过滤 SimpleCursorAdapter 支持的 ListView【英文标题】:Using an EditText to filter a SimpleCursorAdapter-backed ListView 【发布时间】:2011-07-10 03:21:59 【问题描述】:

我有一个由 SimpleCursorAdapter 支持的自定义项目布局的 ListView。我希望用户能够在 EditText 框中键入文本,并让 ListView 在键入时自动过滤。正如here 所述,使用 ArrayAdapter 看起来很简单。

不幸的是,我无法让它与 SimpleCursorAdapter 一起使用。我已经尝试按照here 的描述添加额外的方法,但该示例适用于 AutoCompleteTextView 而不是 ListView。我无法为我的 ListView 获得任何工作。

有人可以提供一个使用 EditText 框过滤 SimpleCursorAdapter 支持的 ListView 的示例吗?

public class DirectoryListActivity extends DirectoryActivity 

    private static SimpleCursorAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        setContentView(R.layout.directory_list);

        fillPeopleListView();

        EditText etext=(EditText)findViewById(R.id.search_box);
        etext.addTextChangedListener(new TextWatcher() 

            public void onTextChanged(CharSequence s, int start, int before, int count) 


            

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) 


            

            public void afterTextChanged(Editable s) 
                adapter.getFilter().filter(s.toString());

            
        );

    

    private void fillPeopleListView() 
        // Populate the ListView
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        queryBuilder.setTables(
            directoryPeople.PEOPLE_TABLE
        );

        String asColumnsToReturn[] =  
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.LAST_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.FIRST_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.MIDDLE_NAME + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople.JOB_TITLE + "," +
                directoryPeople.PEOPLE_TABLE + "."
                + directoryPeople._ID
        ;

        mCursor = queryBuilder.query(mDB, asColumnsToReturn, null, null,
                null, null, directoryPeople.DEFAULT_SORT_ORDER);

        startManagingCursor(mCursor);

        adapter = new SimpleCursorAdapter(this,
                R.layout.directory_people_item, mCursor,
                new String[]
                    directoryPeople.LAST_NAME,
                    directoryPeople.FIRST_NAME,
                    directoryPeople.MIDDLE_NAME,
                    directoryPeople.JOB_TITLE,
                new int[]
                    R.id.txtLastName,
                    R.id.txtFirstName,
                    R.id.txtMiddle,
                    R.id.txtTitle 
        ); 

        ListView av = (ListView)findViewById(R.id.listPeople);
        av.setAdapter(adapter);
        av.setFastScrollEnabled(true);

        adapter.setFilterQueryProvider(new FilterQueryProvider() 

            public Cursor runQuery(CharSequence constraint) 
                String partialValue = constraint.toString();

                SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

                String asColumnsToReturn[] =  
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.LAST_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.FIRST_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.MIDDLE_NAME + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople.JOB_TITLE + "," +
                        directoryPeople.PEOPLE_TABLE + "."
                        + directoryPeople._ID
                ;

                Cursor c = queryBuilder.query(mDB, asColumnsToReturn, directoryPeople.LAST_NAME + " LIKE " + partialValue, null,
                        null, null, directoryPeople.DEFAULT_SORT_ORDER);


                return c;
            
        );

根据要求,这是我的布局代码。主要布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:background="@android:color/white">
    <include android:id="@+id/lytHeadBar" layout="@layout/headbar" />
    <include android:id="@+id/lytTitleBar" layout="@layout/titlebar" />
    <EditText android:layout_
        android:layout_
        android:hint="Type a name..."
        android:maxLines="1" android:inputType="textFilter|textCapWords" android:id="@+id/search_box"/>
    <ListView
        android:layout_
        android:layout_
        android:id="@+id/listPeople"
        android:divider="@android:drawable/divider_horizontal_dark"
        android:cacheColorHint="@android:color/white" />
</LinearLayout>

列表项布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lytItem"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:background="@drawable/item_line_bottom">
    <LinearLayout android:id="@+id/nameLine"
        android:layout_
        android:layout_
        android:orientation="horizontal">
            <TextView
                android:id="@+id/txtLastName"
                android:layout_
                android:layout_
                android:textSize="20sp"
                android:textStyle="bold"
                android:textColor="@android:color/black"
                android:text="lastname" />
            <TextView
                android:id="@+id/nameSpace1"
                android:layout_
                android:layout_
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text=", " />
            <TextView
                android:id="@+id/txtFirstName"
                android:layout_
                android:layout_
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text="firstname" />
            <TextView
                android:id="@+id/nameSpace2"
                android:layout_
                android:layout_
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text=" " />
            <TextView
                android:id="@+id/txtMiddle"
                android:layout_
                android:layout_
                android:textStyle="bold"
                android:textSize="20sp"
                android:textColor="@android:color/black"
                android:text="middle" />    
        </LinearLayout>
    <LinearLayout android:id="@+id/titleLine"
        android:layout_
        android:layout_
        android:orientation="horizontal">
        <TextView
            android:id="@+id/txtTitle"
            android:layout_
            android:layout_
            android:textSize="16sp"
            android:textColor="@android:color/black"
            android:text="title" android:ellipsize="marquee"/>
    </LinearLayout>
</LinearLayout>

【问题讨论】:

【参考方案1】:

它更像是 arrayAdapter 这是示例代码

public class ListViewFilter extends Activity 
private ItemDatabaseHelper itemData;
private SimpleCursorAdapter sc;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    itemData=new ItemDatabaseHelper(this);
    Cursor c=itemData.getAllValues(); 

    sc=new 
        SimpleCursorAdapter(this, R.layout.list_items, c, new String[]itemData.VALUE, new int[]R.id.txtItem);
    ListView lv=(ListView)findViewById(R.id.lstItems);
    lv.setAdapter(sc);
    sc.setFilterQueryProvider(new FilterQueryProvider() 

        @Override
        public Cursor runQuery(CharSequence constraint) 
            String partialValue = constraint.toString();
            return itemData.getAllSuggestedValues(partialValue);

        
    );
    EditText etext=(EditText)findViewById(R.id.etxtItemName);
    etext.addTextChangedListener(new TextWatcher() 

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) 


        

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) 


        

        @Override
        public void afterTextChanged(Editable s) 
            sc.getFilter().filter(s.toString());

        
    );

下面列出了两个xml文件

main.xml 是

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    >
<EditText  
    android:layout_ 
    android:layout_ 
    android:id="@+id/etxtItemName"
    android:layout_alignParentTop="true"
    />
<ListView
    android:layout_
    android:layout_
    android:id="@+id/lstItems"
    android:layout_below="@+id/etxtItemName"
    />
</RelativeLayout>

list_item.xml 是

  <?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/txtItem"
  android:layout_
  android:layout_>
</TextView>

希望对你有帮助

【讨论】:

我的数据库助手中没有getAllSuggestedValues() 方法。我该如何实现? 我也没有getAllValues。我只是在这个类中直接实现我的查询。我已经尝试为此调整您的示例,但无论我输入什么,我的 ListView 仍然只显示所有内容。我会用我的代码更新我的问题。 你可以使用“Like”+partialValue +“%”来代替“Like”+partialValue 不幸的是,仍然没有运气。可能是因为我的列表项太复杂了?它在两个 LinearLayout 中有 4 个 TextView。不过,我不明白为什么这很重要。 Itemdatabasehelper指的是哪个类?【参考方案2】:

终于解决了这个问题!答案可以在这里找到:ListView, SimpleCursorAdapter, an an EditText filter -- why won't it do anything?

【讨论】:

以上是关于使用 EditText 过滤 SimpleCursorAdapter 支持的 ListView的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义列表视图在edittext过滤器中获取空间?可以使用简单的适配器吗?

RecyclerView列表搜索(过滤)EditText问题

在android中的EditText上输入时如何过滤ListView数据

Android listview edittext过滤空间按钮?

使用自定义(对象)适配器过滤 ListView

将EditText过滤器设置为自定义范围内的数字