【问题标题】:How can I filter ListView data when typing on EditText in android在android中的EditText上输入时如何过滤ListView数据
【发布时间】:2010-12-11 08:09:34
【问题描述】:

我有一个ListView 和一个EditText。在EditText 上键入时如何过滤 ListView 数据?

【问题讨论】:

标签: android


【解决方案1】:
  1. TextWatcher 添加到EditText#addTextChangedListener
  2. onTextChanged 中从ListView 的适配器中添加或删除项目。如果您将 ArrayAdapter 子类化,它将具有 addremove 方法

【讨论】:

    【解决方案2】:

    是的,您可以,只需实现此代码即可。使用以下代码在android中实现搜索和过滤列表:

    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);
        }
    
    }
    

    自定义值适配器: 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

    <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

    <?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

    <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>
    

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

    【讨论】:

    • 在 afterTextChanged() 中调用 adapter.getFilter().filter(s)
    【解决方案3】:

    你可以使用:

    http://developer.android.com/reference/android/widget/TextView.html

    addTextChangedListener( TextWatcher watcher )

    找出文本视图何时更改。我相信每次添加或删除字母时都应该调用它。

    然后更新您的列表适配器以显示新项目:

    1. 创建一个新的列表适配器并用满足过滤器的项目填充它或
    2. 拥有BaseAdapter 的子类来接受您的过滤器,并在它完成删除您不再需要的项目后调用notifyDataSetChanged()

    http://developer.android.com/reference/android/widget/BaseAdapter.html

    【讨论】:

    • 所以你的意思是TextView?我正在使用 EditText。反正我觉得对我也有用!谢谢!
    • 对不起。幸运的是,EditText 是 TextView 的子类并且仍然是相关的。我很高兴它有所帮助。
    【解决方案4】:

    根据 EditText 中的输入搜索列表视图

         public class MainActivity extends Activity {
    private ListView lv,lv2;
    private EditText et;
    String listview_array[]={"01634 ABOHAR","080 Bangalore","011 Delhi","Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "1234", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"};
    private ArrayList<String> array_sort = new ArrayList<String>();
    int textlength = 0;
    
    public void onCreate(Bundle savedInstanceState)
    
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.ListView01);
        lv2 = (ListView) findViewById(R.id.ListView02);
        et = (EditText) findViewById(R.id.EditText01);
        lv.setAdapter(new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, listview_array));
        int x= lv.getHeaderViewsCount ();
        System.out.println("x========"+x);
        lv.setAdapter(new ArrayAdapter<String>
        (MainActivity.this,
        android.R.layout.simple_list_item_1, listview_array));
    
        et.addTextChangedListener(new TextWatcher()
        {
            public void afterTextChanged(Editable s)
            {
                // Abstract Method of TextWatcher Interface.
    
            }
            public void beforeTextChanged(CharSequence s,
            int start, int count, int after)
            {
    
                // Abstract Method of TextWatcher Interface.
    
            }
            public void onTextChanged(CharSequence s,
            int start, int before, int count)
            {
                textlength = et.getText().length();
                array_sort.clear();
                for (int i = 0; i < listview_array.length; i++)
                {
                    if (textlength <= listview_array[i].length())
                    {
    
                        String s2= et.getText().toString();
                        if(listview_array[i].toString().contains(et.getText().toString()))
                        {
                            array_sort.add(listview_array[i]);
                        }
    
    
                    }
                }
    
                lv.setAdapter(new ArrayAdapter<String>
                (MainActivity.this,
                android.R.layout.simple_list_item_1, array_sort));
            }
        });
    
    }
     }
    

    对于基于类项的自定义列表视图中的搜索,请参阅链接implement search on a custom listview。根据您的需要进行修改。

    【讨论】:

    • 我的是自定义 ListView,即使在那之后,onTextChanged() 中的代码运行良好。
    【解决方案5】:

    当你使用自定义列表视图时

    适配器:

    public class Adapter extends ArrayAdapter {
    ArrayList<String> list = new ArrayList<>();
    ArrayList<String> filteredData = new ArrayList<>();
    
    public Adapter(@NonNull Context context, int resource) {
        super(context, resource);
    }
    
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    
        LayoutInflater inflate = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        @SuppressLint("ViewHolder") View vi = inflate.inflate(R.layout.ly_items, null);
        try {
            JSONObject js = new JSONObject(list.get(position));
            TextView txtItem = vi.findViewById(R.id.txtItem);
            ImageView imgItem = vi.findViewById(R.id.imgItem);
            txtItem.setText(js.getString("name") + " - " + js.getInt("number"));
            Picasso.get().load(js.getString("logo_url")).into(imgItem);
    
        } catch (JSONException e) {
            e.printStackTrace();
        }
    
        return vi;
    }
    
    @Override
    public void add(@Nullable Object object) {
        super.add(object);
        list.add(object.toString());
        filteredData.add(object.toString());
    }
    
    @Override
    public int getCount() {
        return list.size();
    }
    
    @Nullable
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }
    
    
    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        list.clear();
        if (charText.length() == 0) {
            list.addAll(filteredData);
        } else {
            for (String wp : filteredData) {
    
                try {
                    JSONObject json = new JSONObject(wp);
                    if (json.getString("name").toLowerCase().contains(charText) || json.getString("number").contains(charText)) {
                        list.add(wp);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
        notifyDataSetChanged();
        }
    }
    

    还有你的班级:

     Adapter adapter;
    ListView list;
    EditText edtSearch;
    
     @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    list = findViewById(R.id.list);
    
    edtSearch = findViewById(R.id.edtSearch);
    
     adapter = new Adapter(this, android.R.layout.simple_list_item_1);
    
    
    list.setAdapter(adapter);
    
    edtSearch.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    adapter.filter(s.toString());
                }
    
                @Override
                public void afterTextChanged(Editable s) {
                }
            });
    
        }
    

    【讨论】:

      【解决方案6】:

      1) 为您的列表视图创建一个自定义适配器并创建一个 removeIfMatch(String s) 方法:

      public void removeIfMatch(String s) {
        for item in adapter:
          if item.matches(s) {
             data.removeItem(item);
             notifyDataSetChanged();
             break
          }
      }
      

      2) 当 EditText 内容改变时创建回调

      3) 调用 adapter.removeIfMatch(editText.getText())

      【讨论】:

      • 如果有人输入过多然后按退格键会怎样?
      • 已有过滤器设施。您的解决方案会更改列表中的数据。就像 fixedd 指出的那样,如果您按退格键删除将不会回来。你不应该重新发明轮子。
      猜你喜欢
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      相关资源
      最近更新 更多