键入时 Android 搜索列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2374177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:35:43  来源:igfitidea点击:

Android search list while typing

androidsearchandroid-listview

提问by xger86x

How can I build a search bar where while I'm typing the results are shown in the ListViewin which I'm searching?

我怎样才能建立一个搜索栏,当我输入时,结果会显示在ListView我正在搜索的位置?

For example, I have a list view with 20 strings. I press the search key and appears the bar. I want when I type 3 words or more the search starts running showing the results in the list view (as a filter: only shows the strings in the list that matching what I type)

例如,我有一个包含 20 个字符串的列表视图。我按下搜索键并出现栏。我希望当我输入 3 个或更多单词时,搜索开始运行,在列表视图中显示结果(作为过滤器:只显示列表中与我输入的内容匹配的字符串)

采纳答案by Janusz

You can't do this with the search bar. But the listview has a possibility to filter on key pressed, like it is done in the contacts. The user simply starts typing and the list gets filtered then. Filtering is not really like searching. If you list contains the word foo somewhere and you type oo foo will be filtered out, but if you type fo it will stay even if the list item is call bar foo.

您无法使用搜索栏执行此操作。但是 listview 有可能对 keypress 进行过滤,就像在联系人中所做的那样。用户只需开始输入,然后列表就会被过滤。过滤并不像搜索。如果您的列表在某处包含单词 foo 并且您键入 oo foo 将被过滤掉,但是如果您键入 fo 它会保留,即使列表项是 call bar foo。

You simply have to enable it:

您只需启用它:

ListView lv = getListView();
lv.setTextFilterEnabled(true);

I don't know how this is done if you don't have a hardware keyboard. I'm using the droid and starting to type starts the list to filter and to show only matching results.

如果您没有硬件键盘,我不知道这是如何完成的。我正在使用 droid 并开始键入启动列表以进行过滤并仅显示匹配的结果。

回答by edst

I believe this is what you are looking for:

我相信这就是你要找的:

http://www.java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

http://www.java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

Have your Activity implement SearchView.OnQueryTextListener

让你的 Activity 实现 SearchView.OnQueryTextListener

and add the following methods:

并添加以下方法:

public boolean onQueryTextChange(String newText) {
    if (TextUtils.isEmpty(newText)) {
        mListView.clearTextFilter();
    } else {
        mListView.setFilterText(newText.toString());
    }
    return true;
}

public boolean onQueryTextSubmit(String query) {
    return false;
}

回答by Gareth

I used an EditTextto do the job.

我用 anEditText来完成这项工作。

First I created two copies of the array to hold the list of data to search:

首先,我创建了数组的两个副本来保存要搜索的数据列表:

List<Map<String,String>> vehicleinfo;
List<Map<String,String>> vehicleinfodisplay;

Once I've got my list data from somewhere, I copy it:

从某处获得列表数据后,我将其复制:

for(Map<String,String>map : vehicleinfo)
{
    vehicleinfodisplay.add(map);
}

and use a SimpleAdapterto display the display (copied) version of my data:

并使用 aSimpleAdapter显示我的数据的显示(复制)版本:

String[] from={"vehicle","dateon","dateoff","reg"};
int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg};
listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to);
vehiclelist.setAdapter(listadapter);

Then I added a TextWatcherto the EditTextwhich responds to an afterTextChangedevent by clearing the display version of the list and then adding back only the items from the other list that meet the search criteria (in this case the "reg" field contains the search string). Once the display list is populated with the filtered list, I just call notifyDataSetChangedon the list's SimpleAdapter.

然后,我通过清除列表的显示版本,然后仅添加回另一个列表中满足搜索条件的项目(在这种情况下,“reg”字段包含搜索字符串)TextWatcher来向EditText响应afterTextChanged事件添加 a 。一旦显示列表填充了过滤列表,我只需调用notifyDataSetChanged列表的SimpleAdapter.

searchbox.addTextChangedListener(new TextWatcher()
{
    @Override
    public void afterTextChanged(Editable s)
    {
        vehicleinfodisplay.clear();
        String search=s.toString();
        for(Map<String,String>map : vehicleinfo)
        {
            if(map.get("reg").toLowerCase().contains(search.toLowerCase()))
                vehicleinfodisplay.add(map);
            listadapter.notifyDataSetChanged();
        }
    };
    ... other overridden methods can go here ...
});

Hope this is helpful to someone.

希望这对某人有帮助。

回答by Mahesh

Use following code to implement search and filter list in android:

使用以下代码在android中实现搜索和过滤列表:

SearchAndFilterList.java

SearchAndFilterList.java

public class SearchAndFilterList extends Activity {

    private ListView mSearchNFilterLv;

    private EditText mSearchEdt;

    private ArrayList<String> mStringList;

    private ValueAdapter valueAdapter;

    private TextWatcher mSearchTw;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_search_and_filter_list);

        initUI();

        initData();

        valueAdapter=new ValueAdapter(mStringList,this);

        mSearchNFilterLv.setAdapter(valueAdapter);

        mSearchEdt.addTextChangedListener(mSearchTw);


    }
    private void initData() {

        mStringList=new ArrayList<String>();

        mStringList.add("one");

        mStringList.add("two");

        mStringList.add("three");

        mStringList.add("four");

        mStringList.add("five");

        mStringList.add("six");

        mStringList.add("seven");

        mStringList.add("eight");

        mStringList.add("nine");

        mStringList.add("ten");

        mStringList.add("eleven");

        mStringList.add("twelve");

        mStringList.add("thirteen");

        mStringList.add("fourteen");

        mSearchTw=new TextWatcher() {

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

                valueAdapter.getFilter().filter(s);
            }

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

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        };

    }

    private void initUI() {

        mSearchNFilterLv=(ListView) findViewById(R.id.list_view);

        mSearchEdt=(EditText) findViewById(R.id.txt_search);
    }

}

Custom Value adapter: ValueAdapter.java

自定义值适配器: ValueAdapter.java

public class ValueAdapter extends BaseAdapter implements Filterable{

    private ArrayList<String> mStringList;

    private ArrayList<String> mStringFilterList;

    private LayoutInflater mInflater;

    private ValueFilter valueFilter;

    public ValueAdapter(ArrayList<String> mStringList,Context context) {

        this.mStringList=mStringList;

        this.mStringFilterList=mStringList;

        mInflater=LayoutInflater.from(context);

        getFilter();
    }

    //How many items are in the data set represented by this Adapter.
    @Override
    public int getCount() {

        return mStringList.size();
    }

    //Get the data item associated with the specified position in the data set.
    @Override
    public Object getItem(int position) {

        return mStringList.get(position);
    }

    //Get the row id associated with the specified position in the list.
    @Override
    public long getItemId(int position) {

        return position;
    }

    //Get a View that displays the data at the specified position in the data set.
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Holder viewHolder;

        if(convertView==null) {

            viewHolder=new Holder();

            convertView=mInflater.inflate(R.layout.list_item,null);

            viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem);

            convertView.setTag(viewHolder);

        }else{

            viewHolder=(Holder)convertView.getTag();
        }

            viewHolder.nameTv.setText(mStringList.get(position).toString());

            return convertView;
    }

    private class  Holder{

        TextView nameTv;
    }

    //Returns a filter that can be used to constrain data with a filtering pattern.
    @Override
    public Filter getFilter() {

        if(valueFilter==null) {

            valueFilter=new ValueFilter();
        }

        return valueFilter;
    }


    private class ValueFilter extends Filter {


        //Invoked in a worker thread to filter the data according to the constraint.
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results=new FilterResults();

            if(constraint!=null && constraint.length()>0){

                ArrayList<String> filterList=new ArrayList<String>();

                for(int i=0;i<mStringFilterList.size();i++){

                    if(mStringFilterList.get(i).contains(constraint)) {

                        filterList.add(mStringFilterList.get(i));

                    }
                }


                results.count=filterList.size();

                results.values=filterList;

            }else{

                results.count=mStringFilterList.size();

                results.values=mStringFilterList;

            }

            return results;
        }


        //Invoked in the UI thread to publish the filtering results in the user interface.
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            mStringList=(ArrayList<String>) results.values;

            notifyDataSetChanged();


        }

    }

}

activity_search_and_filter_list.xml

activity_search_and_filter_list.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txt_search"
        tools:context=".SearchAndFilterList"
        android:hint="Enter text to search" />
    <ListView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/list_view"
        android:layout_below="@+id/txt_search"></ListView>

</RelativeLayout>

list_item.xml

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txt_listitem"/>

</RelativeLayout>

AndroidManifext.xml

AndroidManifext.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.searchandfilterlistview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SearchAndFilterList"
            android:label="@string/title_activity_search_and_filter_list" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I hope this code will will helpful to implement custom search and filter listview

我希望这段代码有助于实现自定义搜索和过滤列表视图

回答by Patrick Kafka

The best way is to use the built in search bar or SearchManager by overriding onSearchRequested in a searchable activity. You can set a datasource to search on to get the automatic drop down of results or you can just take in the input from the user and search after. Here is a good overview of SearchManageris a Plus there is a working demo in the API Demos project com.example.android.apis.app.SearchQueryResult

最好的方法是通过覆盖可搜索活动中的 onSearchRequested 来使用内置搜索栏或 SearchManager。您可以设置要搜索的数据源以获取结果的自动下拉列表,或者您可以只接收用户的输入并进行搜索。这是对SearchManager 的一个很好的概述,另外在 API Demos 项目com.example.android.apis.app.SearchQueryResult 中有一个工作演示

@Override
public boolean onSearchRequested() {