【问题标题】:android - search listview?android - 搜索列表视图?
【发布时间】:2011-04-02 18:38:50
【问题描述】:

Android 是否可以为 ListView 设置一个搜索栏,以便在触摸搜索栏时弹出键盘,并且在搜索栏中输入文本时,显示 ListView 中匹配的项目?

我真正需要的是带键盘的搜索栏。

更新:

我添加了 EditText 字段,该字段可以调出键盘,我可以在 EditText 字段中输入内容。我想要的是让 ListView 中显示的列表中项目的前几个字符与输入到 EditText 窗口中的字符匹配。

我已经尝试按照此处列出的方法ListView Filter,但对于 ListView 中已经完成了多少过滤,我有点困惑?

1) 我是否需要创建一个单独的数组来存储与键入到 EditText 中的文本匹配的值?从这篇文章Call adapter.notifyDataSetChanged 看来,ListView 已经有一个影子数组来执行此操作,并且它会在 adapter.notifyDataSetChanged(); 时更新。被调用。

2) 我需要调用 adapter.notifyDataSetChanged();在 EditText 窗口中键入一些文本后更新 ListView?

3) 我是否需要像 post 所指示的那样扩展 ListActivity?如果是这样,如果活动类已经从主活动扩展,我该如何扩展我的活动类?

4) 我目前拥有的如下:

ArrayAdapter<String> adapter = null;
private EditText filterText = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.symptom);
    ListView symptomList = (ListView) findViewById(R.id.ListView_Symptom);
    symptomList.setTextFilterEnabled(true);
    symptomList.setFastScrollEnabled(true);
    filterText = (EditText) findViewById(R.id.search_box);
    filterText.addTextChangedListener(filterTextWatcher);

    adapter = new ArrayAdapter<String>(this, R.layout.menu_item, symptomsArray);
    symptomList.setAdapter(adapter);

    private TextWatcher filterTextWatcher = new TextWatcher() {

        public void afterTextChanged(Editable s) {
        }

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

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            adapter.getFilter().filter(s);
            adapter.notifyDataSetChanged();
        }

    };

不幸的是,当我在 EditText 框中键入时,我在

中得到一个 NullPointer 异常
 Thread [<7> Filter] (Suspended (exception NullPointerException))   
ArrayAdapter$ArrayFilter.performFiltering(CharSequence) line: 437   
Filter$RequestHandler.handleMessage(Message) line: 234  
Filter$RequestHandler(Handler).dispatchMessage(Message) line: 99    
Looper.loop() line: 123 
HandlerThread.run() line: 60    

知道我错过了什么吗?

【问题讨论】:

    标签: android


    【解决方案1】:

    您犯了一个非常小的错误:- 在将文本更改侦听器设置为编辑文本之前创建数组适配器

    查看更正后的代码

    public class SearchListView extends Activity
    {
    
    
    /** Called when the activity is first created. */
    
    private ListView lv1;
    private String lv_arr[] =
    { "Android", "iPhone", "BlackBerry", "me", "J2ME", "Listview", "ArrayAdapter", "ListItem", "Us", "UK", "India" };
    ListView lst;
    EditText edt;
    ArrayAdapter<String> arrad;
    
    
    
    @Override
    public void onCreate( Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
    
        lv1=(ListView)findViewById(R.id.ListView01);
        edt = (EditText) findViewById(R.id.EditText01);
    
         arrad =  new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1 , lv_arr);
         lv1.setAdapter(arrad);
    
        // By using setTextFilterEnabled method in listview we can filter the listview items.
    
         lv1.setTextFilterEnabled(true);
         edt.addTextChangedListener(new TextWatcher()
        {
    
    
            @Override
            public void onTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub
    
            }
    
    
    
            @Override
            public void beforeTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub
    
            }
    
    
    
            @Override
            public void afterTextChanged( Editable arg0)
            {
                // TODO Auto-generated method stub
                SearchListView.this.arrad.getFilter().filter(arg0);
    
            }
        });
    
    }
    

    }

    【讨论】:

      【解决方案2】:

      如果您在适配器中实现Filterable,则为ListView can handle the filtering

      【讨论】:

      【解决方案3】:

      作为另一种方法,ListView 本身可以显示用户正在输入的文本(而不是使用单独的 TextView),方法是处理 onKeyUp 事件,将 ListView 滚动到具有输入文本的项目,并在其下划线ListView 中的文本。我使用 AsyncTask 来实现 ListView 文本搜索,这会产生一种方便的提前输入功能。

      【讨论】:

        【解决方案4】:

        此页面有您正在寻找的工作示例 http://learningsolo.com/android-text-search-filter-with-textwatcher-in-listview-example/

        在应用栏布局中添加搜索框:

        <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay">
        
        <!-- To add Search Text box to action bar -->
                <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay">
                    <EditText android:layout_width="200dp" android:layout_height="wrap_content" android:id="@+id/searchProjectTxt" android:layout_marginLeft="30dp" android:singleLine="true" android:hint="Search Here..." />
                </android.support.v7.widget.Toolbar>
        
            </android.support.design.widget.AppBarLayout>
        

        然后在“searchProjectTxt”上添加TextWatcher来添加过滤器

        EditText searchTxt = (EditText)findViewById(R.id.searchProjectTxt);
        searchTxt.addTextChangedListener(new TextWatcher() {
        
                    @Override
                    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                        // When user changed the Text
                        filter(cs.toString());
                    }
        
                    @Override
                    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                                  int arg3) {
                    }
        
                    @Override
                    public void afterTextChanged(Editable arg0) {
                    }
                });
            }
        
            void filter(String text){
                List<ProjectsVo> temp = new ArrayList();
                for(ProjectsVo d: projectListCache){
                    if(d.getTitle().toLowerCase().contains(text.toLowerCase())){
                        temp.add(d);
                    }
                }
                projectList.clear();
                projectList.addAll(temp);
                adapter.notifyDataSetChanged();
            }
        

        【讨论】:

          猜你喜欢
          • 2011-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-11
          • 1970-01-01
          • 2013-05-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多