具有自定义适配器的 ListView 中的 SearchView
Posted
技术标签:
【中文标题】具有自定义适配器的 ListView 中的 SearchView【英文标题】:SearchView In ListView having a custom Adapter 【发布时间】:2014-06-18 18:42:55 【问题描述】:伙计们,我需要一些帮助。我一直在尝试在我的项目中实现 SearchView。但是我的项目包含一个带有自定义适配器的列表视图。我搜索了许多站点,但都有使用实现的示例一个 arrayadapter..假设我有一个 Employee 类,它包含姓名和年龄字段..我如何只使用他们的姓名过滤员工..
public class MainActivity extends Activity implements SearchView.OnQueryTextListener
SearchView mSearchView;
ListView mListView;
//String mStrings[]= "abc","def","efg","ghi","ijk","apple","agxhsdgc","abbbcc";
ArrayList<Employee> emp_list=null;
EmployeeAdapter emp_adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSearchView=(SearchView) findViewById(R.id.searchView1);
mListView=(ListView) findViewById(R.id.listView1);
emp_list=new ArrayList<Employee>();
emp_list.add(new Employee("ABC", 24));
emp_list.add(new Employee("ACB", 24));
emp_list.add(new Employee("BVF", 28));
emp_list.add(new Employee("BRT", 28));
emp_list.add(new Employee("ANM", 23));
emp_adapter=new EmployeeAdapter(MainActivity.this, emp_list);
mListView.setAdapter(emp_adapter);
// mListView.setAdapter(new ArrayAdapter<String>(this,
// android.R.layout.simple_list_item_1,
// mStrings));
mListView.setTextFilterEnabled(true);
setupSearchView();
private void setupSearchView()
mSearchView.setIconifiedByDefault(false);
mSearchView.setOnQueryTextListener(this);
mSearchView.setSubmitButtonEnabled(true);
mSearchView.setQueryHint("Search Here");
@Override
public boolean onQueryTextChange(String newText)
if (TextUtils.isEmpty(newText.toString()))
mListView.clearTextFilter();
else
mListView.setFilterText(newText.toString());
return true;
@Override
public boolean onQueryTextSubmit(String query)
return false;
这是我扩展 BaseAdapter 的适配器类..
public class EmployeeAdapter extends BaseAdapter
Context ctx;
ArrayList<Employee> emp_list;
LayoutInflater linf=null;
EmployeeHolder holder=null;
public EmployeeAdapter(Context ctx, ArrayList<Employee> emp_list)
super();
this.ctx = ctx;
this.emp_list = emp_list;
linf=(LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public class EmployeeHolder
TextView name;
TextView age;
@Override
public int getCount()
// TODO Auto-generated method stub
return emp_list.size();
@Override
public Object getItem(int position)
// TODO Auto-generated method stub
return emp_list.get(position);
@Override
public long getItemId(int position)
// TODO Auto-generated method stub
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
// TODO Auto-generated method stub
if(convertView==null)
convertView=linf.inflate(R.layout.row, parent, false);
holder=new EmployeeHolder();
holder.name=(TextView) convertView.findViewById(R.id.name);
holder.age=(TextView) convertView.findViewById(R.id.age);
convertView.setTag(holder);
else
holder=(EmployeeHolder) convertView.getTag();
Employee e=(Employee) getItem(position);
holder.name.setText(e.getName());
holder.age.setText(String.valueOf(e.getAge()));
return convertView;
提前致谢..
【问题讨论】:
【参考方案1】:试试这个方法,希望对你有帮助...
activity_main.xml
<SearchView
android:id="@+id/searchView1"
android:layout_
android:layout_/>
<ListView
android:id="@+id/listView1"
android:layout_
android:layout_
android:layout_weight="1"/>
</LinearLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_>
<TextView
android:id="@+id/txtName"
android:layout_
android:layout_ />
<TextView
android:id="@+id/txtAge"
android:layout_
android:layout_
android:layout_marginTop="5dp"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity implements SearchView.OnQueryTextListener
private SearchView mSearchView;
private ListView mListView;
private ArrayList<Employee> employeeArrayList;
private EmployeeAdapter employeeAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSearchView=(SearchView) findViewById(R.id.searchView1);
mListView=(ListView) findViewById(R.id.listView1);
employeeArrayList=new ArrayList<Employee>();
employeeArrayList.add(new Employee("ABC", 24));
employeeArrayList.add(new Employee("ACB", 24));
employeeArrayList.add(new Employee("BVF", 28));
employeeArrayList.add(new Employee("BRT", 28));
employeeArrayList.add(new Employee("ANM", 23));
employeeAdapter=new EmployeeAdapter(MainActivity.this, employeeArrayList);
mListView.setAdapter(employeeAdapter);
mListView.setTextFilterEnabled(true);
setupSearchView();
private void setupSearchView()
mSearchView.setIconifiedByDefault(false);
mSearchView.setOnQueryTextListener(this);
mSearchView.setSubmitButtonEnabled(true);
mSearchView.setQueryHint("Search Here");
@Override
public boolean onQueryTextChange(String newText)
if (TextUtils.isEmpty(newText))
mListView.clearTextFilter();
else
mListView.setFilterText(newText);
return true;
@Override
public boolean onQueryTextSubmit(String query)
return false;
EmployeeAdapter.java
public class EmployeeAdapter extends BaseAdapter implements Filterable
public Context context;
public ArrayList<Employee> employeeArrayList;
public ArrayList<Employee> orig;
public EmployeeAdapter(Context context, ArrayList<Employee> employeeArrayList)
super();
this.context = context;
this.employeeArrayList = employeeArrayList;
public class EmployeeHolder
TextView name;
TextView age;
public Filter getFilter()
return new Filter()
@Override
protected FilterResults performFiltering(CharSequence constraint)
final FilterResults oReturn = new FilterResults();
final ArrayList<Employee> results = new ArrayList<Employee>();
if (orig == null)
orig = employeeArrayList;
if (constraint != null)
if (orig != null && orig.size() > 0)
for (final Employee g : orig)
if (g.getName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
oReturn.values = results;
return oReturn;
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
employeeArrayList = (ArrayList<Employee>) results.values;
notifyDataSetChanged();
;
public void notifyDataSetChanged()
super.notifyDataSetChanged();
@Override
public int getCount()
return employeeArrayList.size();
@Override
public Object getItem(int position)
return employeeArrayList.get(position);
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
EmployeeHolder holder;
if(convertView==null)
convertView=LayoutInflater.from(context).inflate(R.layout.row, parent, false);
holder=new EmployeeHolder();
holder.name=(TextView) convertView.findViewById(R.id.txtName);
holder.age=(TextView) convertView.findViewById(R.id.txtAge);
convertView.setTag(holder);
else
holder=(EmployeeHolder) convertView.getTag();
holder.name.setText(employeeArrayList.get(position).getName());
holder.age.setText(String.valueOf(employeeArrayList.get(position).getAge()));
return convertView;
Employee.java
public class Employee
private String name;
private int age;
public Employee(String name,int age)
this.name = name;
this.age = age;
public String getName()
return name;
public int getAge()
return age;
【讨论】:
@Haresh:在我的情况下,我使用 Imageview 是否可以过滤 但是有一个问题,当用户点击过滤列表中的项目进行过滤后,它仍然从原始列表中打开项目。!我用谷歌搜索并找到了解决方案,但无法解决我的问题。 您好,在搜索视图中单击交叉时,我没有返回完整列表。需要紧急帮助..谢谢 你有没有尝试调用mListView.clearTextFilter();点击十字架? @HareshChhelana 非常感谢您的回答!我一直在寻找几个小时如何做到这一点,这对我有很大帮助!不过有一个问题,我如何摆脱“搜索”文本覆盖?【参考方案2】:那里有很好的答案,但仍然存在评论部分提到的一些问题(onclick时位置错误,serchview文本覆盖),因此您也可以通过以下方式进行此操作
更多信息请参考:searchview listview android
我已经测试过了,目前没有发现任何问题,如果你发现任何问题,请在评论部分提及。
模型类:MovieNames.java
public class MovieNames
private String movieName;
public MovieNames(String movieName)
this.movieName = movieName;
public String getAnimalName()
return this.movieName;
2: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 )
mContext = context;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<MovieNames>();
this.arraylist.addAll(MainActivity.movieNamesArrayList);
public class ViewHolder
TextView name;
@Override
public int getCount()
return MainActivity.movieNamesArrayList.size();
@Override
public MovieNames getItem(int position)
return MainActivity.movieNamesArrayList.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(MainActivity.movieNamesArrayList.get(position).getAnimalName());
return view;
// Filter Class
public void filter(String charText)
charText = charText.toLowerCase(Locale.getDefault());
MainActivity.movieNamesArrayList.clear();
if (charText.length() == 0)
MainActivity.movieNamesArrayList.addAll(arraylist);
else
for (MovieNames wp : arraylist)
if (wp.getAnimalName().toLowerCase(Locale.getDefault()).contains(charText))
MainActivity.movieNamesArrayList.add(wp);
notifyDataSetChanged();
MainActivity.java 类:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener
// Declare Variables
private ListView list;
private ListViewAdapter adapter;
private SearchView editsearch;
private String[] moviewList;
public static ArrayList<MovieNames> movieNamesArrayList = new ArrayList<MovieNames>();
@Override
public 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";
// Locate the ListView in listview_main.xml
list = (ListView) findViewById(R.id.listview);
movieNamesArrayList = 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);
// Pass results to ListViewAdapter Class
adapter = new ListViewAdapter(this);
// Binds the Adapter to the ListView
list.setAdapter(adapter);
// Locate the EditText in listview_main.xml
editsearch = (SearchView) findViewById(R.id.search);
editsearch.setOnQueryTextListener(this);
list.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
Toast.makeText(MainActivity.this, movieNamesArrayList.get(position).getAnimalName(), Toast.LENGTH_SHORT).show();
);
@Override
public boolean onQueryTextSubmit(String query)
return false;
@Override
public boolean onQueryTextChange(String newText)
String text = newText;
adapter.filter(text);
return false;
【讨论】:
【参考方案3】:源代码
https://drive.google.com/open?id=0BzBKpZ4nzNzUOFlxeHhuWmF0Q1U
package example.abhiandroid.searchviewexample;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ListView;
import android.widget.SearchView;
import java.util.ArrayList;
public class SearchViewActivity extends AppCompatActivity implements SearchView.OnQueryTextListener
// Declare Variables
ListView list;
ListViewAdapter adapter;
public static SearchView editsearch;
String[] animalNameList;
ArrayList<AnimalNames> arraylist = new ArrayList<AnimalNames>();
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
// Generate sample data
animalNameList = new String[]"Lion", "Tiger", "Dog",
"Cat", "Tortoise", "Rat", "Elephant", "Fox",
"Cow","Donkey","Monkey";
// Locate the ListView in listview_main.xml
list = (ListView) findViewById(R.id.listview);
for (int i = 0; i < animalNameList.length; i++)
AnimalNames animalNames = new AnimalNames(animalNameList[i]);
// Binds all strings into an array
arraylist.add(animalNames);
// Pass results to ListViewAdapter Class
adapter = new ListViewAdapter(this, arraylist);
// Binds the Adapter to the ListView
list.setAdapter(adapter);
// Locate the EditText in listview_main.xml
editsearch = (SearchView) findViewById(R.id.search);
editsearch.setOnQueryTextListener(this);
editsearch.setOnSuggestionListener(new SearchView.OnSuggestionListener()
@Override
public boolean onSuggestionSelect(int position)
return true;
@Override
public boolean onSuggestionClick(int position)
Cursor cursor= editsearch.getSuggestionsAdapter().getCursor();
cursor.moveToPosition(position);
String suggestion =cursor.getString(2);//2 is the index of col containing suggestion name.
editsearch.setQuery(suggestion,true);//setting suggestion
return true;
);
@Override
public boolean onQueryTextSubmit(String query)
Log.e("keshav","query ->"+query);
return false;
@Override
public boolean onQueryTextChange(String newText)
String text = newText;
Log.e("keshav","newText ->"+newText);
adapter.filter(text);
return false;
package example.abhiandroid.searchviewexample;
import android.content.Context;
import android.util.Log;
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.List;
import java.util.Locale;
public class ListViewAdapter extends BaseAdapter
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<AnimalNames> animalNamesList = null;
private ArrayList<AnimalNames> arraylist;
public ListViewAdapter(Context context, List<AnimalNames> animalNamesList)
mContext = context;
this.animalNamesList = animalNamesList;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<AnimalNames>();
this.arraylist.addAll(animalNamesList);
public class ViewHolder
TextView name;
@Override
public int getCount()
return animalNamesList.size();
@Override
public AnimalNames getItem(int position)
return animalNamesList.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.search_list_view_item, null);
// Locate the TextViews in search_list_view_itemiew_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(animalNamesList.get(position).getAnimalName());
view.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Log.e("keshav","click list item ->"+animalNamesList.get(position).getAnimalName());
SearchViewActivity.editsearch.setQuery(animalNamesList.get(position).getAnimalName(), false);
Log.e("keshav","click size ->"+animalNamesList.size());
// TOdo size always 1 Important See cs Electric Project in Holostik
Log.e("keshav","click size ->"+animalNamesList.get(0).getAnimalName());
);
return view;
// Filter Class
public void filter(String charText)
charText = charText.toLowerCase(Locale.getDefault());
animalNamesList.clear();
if (charText.length() == 0)
animalNamesList.addAll(arraylist);
else
for (AnimalNames wp : arraylist)
if (wp.getAnimalName().toLowerCase(Locale.getDefault()).contains(charText))
animalNamesList.add(wp);
notifyDataSetChanged();
package example.abhiandroid.searchviewexample;
public class AnimalNames
private String animalName;
public AnimalNames(String animalName)
this.animalName = animalName;
public String getAnimalName()
return this.animalName;
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<SearchView
android:id="@+id/search"
android:layout_
android:layout_
android:iconifiedByDefault="false">
<requestFocus />
</SearchView>
<ListView
android:id="@+id/listview"
android:layout_
android:layout_
android:layout_below="@+id/search" />
</RelativeLayout>
list item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:padding="10dp">
<TextView
android:id="@+id/nameLabel"
android:layout_
android:layout_
android:text="Animal : " />
<TextView
android:id="@+id/name"
android:layout_
android:layout_
android:layout_toRightOf="@+id/nameLabel" />
</RelativeLayout>
快乐编码
【讨论】:
【参考方案4】:菜单:menu_doctor_list.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search_white_24dp"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>
</menu>
活动:
public class ListActivity extends AppActivity implements SearchView.OnQueryTextListener
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_doctor_list, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQueryHint("Search Doctor by Name or Specialization");
searchView.setOnQueryTextListener(this);
searchView.setOnCloseListener(this);
searchView.setIconified(false);
return true;
@Override
public boolean onQueryTextSubmit(String query)
System.out.println("query = " + query);
doctorListAdapter.getFilter().filter(query);
return true;
@Override
public boolean onQueryTextChange(String newText)
System.out.println("query = " + newText);
doctorListAdapter.getFilter().filter(newText);
return true;
适配器:
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.BindingHolder> implements Filterable
private List<DoctorInfo> mOriginalValues; // Original Values
private List<DoctorInfo> mDisplayedValues; // Values to be displayed use this in onBindViewHolder()
public DoctorListAdapter(Context context, List<DoctorInfo> appointmentList)
this.mOriginalValues = appointmentList;
this.mDisplayedValues = appointmentList;
@Override
public Filter getFilter()
Filter filter = new Filter()
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
mDisplayedValues = (ArrayList<DoctorInfo>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
@Override
protected FilterResults performFiltering(CharSequence constraint)
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
ArrayList<DoctorInfo> FilteredArrList = new ArrayList<DoctorInfo>();
if (mOriginalValues == null)
mOriginalValues = new ArrayList<DoctorInfo>(mDisplayedValues); // saves the original data in mOriginalValues
/********
*
* If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
* else does the Filtering and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0)
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
else
constraint = constraint.toString().toLowerCase();
for (int i = 0; i < mOriginalValues.size(); i++)
String data = mOriginalValues.get(i).getFirstname() + " " + mOriginalValues.get(i).getLastname();
if (data.toLowerCase().startsWith(constraint.toString()))
FilteredArrList.add(mOriginalValues.get(i));
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
return results;
;
return filter;
【讨论】:
以上是关于具有自定义适配器的 ListView 中的 SearchView的主要内容,如果未能解决你的问题,请参考以下文章
自定义 ListView 适配器中的 ImageButton
使用自定义适配器更改 ListView 中特定行中的 ImageView