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

Posted

技术标签:

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

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

【问题讨论】:

认为我的解决方案可能正是您正在寻找的! ***.com/questions/1737009/…> Johe,看这里,解释很清楚。 ***.com/questions/1901020/… Read this 一个不错的解决方案。 【参考方案1】:
    TextWatcher 添加到EditText#addTextChangedListeneronTextChanged 中从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_
    android:layout_ >

    <EditText
        android:layout_
        android:layout_
        android:id="@+id/txt_search"
        tools:context=".SearchAndFilterList"
        android:hint="Enter text to search" />
    <ListView 
        android:layout_
        android:layout_
        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_
    android:layout_ >
    <TextView 
        android:layout_
        android:layout_
        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 )

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

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

    创建一个新的列表适配器并用满足过滤器的项目填充它或 拥有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 指出的那样,如果您按退格键删除将不会回来。你不应该重新发明***。

以上是关于在android中的EditText上输入时如何过滤ListView数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中禁用 EditText

android中的格式化EditText

android中的EditText在输入文本时回到顶部布局

ListView 中的 EditText 没有它回收输入

如何在 android 中动态更改 EditText 小部件的文本大小?

如何在Android Studio中对包含数值的EditText字段执行基本计算