implement search on a custom listview
i have a listview
and EditText
field and i wanna implement search, but my listview
is a custom listview
populated with array of objects of class Item. And when i press key whole listview
gone so i guess the problem is that it cannot match char with object of class Item that's why there is no results when i press a key.
this is my code
filterText = (EditText) findViewById(R.id.editTextfilter);
filterText.addTextChangedListener(filterTextWatcher);
m_开发者_如何学Pythonitems = new ArrayList<Item>();
phoneList=(ListView)findViewById(android.R.id.list);
phoneList.setTextFilterEnabled(true);
this.m_adapter = new ItemAdapter(this,R.layout.row,m_items);
phoneList.setAdapter(this.m_adapter);
private TextWatcher filterTextWatcher = 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) {
m_adapter.getFilter().filter(s.toString());
}
};
@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}
any help how to get it works
I had a similar requirement. I have used a custom Filter.
ArrayList<PostData> mPostingData = null;//arraylist of class items
ArrayList<PostData> mTemp = new ArrayList<PostData>();//temporary arraylist of class items
ArrayList<PostData> mOri = new ArrayList<PostData>();//Original arraylist
getListView().setTextFilterEnabled(true);
search= (EditText) findViewById(R.id.searchbox);
search.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
mCustomListView.getFilter().filter(s);
mCustomListView.notifyDataSetChanged();
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
});
POJO Class
class PostData {
String mID;
String mPostedBy;
String mTitle;
String mMessage;
String mImageUrl;
String mVideoUrl;
String mType ;
boolean me=false;
}
Custom List View with Filter method overriden. Search based on mTitle of POJO Class
class CustomListView extends ArrayAdapter {
Context context;
LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2;
private Bitmap mIcon3;
PostData mp ;
public CustomListView(Context c)
{
super(c, 0);
mInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mIcon1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.text_icon);
mIcon2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.image_icon);
mIcon3 = BitmapFactory.decodeResource(c.getResources(), R.drawable.video_icon);
}
public int getCount() {
if(mPostingData!=null){
return mPostingData.size();
}else{
return 0;
}
}
public void setData(ArrayList<PostData> mPpst) {
mPostingData = mPpst;//contains class items data.
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count >= 0) {
setData((ArrayList<PostData>) results.values);//if results of search is null set the searched results data
} else {
setData(mOri);// set original values
}
notifyDataSetInvalidated();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (!TextUtils.isEmpty(constraint)) {
constraint = constraint.toString().toLowerCase();
ArrayList<PostData> foundItems = new ArrayList<PostData>();
if(mTemp!=null)
{
for(int i=0;i<mTemp.size();i++)
{
//If mTitle contains the string entered in Editext
if (mTemp.get(i).mTitle.toString().contains(constraint)) {
foundItems.add(mTemp.get(i));
}
else
{
}
}
}
result.count = foundItems.size();//search results found return count
result.values = foundItems;// return values
}
else
{
result.count=-1;// no search results found
}
return result;
}
};
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
///int type = getItemViewType(arg0);
Log.i("Aru","get View");
if(mPostingData == null ){
return null;
}
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listviewimg, null);
convertView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.ll=(LinearLayout) convertView.findViewById(R.id.lvid);
holder.text = (TextView) convertView.findViewById(R.id.texttitle);
holder.text2 = (TextView) convertView.findViewById(R.id.tvst);
holder.icon = (ImageView) convertView.findViewById(R.id.llimage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
mp = mPostingData.get(position);
String title = mp.mType;
if(mp.mTitle!=null && Name.equals(mp.mPostedBy )){
title = mp.mTitle+" "+title;
//holder.text.setBackgroundColor(Color.WHITE);
holder.ll.setBackgroundResource(R.drawable.listbkgme);
holder.text.setText(title);
}
else if(mp.mTitle!=null && Name!=mp.mPostedBy)
{
title = mp.mTitle+" "+title;
holder.text.setText(title);
}
if(mp.mMessage!=null && Name.equals(mp.mPostedBy )){
holder.ll.setBackgroundResource(R.drawable.listbkgme);
holder.text2.setText(mp.mMessage);
}
else if(mp.mMessage!=null && Name!=(mp.mPostedBy))
{
holder.text2.setText(mp.mMessage);
}
if(mp.mImageUrl!=null ){
holder.icon.setImageBitmap(mIcon2);
}else if(mp.mVideoUrl!=null){
holder.icon.setImageBitmap(mIcon3);
}else{
holder.icon.setImageBitmap(mIcon1);
}
return convertView;
}
class ViewHolder {
TextView text;
TextView text2;
ImageView icon;
LinearLayout ll;
}
public long getItemId(int position) {
return position;
}
}
Modify the above according to your requirements. I have tested the code and it works.
Make a data class like this
package ali.search;
public class Data {
public Data() {
}
int id;
private String JobTitle;
private String Department;
private String Locationn;
private String JobRole;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getJobTitle() {
return JobTitle;
}
public void setJobTitle(String jobTitle) {
JobTitle = jobTitle;
}
public String getDepartment() {
return Department;
}
public void setDepartment(String department) {
Department = department;
}
public String getLocation() {
return Locationn;
}
public void setLocation(String location) {
Locationn = location;
}
public String getJobRole() {
return JobRole;
}
public void setJobRole(String jobRole) {
JobRole = jobRole;
}
}
Make Activity class like this
package ali.search;
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
public class SearchActivity extends Activity {
String[] jobtitles = { "Android Developer", "Tester","iOS Developer",
};
String[] departments = { "android", "testing", "iphone" };
String[] locations = { "Delhi", "Mumbai", "Noida" };
String[] jobRoles = { "develop android based apps", "test mobile apps",
"develop iphone based apps" };
private ListView listViewSearch;
private EditText editSearchView;
private SearchAdapter adapter;
private ArrayList<Data> sortedItems = new ArrayList<Data>();
private ArrayList<Data> OrignalItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
listViewSearch = (ListView) findViewById(R.id.lvSearch);
editSearchView = (EditText) findViewById(R.id.edittext);
OrignalItems = getListOfType();
sortedItems.addAll(OrignalItems);
adapter = new SearchAdapter(SearchActivity.this, sortedItems);
listViewSearch.setAdapter(adapter);
editSearchView.addTextChangedListener(searchTxtChangeListener);
}
private ArrayList<Data> getListOfType() {
ArrayList<Data> dataList = new ArrayList<Data>();
for (int i = 0; i < 3; i++) {
Data data = new Data();
data.setJobTitle(jobtitles[i]);
data.setDepartment(departments[i]);
data.setLocation(locations[i]);
data.setJobRole(jobRoles[i]);
data.setId(i);
dataList.add(data);
dataList.add(data);// dulicate entry
}
return dataList;
}
private TextWatcher searchTxtChangeListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
int textlength = editSearchView.getText().length();
sortedItems.clear();
for (int i = 0; i < OrignalItems.size(); i++) {
if (textlength <= OrignalItems.get(i).getJobTitle().length()) {
if (editSearchView
.getText()
.toString()
.equalsIgnoreCase(
(String) OrignalItems.get(i).getJobTitle().subSequence(0,
textlength))) {
sortedItems.add(OrignalItems.get(i));
}
}
}
adapter.notifyDataSetChanged();
}
};
}
Finally this the custom adapter
package ali.search;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class SearchAdapter extends BaseAdapter{
Context context;
ArrayList<Data> list;
LayoutParams params;
private static LayoutInflater inflater = null;
public SearchAdapter(Context context, ArrayList<Data> list) {
this.context = context;
this.list = list;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if (vi == null) {
vi = inflater.inflate(R.layout.search_list_item, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
holder.txtDepartment = (TextView) vi.findViewById(R.id.txtDepartment);
holder.txtLocation = (TextView) vi.findViewById(R.id.txtLocation);
holder.txtJobRole = (TextView) vi.findViewById(R.id.txtJobRole);
holder.layoutRelative = (RelativeLayout) vi.findViewById(R.id.layoutRelative);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
holder.txtTitle.setText(list.get(position).getJobTitle());
holder.txtDepartment.setText(list.get(position).getDepartment());
holder.txtLocation.setText(list.get(position).getLocation());
holder.txtJobRole.setText(list.get(position).getJobRole());
return vi;
}
class ViewHolder {
RelativeLayout layoutRelative;
TextView txtTitle;
TextView txtDepartment;
TextView txtLocation;
TextView txtJobRole;
}
}
It is working fine.
In custom listview,you must create a Filter method in Adapter.
精彩评论