带有过滤器 Android 的自定义 Listview 适配器

Posted

技术标签:

【中文标题】带有过滤器 Android 的自定义 Listview 适配器【英文标题】:Custom Listview Adapter with filter Android 【发布时间】:2014-09-06 07:13:39 【问题描述】:

请尝试在我的列表视图上实施过滤器。但是每当文本更改时,列表就会消失。请帮助 这是我的代码。适配器类。

package com.talagbe.schymn;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class HymnsAdapter extends ArrayAdapter<Hymns> 
ArrayList<Hymns> hymnarray;
Context context;
LayoutInflater inflater;
int Resource;


public HymnsAdapter(Context context, int resource, ArrayList<Hymns> objects) 
    super(context, resource, objects);
    // TODO Auto-generated constructor stub

    hymnarray=objects;
    Resource= resource;
    this.context=context;
    inflater= (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);



@Override
public View getView(int position, View convertView, ViewGroup parent) 
    // TODO Auto-generated method stub
     ViewHolder holder;
     if(convertView==null)

         convertView= inflater.inflate(Resource,null);
         holder= new ViewHolder();
         holder.hymntitle= (TextView) convertView.findViewById(R.id.Hymn_title);
        // holder.hymntext= (TextView) convertView.findViewById(R.id.Channel_name);


         convertView.setTag(holder);

     else
         holder=(ViewHolder)convertView.getTag();
     

     holder.hymntitle.setText(hymnarray.get(position).getTitle());
     //holder.hymntext.setText(hymnarray.get(position).getText());

    return convertView;





   static class ViewHolder

    public TextView hymntitle;
    public TextView hymntext;



 

这是我尝试实现过滤器的另一个类。我有一个编辑文本,我在 textChangeListener 上实现

package com.talagbe.schymn;

import java.util.ArrayList;

import database.DatabaseHelper;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.AdapterView.OnItemClickListener;

 public class Home extends Fragment 

    private static final String DB_NAME = "schymn.sqlite";
    private static final String TABLE_NAME = "Hymns";
    private static final String Hymn_ID = "_id";
    private static final String Hymn_Title = "Title";
    private static final String Hymn_Text = "Text";
    private SQLiteDatabase database;

ListView list;
EditText search;
HymnsAdapter vadapter;
ArrayList<Hymns> HymnsList;
String url;
Context context=null;


public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    // TODO Auto-generated method stub
      return inflater.inflate(R.layout.index, container,false);



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

    list = (ListView)getActivity().findViewById(R.id.hymn_list);
    search = (EditText) getActivity().findViewById(R.id.search);
    HymnsList = new ArrayList<Hymns>();

    DatabaseHelper dbOpenHelper = new DatabaseHelper(getActivity(), DB_NAME);
    database = dbOpenHelper.openDataBase();

    fillHymns();
    //setUpList();





private void fillHymns() 
    Cursor hymnCursor = database.query(TABLE_NAME,
                                         new String[] 
                                         Hymn_ID, Hymn_Title,Hymn_Text,
                                         null, null, null, null
                                         , Hymn_Title);
    hymnCursor.moveToFirst();
    if(!hymnCursor.isAfterLast()) 
        do 
            Hymns hy = new Hymns();
            hy.setTitle(hymnCursor.getString(1));
            hy.setText(hymnCursor.getString(2));
            HymnsList.add(hy);

         while (hymnCursor.moveToNext());
    
    hymnCursor.close();
     vadapter = new HymnsAdapter(getActivity().getApplicationContext(),R.layout.hymns,HymnsList);
    list.setAdapter(vadapter);

    list.setOnItemClickListener(new OnItemClickListener() 
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) 

            Intent intent = new Intent(getActivity().getApplicationContext(), Hymn_Text.class);
            intent.putExtra("Title",HymnsList.get(position).getTitle());
            intent.putExtra("Text",HymnsList.get(position).getText());
            startActivity(intent);
            //Log.i("Text",HymnsList.get(position).getText());

        








    );


    search.addTextChangedListener( new TextWatcher() 

        @Override
        public void onTextChanged(CharSequence cs, int start, int before, int count) 
            // TODO Auto-generated method stub
            if(count>0)


            

        

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) 
            // TODO Auto-generated method stub

        

        @Override
        public void afterTextChanged(Editable s) 
            // TODO Auto-generated method stub
             Home.this.vadapter.getFilter().filter(s);
                Log.i("Changed",s.toString());
        
    );





  

日志,记录我输入的任何输入,但不显示列表视图。谢谢你

【问题讨论】:

【参考方案1】:

您可以在适配器上使用Filterable 接口,请看下面的示例:

public class SearchableAdapter extends BaseAdapter implements Filterable 
    
    private List<String>originalData = null;
    private List<String>filteredData = null;
    private LayoutInflater mInflater;
    private ItemFilter mFilter = new ItemFilter();
    
    public SearchableAdapter(Context context, List<String> data) 
        this.filteredData = data ;
        this.originalData = data ;
        mInflater = LayoutInflater.from(context);
    
 
    public int getCount() 
        return filteredData.size();
    
 
    public Object getItem(int position) 
        return filteredData.get(position);
    
 
    public long getItemId(int position) 
        return position;
    
 
    public View getView(int position, View convertView, ViewGroup parent) 
        // A ViewHolder keeps references to children views to avoid unnecessary calls
        // to findViewById() on each row.
        ViewHolder holder;
 
        // When convertView is not null, we can reuse it directly, there is no need
        // to reinflate it. We only inflate a new View when the convertView supplied
        // by ListView is null.
        if (convertView == null) 
            convertView = mInflater.inflate(R.layout.list_item, null);
 
            // Creates a ViewHolder and store references to the two children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.list_view);
 
            // Bind the data efficiently with the holder.
 
            convertView.setTag(holder);
         else 
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        
 
        // If weren't re-ordering this you could rely on what you set last time
        holder.text.setText(filteredData.get(position));
 
        return convertView;
    
    
    static class ViewHolder 
        TextView text;
    
 
    public Filter getFilter() 
        return mFilter;
    
 
    private class ItemFilter extends Filter 
        @Override
        protected FilterResults performFiltering(CharSequence constraint) 
            
            String filterString = constraint.toString().toLowerCase();
            
            FilterResults results = new FilterResults();
            
            final List<String> list = originalData;
 
            int count = list.size();
            final ArrayList<String> nlist = new ArrayList<String>(count);
 
            String filterableString ;
            
            for (int i = 0; i < count; i++) 
                filterableString = list.get(i);
                if (filterableString.toLowerCase().contains(filterString)) 
                    nlist.add(filterableString);
                
            
            
            results.values = nlist;
            results.count = nlist.size();
 
            return results;
        
 
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) 
            filteredData = (ArrayList<String>) results.values;
            notifyDataSetChanged();
        
 
    

在您实例化适配器的 Activity 或 Fragment 中:

editTxt.addTextChangedListener(new TextWatcher() 
  
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) 
        System.out.println("Text ["+s+"]");
        
        mSearchableAdapter.getFilter().filter(s.toString());                           
    
     
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) 
         
    
     
    @Override
    public void afterTextChanged(Editable s) 
    
);

这里是original source 和another example 的链接

【讨论】:

谢谢@Andre。它可以工作,但我无法将过滤结果的内容传递给另一个活动。你能帮忙吗?(当我过滤时,listview的onclick事件不会改变原始内容) @olakunle,过滤后你的列表继续显示之前的数据,是吗? @anderson_acs 你能看看这个问题吗,我试着看看你的答案。我需要你的帮助来纠正这个问题。请看看这个。 ***.com/questions/29340403/… @AndersonCSilva 你能解释一下Filterable接口的用途吗 @Anderson Kxiasss..你能看看这个..how to implement getFilter() on a BaseAdapter.【参考方案2】:

我希望它对其他人有所帮助。

// put below code (method) in Adapter class
public void filter(String charText) 
    charText = charText.toLowerCase(Locale.getDefault());
    myList.clear();
    if (charText.length() == 0) 
        myList.addAll(arraylist);
    
    else
    
        for (MyBean wp : arraylist) 
            if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) 
                myList.add(wp);
            
        
    
    notifyDataSetChanged();

在适配器类中声明以下代码

private ArrayList<MyBean> myList;  // for loading main list
private ArrayList<MyBean> arraylist=null;  // for loading  filter data

适配器构造函数中的以下代码

this.arraylist = new ArrayList<MyBean>();
    this.arraylist.addAll(myList);

您的活动类中的以下代码

final EditText searchET = (EditText)findViewById(R.id.search_et);
    // Capture Text in EditText
    searchET.addTextChangedListener(new TextWatcher() 

        @Override
        public void afterTextChanged(Editable arg0) 
            // TODO Auto-generated method stub
            String text = searchET.getText().toString().toLowerCase(Locale.getDefault());
            adapter.filter(text);
        

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1,
                                      int arg2, int arg3) 
            // TODO Auto-generated method stub
        

        @Override
        public void onTextChanged(CharSequence arg0, int arg1, int arg2,
                                  int arg3) 
            // TODO Auto-generated method stub
        
    );

【讨论】:

这是最好的方法 ))) 非常简单【参考方案3】:

在您的 CustomAdapter 类中实现可过滤。

 public class CustomAdapter extends BaseAdapter implements Filterable 

    private List<ItemsModel> itemsModelsl;
    private List<ItemsModel> itemsModelListFiltered;
    private Context context;

    public CustomAdapter(List<ItemsModel> itemsModelsl, Context context) 
        this.itemsModelsl = itemsModelsl;
        this.itemsModelListFiltered = itemsModelsl;
        this.context = context;
    



    @Override
    public int getCount() 
        return itemsModelListFiltered.size();
    

    @Override
    public Object getItem(int position) 
        return itemsModelListFiltered.get(position);
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 
        View view = getLayoutInflater().inflate(R.layout.row_items,null);


        TextView names = view.findViewById(R.id.name);
        TextView emails = view.findViewById(R.id.email);
        ImageView imageView = view.findViewById(R.id.images);

        names.setText(itemsModelListFiltered.get(position).getName());
        emails.setText(itemsModelListFiltered.get(position).getEmail());
        imageView.setImageResource(itemsModelListFiltered.get(position).getImages());

        view.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Log.e("main activity","item clicked");
                startActivity(new Intent(MainActivity.this,ItemsPreviewActivity.class).putExtra("items",itemsModelListFiltered.get(position)));

            
        );

        return view;
    



    @Override
    public Filter getFilter() 
        Filter filter = new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence constraint) 

                FilterResults filterResults = new FilterResults();
                if(constraint == null || constraint.length() == 0)
                    filterResults.count = itemsModelsl.size();
                    filterResults.values = itemsModelsl;

                else
                    List<ItemsModel> resultsModel = new ArrayList<>();
                    String searchStr = constraint.toString().toLowerCase();

                    for(ItemsModel itemsModel:itemsModelsl)
                        if(itemsModel.getName().contains(searchStr) || itemsModel.getEmail().contains(searchStr))
                            resultsModel.add(itemsModel);

                        
                         filterResults.count = resultsModel.size();
                            filterResults.values = resultsModel;
                    


                

                return filterResults;
            

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) 

                itemsModelListFiltered = (List<ItemsModel>) results.values;
                notifyDataSetChanged();

            
        ;
        return filter;
    

您可以在此处获取整个教程: ListView With Search/Filter and OnItemClickListener

Github Source Code

【讨论】:

【参考方案4】:

请查看下面的代码,它会对您有所帮助

DrawerActivity.userListview
            .setOnItemClickListener(new OnItemClickListener() 

                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) 

                    int pos = position;
                    Intent intent = new Intent(getContext(),
                            UserDetail.class);
                    intent.putExtra("model", list.get(position));
                    context.startActivity(intent);
                
            );
    return convertView;


@Override
public android.widget.Filter getFilter() 

    return new android.widget.Filter() 

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) 

            ArrayList<UserListModel> updatelist = (ArrayList<UserListModel>) results.values;
            UserListCustomAdaptor newadaptor = new UserListCustomAdaptor(
                    getContext(), getCount(), updatelist);

            if (results.equals(constraint)) 
                updatelist.add(modelobj);
            
            if (results.count > 0) 
                notifyDataSetChanged();
             else 

                notifyDataSetInvalidated();
            
        

        @Override
        protected FilterResults performFiltering(CharSequence constraint) 

            FilterResults filterResults = new FilterResults();
            list = new ArrayList<UserListModel>();

            if (constraint != null && DrawerActivity.userlist != null) 

                constraint = constraint.toString().toLowerCase();
                int length = DrawerActivity.userlist.size();
                int i = 0;
                while (i < length) 

                    UserListModel modelobj = DrawerActivity.userlist.get(i);
                    String data = modelobj.getFirstName() + " "
                            + modelobj.getLastName();
                    if (data.toLowerCase().contains(constraint.toString())) 
                        list.add(modelobj);
                    

                    i++;
                
                filterResults.values = list;
                filterResults.count = list.size();
            
            return filterResults;
        
    ;


@Override
public int getCount() 
    return list.size();


@Override
public UserListModel getItem(int position) 

    return list.get(position);

【讨论】:

【参考方案5】:

如果你想用kotlin中的自定义模型类实现过滤,那么你可以实现下面的代码。

第 1 步: 在您的xml 文件中添加SearchView,然后在您的activityfragment 中实现SearchView.OnQueryTextListener

class SearchActivity : AppCompatActivity(),SearchView.OnQueryTextListener 


    lateinit var sectionModelArrayList: ArrayList<CategorySectionModel>
    lateinit var filteredArrayList: ArrayList<CategorySectionModel>

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_category_updated)
        searchView.setOnQueryTextListener(this)
    


    //Called this method with you own data to populate the recycler view.
    private fun parseJson() 
        rv_category_list.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
        adapter = CategoryLabelAdapter(sectionModelArrayList, this)
        rv_category_list.adapter = adapter
    

    override fun onQueryTextSubmit(query: String?): Boolean 
        return false
    

    override fun onQueryTextChange(newText: String?): Boolean 
        adapter.filter!!.filter(newText.toString())
        return false
    

我的模型类CategorySectionModel 看起来像

class CategorySectionModel(val categoryLabel: String, val categoryItemList: ArrayList<CategoryItem>)

现在我们必须处理适配器类,您需要实现Filterable 接口并覆盖getFilter() 方法,如下所示

class CategoryLabelAdapter(internal var data: ArrayList<CategorySectionModel>?, internal var activity: Context) : RecyclerView.Adapter<CategoryLabelAdapter.ViewHolder>(), Filterable 
    val originalList = data
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder 
        val v = LayoutInflater.from(parent.context).inflate(R.layout.item_category_name, parent, false)
        return ViewHolder(v)
    

    override fun getItemCount(): Int 
        return data!!.size
    

    override fun onBindViewHolder(holder: ViewHolder, position: Int) 
        data?.get(position)?.let  holder.bindItem(it) 
    


    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) 
        @SuppressLint("SetTextI18n")
        fun bindItem(data: CategorySectionModel) 
            itemView.tv_category_name.text = data.categoryLabel
        
    

    override fun getFilter(): Filter? 
        return object : Filter() 
            override fun performFiltering(constraint: CharSequence): FilterResults 
                val results = FilterResults()
                if (constraint.isEmpty()) 
                    //no filter implemented we return full list
                    results.values = data
                    results.count = data!!.size
                 else 
                    //Here we perform filtering operation
                    val list: ArrayList<CategorySectionModel> = ArrayList()
                    for (p in data!!) 
                        if (p.categoryLabel.toUpperCase().startsWith(constraint.toString().toUpperCase())) list.add(p)
                    
                    results.values = list
                    results.count = list.size
                
                return results
            

            override fun publishResults(constraint: CharSequence, results: FilterResults) 
                // Now we have to inform the adapter about the new list filtered
                if (results.count == 0 || constraint == "") 
                    data = originalList
                    notifyDataSetChanged()
                 else 
                    data = results.values as ArrayList<CategorySectionModel>?
                    notifyDataSetChanged()
                
            
        
    

【讨论】:

【参考方案6】:

首先您在 xml 文件中创建 EditText 并分配一个 id,例如 con_pag_etPesquisa。之后,我们将创建两个列表,其中一个是列表视图,另一个接收相同的内容,但将保留作为备份。 在将对象移动到列表之前,首先将它们初始化如下:

//Declaring

public EditText etPesquisa;

public ContasPagarAdapter adapterNormal;

public List<ContasPagar> lstBkp;

public List<ContasPagar> lstCp;

//Within the onCreate method, type the following:

etPesquisa = (EditText) findViewById(R.id.con_pag_etPesquisa);

etPesquisa.addTextChangedListener(new TextWatcher()

    @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3)
        filter(String.valueOf(cs));
    
    @Override
    public void beforeTextChanged(CharSequence cs, int arg1, int arg2, int arg3)

    // TODO Auto-generated method stub
    
    @Override
    public void afterTextChanged(Editable e)

    

);

//Before moving objects to lists first initializes them as below:

lstCp = new ArrayList<ContasPagar>();

lstBkp = new ArrayList<ContasPagar>();


//When you add objects to the main list, repeat the procedure also for bkp list, as follows:

lstCp.add(cp);

lstBkp.add(cp);


//Now initializes the adapter and let the listener, as follows:

adapterNormal = new ContasPagarAdapter(ContasPagarActivity.this, lstCp);

lvContasPagar.setAdapter(adapterNormal);
                    lvContasPagar.setOnItemClickListener(verificaClickItemContasPagar(lstCp));


//Now create the methods inside actito filter the text entered by the user, as follows:

public void filter(String charText)

    charText = charText.toLowerCase();

    lstCp.clear();

    if (charText.length() == 0)

        lstCp.addAll(lstBkp);

        appendAddItem(lstBkp);

     

    else 

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

            if((lstBkp.get(i).getNome_lancamento() + " - " + String.valueOf(lstBkp.get(i).getCodigo())).toLowerCase().contains(charText))

                lstCp.add(lstBkp.get(i));

            

        

        appendAddItem(lstCp);
    


private void appendAddItem(final List<ContasPagar> novaLista)
    runOnUiThread(new Runnable()

        @Override
            public void run()
                adapterNormal.notifyDataSetChanged();               
            
        );
    

【讨论】:

【参考方案7】:

您可以通过两种方式在列表视图中实现搜索过滤器。 1. 使用 searchview 2. 使用 edittext。

    如果您想使用 searchview,请阅读此处:searchview filter.

    如果您想使用edittext,请阅读下文。

我参考了:listview search filter android

编码 sn-ps 以使用 edittext 进行过滤。

首先创建模型类MovieNames.java:

public class MovieNames 
    private String movieName;

    public MovieNames(String movieName) 
        this.movieName = movieName;
    

    public String getMovieName() 
        return this.movieName;
    


创建 listview_item.xml 文件:

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:padding="10dp">


    <TextView
        android:id="@+id/name"
        android:layout_
        android:layout_ />

</RelativeLayout>

制作 ListViewAdapter.java 类:

    import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Locale;

public class ListViewAdapter extends BaseAdapter 

    // Declare Variables

    Context mContext;
    LayoutInflater inflater;
    private ArrayList<MovieNames> arraylist;

    public ListViewAdapter(Context context, ArrayList<MovieNames> arraylist) 
        mContext = context;
        inflater = LayoutInflater.from(mContext);
        this.arraylist = arraylist;

    

    public class ViewHolder 
        TextView name;
    

    @Override
    public int getCount() 
        return arraylist.size();
    

    @Override
    public MovieNames getItem(int position) 
        return arraylist.get(position);
    

    @Override
    public long getItemId(int position) 
        return position;
    

    public View getView(final int position, View view, ViewGroup parent) 
        final ViewHolder holder;
        if (view == null) 
            holder = new ViewHolder();
            view = inflater.inflate(R.layout.listview_item, null);
            // Locate the TextViews in listview_item.xml
            holder.name = (TextView) view.findViewById(R.id.name);
            view.setTag(holder);
         else 
            holder = (ViewHolder) view.getTag();
        
        // Set the results into TextViews
        holder.name.setText(arraylist.get(position).getMovieName());
        return view;
    


 

准备activity_main.xml文件:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.parsaniahardik.searchedit.MainActivity"
    android:orientation="vertical">


    <EditText
        android:layout_
        android:layout_
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:hint="enter query"
        android:singleLine="true">


        <requestFocus/>
    </EditText>

    <ListView
        android:layout_
        android:layout_
        android:id="@+id/listView"
        android:divider="#694fea"
        android:dividerHeight="1dp" />


</LinearLayout>

最后制作 MainActivity.java 类:

    import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity 

    private EditText etsearch;
    private ListView list;
    private ListViewAdapter adapter;
    private String[] moviewList;
    public static ArrayList<MovieNames> movieNamesArrayList;
    public static ArrayList<MovieNames> array_sort;
    int textlength = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Generate sample data

        moviewList = new String[]"Xmen", "Titanic", "Captain America",
                "Iron man", "Rocky", "Transporter", "Lord of the rings", "The jungle book",
                "Tarzan","Cars","Shreck";

        list = (ListView) findViewById(R.id.listView);

        movieNamesArrayList = new ArrayList<>();
        array_sort = new ArrayList<>();

        for (int i = 0; i < moviewList.length; i++) 
            MovieNames movieNames = new MovieNames(moviewList[i]);
            // Binds all strings into an array
            movieNamesArrayList.add(movieNames);
            array_sort.add(movieNames);
        

        adapter = new ListViewAdapter(this,movieNamesArrayList);
        list.setAdapter(adapter);


        etsearch = (EditText) findViewById(R.id.editText);

        list.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                Toast.makeText(MainActivity.this, array_sort.get(position).getMovieName(), Toast.LENGTH_SHORT).show();
            
        );

        etsearch.addTextChangedListener(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) 
                textlength = etsearch.getText().length();
                array_sort.clear();
                for (int i = 0; i < movieNamesArrayList.size(); i++) 
                    if (textlength <= movieNamesArrayList.get(i).getMovieName().length()) 
                        Log.d("ertyyy",movieNamesArrayList.get(i).getMovieName().toLowerCase().trim());
                        if (movieNamesArrayList.get(i).getMovieName().toLowerCase().trim().contains(
                                etsearch.getText().toString().toLowerCase().trim())) 
                            array_sort.add(movieNamesArrayList.get(i));
                        
                    
                
                    adapter = new ListViewAdapter(MainActivity.this, array_sort);
                    list.setAdapter(adapter);

            
        );

    

【讨论】:

【参考方案8】:

您可以使用编辑文本中的文本更改找到自定义列表适配器类...

使用 Filterable 实现创建自定义列表适配器类:

private class CustomListAdapter extends BaseAdapter implements Filterable

    private LayoutInflater inflater;
    private ViewHolder holder;
    private ItemFilter mFilter = new ItemFilter();

    public CustomListAdapter(List<YourCustomData> newlist) 
        filteredData = newlist;
    

    @Override
    public int getCount() 
        return filteredData.size();
    

    @Override
    public Object getItem(int position) 
        return null;
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 

        holder = new ViewHolder();

        if(inflater==null)
            inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(convertView == null)
            convertView = inflater.inflate(R.layout.row_listview_item, null);

            holder.mTextView = (TextView)convertView.findViewById(R.id.row_listview_member_tv);

            convertView.setTag(holder);
        else
            holder = (ViewHolder)convertView.getTag();
        

        holder.mTextView.setText(""+filteredData.get(position).getYourdata());

        return convertView;
    

    @Override
    public Filter getFilter() 
        return mFilter;
    




class ViewHolder
    TextView mTextView;


private class ItemFilter extends Filter 
    @SuppressLint("DefaultLocale")
    @Override
    protected FilterResults performFiltering(CharSequence constraint) 

        String filterString = constraint.toString().toLowerCase();

        FilterResults results = new FilterResults();

        final List<YourCustomData> list = YourObject.getYourDataList();

        int count = list.size();
        final ArrayList<YourCustomData> nlist = new ArrayList<YourCustomData>(count);

        String filterableString ;

        for (int i = 0; i < count; i++) 
            filterableString = ""+list.get(i).getYourText();
            if (filterableString.toLowerCase().contains(filterString)) 
                YourCustomData mYourCustomData = list.get(i);
                nlist.add(mYourCustomData);
            
        

        results.values = nlist;
        results.count = nlist.size();

        return results;
    

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) 
        filteredData = (ArrayList<YourCustomData>) results.values;
        mCustomListAdapter.notifyDataSetChanged();
    



mEditTextSearch.addTextChangedListener(new TextWatcher() 
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) 
            if(mCustomListAdapter!=null)
                mCustomListAdapter.getFilter().filter(s.toString());

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

【讨论】:

【参考方案9】:

我注意到的一件事是,每当您编辑列表(例如添加项目)以及对其进行过滤时,然后在 @Override getView 方法中,您不应该使用 filteredData.get(position),因为它会抛出IndexOutOfBounds 异常。

相反,对我有用的是使用 getItem(position) 方法,它属于 ArrayAdapter 类。

【讨论】:

【参考方案10】:

只是更新。

如果勾选的答案对您来说很好,但当搜索文本为空时它什么也不显示。这是解决方案:

private class ItemFilter extends Filter 
    @Override
    protected FilterResults performFiltering(CharSequence constraint) 
        
        String filterString = constraint.toString().toLowerCase();
        
        FilterResults results = new FilterResults();

        if(constraint.length() == 0)
        
            results.count = originalData.size();
            results.values = originalData;
        else 

        
        final List<String> list = originalData;

        int count = list.size();
        final ArrayList<String> nlist = new ArrayList<String>(count);

        String filterableString ;
        
        for (int i = 0; i < count; i++) 
            filterableString = list.get(i);
            if (filterableString.toLowerCase().contains(filterString)) 
                nlist.add(filterableString);
            
        
        
        results.values = nlist;
        results.count = nlist.size();
     
        return results;
    

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) 
        filteredData = (ArrayList<String>) results.values;
        notifyDataSetChanged();
      

   

对于下面的任何查询评论

【讨论】:

以上是关于带有过滤器 Android 的自定义 Listview 适配器的主要内容,如果未能解决你的问题,请参考以下文章

Android中的自定义相机过滤器

如何在android中制作带有圆角的自定义对话框

带有旋转,放大,缩小和移动在android中的自定义textview?

带有矢量资产图标的 android 谷歌地图中的自定义标记

Android ListView 和带有 ViewHolder 的自定义适配器

Django 找不到我的自定义模板过滤器