带有过滤器 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
,然后在您的activity
或fragment
中实现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中的自定义textview?