I'm trying to implement a search function in my application. I have used an adapter to because I want to display 2 textviews in listview and listview should be clickable (I don;t think it's possible to do without an adapter).
My problem is I can't use addTextChangedListener in the adapter class. it gives exception (It worked in my activity class).
search activity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_results_activity);
new SearchMenuAsyncTask(getApplicationContext(), this).execute();
listtv = (LinearLayout) findViewById(R.id.product_lv);
lv = (ListView) findViewById(R.id.list_view);
inputSearch = (EditText) findViewById(R.id.inputSearch);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"]");
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onTaskCompleted(JSONArray responseJson) {
try {
final List<String> descriptions = new ArrayList<String>();
final List<String> menudescriptions = new ArrayList<String>();
for (int i = 0; i < responseJson.length(); ++i) {
final JSONObject object = responseJson.getJSONObject(i);
if ((object.getString("MainCategoryID")).equals("5")
&& (object.getString("SubCategoryID")).equals("6")
&& (object.getString("Visible")).equals("true")) {
Log.i("descriptionsBev ", object.getString("Description"));
descriptions.add(object.getString("Description"));
Log.i("MenuDescription ",
object.getString("MenuDescription"));
menudescriptions
.add(object.getString("MenuDescription"));
}
adapter = new CustomListSearch(
getApplicationContext(), descriptions,
menudescriptions);
lv.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
CustomListSearch.java
public class CustomListSearch extends BaseAdapter implements Filterable {
private Context context;
private final List<String> descriptions;
private List<String>filteredData = null;
private final List<String> menudescriptions;
private ItemFilter mFilter = new ItemFilter();
private LayoutInflater mInflater;
ArrayAdapter<String> adapter;
public CustomListSearch(Context c, List<String> data,
List<String> menudescriptions) {
this.context = c;
this.filteredData = data ;
this.descriptions = data;
this.menudescriptions = menudescriptions;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return filteredData.size();
}
#Override
public Object getItem(int position) {
return filteredData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
private TextView tvMenudescriptions;
private TextView tvDescriptions;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.search_list_item, parent, false);
holder.tvDescriptions = (TextView) convertView
.findViewById(R.id.product_name);
holder.tvMenudescriptions = (TextView) convertView
.findViewById(R.id.product_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvDescriptions.setText(descriptions.get(position));
holder.tvMenudescriptions.setText(menudescriptions.get(position));
LinearLayout itemlist = (LinearLayout) convertView
.findViewById(R.id.product_lv);
itemlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Still under constructions...",
Toast.LENGTH_LONG).show();
}
});
return convertView;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
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 = descriptions;
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();
}
}
}
I was following below answer and worked this out
Custom Listview Adapter with filter Android
Related
I have an android app where I have a custom adapter. I want to filter my data but when I clear my edit text my list goes blank.
I want my original list view to be displayed when I clear my edit text. I think my original list is also getting cleared in some code but I do not understand where.
public class Adapter_SelectedDetail extends ArrayAdapter<DataModel> implements Filterable {
private final Context context;
ArrayList<DataModel> MyList=null,newList=null;
private MyFilter filter;
DataModel dataModel;
EditText Mysearch;
ListView listView;
String searchdata;
private static LayoutInflater inflater=null;
public Adapter_SelectedDetail(Context context, EditText search, ArrayList MyList1, ListView listView) {
super(context, -1, MyList1);
this.newList = new ArrayList<DataModel>();
this.newList.addAll(newList);
this.Mysearch=search;
this.listView=listView;
this.MyList = new ArrayList<DataModel>();
this.MyList.addAll(newList);
this.MyList=MyList1;
this.context=context;
}
#Override
public Filter getFilter() {
if (filter == null){
filter = new MyFilter();
}
return filter;
}
#Override
public View getView(final int position, View ConverView, ViewGroup parent) {
inflater = ( LayoutInflater )context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// DataModel dataModel = (DataModel) getItem(position);
View rowView = ConverView;
// TODO Auto-generated method stub
TextView CompanyName,CompanyMobile,Bill_no,Bill_date,PartyName,Transport,City,
State,CustomerMobileNumber,AgentName,LRno,LRdate,Item,Shades,
AgentMobileNumber,InvoicePDF,PartyEmail,agentEmail;
if (rowView==null) {
rowView = inflater.inflate(R.layout.selected_detail_list_view, parent,false);
}
dataModel=MyList.get(position);
if (dataModel!=null) {
CompanyName = (TextView) rowView.findViewById(R.id.txt_heading_of_detail);
CompanyMobile = (TextView) rowView.findViewById(R.id.txt_subheading_of_detail);
Bill_no = (TextView) rowView.findViewById(R.id.txt_bill_no);
Bill_date = (TextView) rowView.findViewById(R.id.txt_bill_date);
PartyName = (TextView) rowView.findViewById(R.id.txt_party_name);
Transport = (TextView) rowView.findViewById(R.id.txt_transport);
City = (TextView) rowView.findViewById(R.id.txt_city);
State = (TextView) rowView.findViewById(R.id.txt_state);
Shades = (TextView) rowView.findViewById(R.id.txt_shades);
CustomerMobileNumber = (TextView) rowView.findViewById(R.id.txt_customer_mob_no);
AgentName = (TextView) rowView.findViewById(R.id.txt_agent);
AgentMobileNumber = (TextView) rowView.findViewById(R.id.txt_agent_mob_number);
LRdate = (TextView) rowView.findViewById(R.id.txt_lr_date);
LRno = (TextView) rowView.findViewById(R.id.txt_lr_number);
Item = (TextView) rowView.findViewById(R.id.txt_item);
agentEmail = (TextView) rowView.findViewById(R.id.txt_agent_Email);
PartyEmail = (TextView) rowView.findViewById(R.id.txt_party_email);
// Toast.makeText(context, MyList1.get(2).toString(), Toast.LENGTH_SHORT).show();
CompanyMobile.setText(dataModel.getCompanyMobile());
City.setText(dataModel.getCity());
State.setText(dataModel.getState());
CompanyName.setText(dataModel.getCompanyName());
Bill_no.setText(dataModel.getBill_no());
PartyName.setText(dataModel.getPartyName());
Transport.setText(dataModel.getTransport());
Shades.setText(dataModel.getShades());
CustomerMobileNumber.setText(dataModel.getCustomerMobileNumber());
AgentName.setText(dataModel.getAgentName());
AgentMobileNumber.setText(dataModel.getAgentMobileNumber());
LRdate.setText(dataModel.getLRdate());
LRno.setText(dataModel.getLRno());
Item.setText(dataModel.getItem());
agentEmail.setText(dataModel.getAgentEmail());
PartyEmail.setText(dataModel.getPartyEmail());
}
return rowView;
}
public class MyFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
{
ArrayList<DataModel> filteredItems = new ArrayList<DataModel>();
for(int i = 0, l = MyList.size(); i < l; i++)
{
DataModel dataModel = MyList.get(i);
if(dataModel.getShades().toString().toLowerCase().contains(constraint))
filteredItems.add(dataModel);
}
result.count = filteredItems.size();
result.values = filteredItems;
}
else
{
synchronized(this)
{
result.values = MyList;
result.count = MyList.size();
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
newList = (ArrayList<DataModel>)results.values;
notifyDataSetChanged();
clear();
for (int i = 0, l = newList.size(); i < l; i++)
add(newList.get(i));
notifyDataSetInvalidated();
}
}
}
public class Selected_Detail_Activity extends Activity {
#BindView(R.id.select_listview)
ListView selected_list;
#BindView(R.id.search)
EditText search;
String item, mobile, pass, partyName;
ArrayList<DataModel> MyList1;
Context context;
DataModel dataModel=new DataModel();
#BindView(R.id.txt_party_name)
TextView txtparty_Name;
ConnectionClass connectionClass;
Adapter_SelectedDetail adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.selected_detail);
ButterKnife.bind(this);
item = getIntent().getStringExtra("item");
mobile = getIntent().getStringExtra("mobile");
pass = getIntent().getStringExtra("pass");
partyName = getIntent().getStringExtra("partyName");
txtparty_Name.setText(partyName);
connectionClass = new ConnectionClass();
context=this;
selected_list.setAdapter(adapter);
try {
Connection con = connectionClass.CONN();
if (con == null) {
} else {
PreparedStatement statement = con.prepareStatement("EXEC " + pass + " " + item + " , " + mobile + "");
MyList1 = new ArrayList<DataModel>();
ResultSet rs = statement.executeQuery();
while (rs.next()) {
dataModel.setBill_date(rs.getString("bill_date"));
dataModel.setCompanyMobile(rs.getString("CompanyMobile"));
dataModel.setCity(rs.getString("city"));
dataModel.setState(rs.getString("state"));
dataModel.setShades(rs.getString("Shades"));
dataModel.setAgentMobileNumber(rs.getString("agentMobNumber"));
MyList1.add(dataModel);
dataModel=new DataModel();
adapter=new Adapter_SelectedDetail(this,search,MyList1,selected_list);
selected_list.setAdapter(adapter);
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
Selected_Detail_Activity.this.adapter.getFilter().filter(s.toString());
}
});
}
}
}
catch (Exception e) {
Log.e("123", "error", e);
}
}
}
You misuse your datasets. i.e, you have erase all your original data.
firstly, you have not set backup data, replace adapters constructor with this.
public Adapter_SelectedDetail(Context context, EditText search, ArrayList MyList1, ListView listView) {
super(context,-1);
this.newList = new ArrayList<>();
this.newList.addAll(MyList1);
this.Mysearch = search;
this.listView = listView;
this.MyList = new ArrayList<>();
this.MyList.addAll(MyList1);
this.context = context;
}
and,add an override function getCount to your adapter.
#Override
public int getCount() {
return MyList.size();
}
then,
......
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
{
ArrayList<DataModel> filteredItems = new ArrayList<DataModel>();
for(int i = 0, l = newList.size(); i < l; i++)
{
DataModel dataModel = newList.get(i);
if(dataModel.getShades().toString().toLowerCase().contains(constraint))
filteredItems.add(dataModel);
}
result.count = filteredItems.size();
result.values = filteredItems;
}else
{
synchronized(this)
{
result.values = newList;
result.count = newList.size();
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
MyList= (ArrayList<DataModel>)results.values;
notifyDataSetChanged();
}
.....
then it works fine,
Good luck.
I have implement search for my application. For that I have used an adapter as well. I have loaded 30 items to the search screen. When I pressed letter z to search, then letter z belongs to 4 items out of 30 items in the list.
According to the below shown code it identifies the number 4 and shows the first 4 items out of the 30 items. When I debug inside getFilter(), it shows the filtered items correctly(I have provided a screen shot).
My problem is how can I load the filtered items. Bit confused here.
search.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_results_activity);
new SearchMenuAsyncTask(getApplicationContext(), this).execute();
listtv = (LinearLayout) findViewById(R.id.product_lv);
lv = (ListView) findViewById(R.id.list_view);
inputSearch = (EditText) findViewById(R.id.inputSearch);
lv.setTextFilterEnabled(true);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"]");
adapter.getFilter().filter(s.toString());
TextView headerTV = (TextView) findViewById(R.id.search_header);
headerTV.setText("SEARCH RESULTS");
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onTaskCompleted(JSONArray responseJson) {
try {
final List<String> menudescriptions = new ArrayList<String>();
for (int i = 0; i < responseJson.length(); ++i) {
final JSONObject object = responseJson.getJSONObject(i);
if ((object.getString("MainCategoryID")).equals("1")
&& (object.getString("SubCategoryID")).equals("1")
&& (object.getString("Visible")).equals("true")) {
Log.i("descriptionsTop ", object.getString("Description"));
descriptions.add(object.getString("Description"));
Log.i("MenuDescription ",
object.getString("MenuDescription"));
menudescriptions
.add(object.getString("MenuDescription"));
}
adapter = new CustomListSearch(
getApplicationContext(), descriptions,
menudescriptions);
lv.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
CustomListSearch.java
public class CustomListSearch extends BaseAdapter implements Filterable {
private Context context;
List<String> descriptions;
private List<String>filteredDescriptions;
private final List<String> menudescriptions;
private ItemFilter mFilter = new ItemFilter();
private LayoutInflater mInflater;
ArrayAdapter<String> adapter;
public CustomListSearch(Context c, List<String> data,
List<String> menudescriptions) {
this.context = c;
this.filteredDescriptions = data ;
this.descriptions = data;
this.menudescriptions = menudescriptions;
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return filteredDescriptions.size();
}
#Override
public Object getItem(int position) {
return filteredDescriptions.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
private TextView tvMenudescriptions;
private TextView tvDescriptions;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.search_list_item, parent, false);
holder.tvDescriptions = (TextView) convertView
.findViewById(R.id.product_name);
holder.tvMenudescriptions = (TextView) convertView
.findViewById(R.id.product_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvDescriptions.setText(descriptions.get(position));
holder.tvMenudescriptions.setText(menudescriptions.get(position));
LinearLayout itemlist = (LinearLayout) convertView
.findViewById(R.id.product_lv);
itemlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Still under constructions...",
Toast.LENGTH_LONG).show();
}
});
return convertView;
}
#Override
public Filter getFilter() {
// TODO Auto-generated method stub
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 = descriptions;
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) {
filteredDescriptions = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
}
Screen shot
To filter adapter that contains list of custom object
Create a Object:
public class TvObject {
String name;
String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
After:
public class CustomListSearch extends BaseAdapter implements Filterable {
private Context context;
private ItemFilter mFilter = new ItemFilter();
private LayoutInflater mInflater;
private List<TvObject> mListTvObject = new ArrayList<>();
private List<TvObject> mListTvObjectFiltered = new ArrayList<>();
public CustomListSearch(Context c, List<TvObject> mListTvObject) {
this.context = c;
mInflater = LayoutInflater.from(context);
this.mListTvObject = mListTvObject;
this.mListTvObjectFiltered = mListTvObject;
}
#Override
public int getCount() {
return mListTvObjectFiltered.size();
}
#Override
public Object getItem(int position) {
return mListTvObjectFiltered.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
private TextView tvMenudescriptions;
private TextView tvDescriptions;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.search_list_item, parent, false);
holder.tvDescriptions = (TextView) convertView.findViewById(R.id.product_name);
holder.tvMenudescriptions = (TextView) convertView.findViewById(R.id.product_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvDescriptions.setText(mListTvObjectFiltered.get(position).getName());
holder.tvMenudescriptions.setText(mListTvObjectFiltered.get(position).getDescription());
LinearLayout itemlist = (LinearLayout) convertView.findViewById(R.id.product_lv);
itemlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Still under constructions...",Toast.LENGTH_LONG).show();
}
});
return convertView;
}
#Override
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();
int count = mListTvObject.size();
final ArrayList<TvObject> mListResult = new ArrayList<>();
String name;
for (int i = 0; i < count; i++) {
TvObject mTvObject = mListTvObject.get(i);
name = mTvObject.getName();
if (name.toLowerCase().contains(filterString)) {
mListResult.add(mTvObject);
}
}
results.values = mListResult;
results.count = mListResult.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
mListTvObjectFiltered = (ArrayList<TvObject>) results.values;
notifyDataSetChanged();
}
}
}
Edited:
In your Activity do something like this!
try {
final List<TvObject > mListObjects = new ArrayList<>();
for (int i = 0; i < responseJson.length(); ++i) {
final JSONObject object = responseJson.getJSONObject(i);
if ((object.getString("MainCategoryID")).equals("1")
&& (object.getString("SubCategoryID")).equals("1")
&& (object.getString("Visible")).equals("true")) {
Log.i("descriptionsTop ", object.getString("Description"));
Log.i("MenuDescription ", object.getString("MenuDescription"));
TvObject mTvObject = new TvObject();
mTvObject.setName(object.getString("Description"));
mTvObject.setDescription(object.getString("MenuDescription"));
mListObjects.add(mTvObject);
}
adapter = new CustomListSearch( getApplicationContext(), mListObjects);
lv.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
I am using a custom adapter with a search filter in a fragment, however the results don't get filtered on a search, I debugged and stepped through my code and find that it is saying that the args.listenere = null!. What does this mean and how do I correct it? My code is below:
---------Custom Adapter -------
public class SalesPartAdapter extends BaseAdapter implements Filterable {
private ArrayList<SalesPartItem> listData;
private ArrayList<SalesPartItem> filteredData;
private SalesPartFilter filter;
private Context _context;
private LayoutInflater layoutInflater;
public SalesPartAdapter(Context context, ArrayList<SalesPartItem> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
_context = context;
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
//set background colour
if (convertView == null) {
//set up holder
convertView = layoutInflater.inflate(R.layout.salespart_item, null);
holder = new ViewHolder();
holder.salesPartCodeView = (TextView) convertView.findViewById(R.id.salesPartCode);
holder.salesPartDescView = (TextView) convertView.findViewById(R.id.salesPartDescription);
holder.salesPartColourBar= (ImageView) convertView.findViewById(R.id.colourBar);
convertView.setTag(holder);
} else {
//use existing holder
holder = (ViewHolder) convertView.getTag();
}
SalesPartItem salespartView = (SalesPartItem) listData.get(position);
holder.salesPartCodeView.setText(salespartView.SalesPartCode);
holder.salesPartDescView.setText(salespartView.SalesPartDescription);
holder.salesPartColourBar.setBackgroundColor(Color.parseColor(salespartView.Colour));//String.valueOf(salespartView.Colour);
return convertView;
}
/********* holder Class to contain previously inflated xml file elements *********/
static class ViewHolder {
TextView salesPartCodeView;
TextView salesPartDescView;
ImageView salesPartColourBar;
}
public Filter getFilter() {
if (filter == null){
filter = new SalesPartFilter();
}
return filter;
}
ArrayList<SalesPartItem> filteredItems;
ArrayList<Integer>countFilteredItems;
private class SalesPartFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if(constraint != null && constraint.toString().length() > 0)
{
filteredItems = new ArrayList<SalesPartItem>();
// countFilteredItems = new ArrayList<Integer>();
for(int i = 0, l = listData.size(); i < l; i++)
{
SalesPartItem salesPartItem = listData.get(i);
if(salesPartItem.SalesPartDescription.toString().toLowerCase().contains(constraint))
filteredItems.add(salesPartItem);
// countFilteredItems.add(i);
}
result.count = filteredItems.size();
result.values = filteredItems;
}
else
{
synchronized(this)
{
result.values = listData;
result.count = listData.size();
}
}
return result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// notifyDataSetChanged();
if (results.count > 0) {
listData =(ArrayList<SalesPartItem>)results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
----------------Fragment code that deals with the list view -------------------
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//USE SAMPLE ID TO GET SALES PARTS LIST FROM DATABASE
addSalesParts.setEnabled(false);
//ListViewModel (SalesPartId,salesPartName,NotUsed)
final int numberOfAddedSalesParts = 3;
SalesPartItem sp;
// fill with some dummy data for now.
for (long i = 1; i < numberOfAddedSalesParts; i++) {
sp = new SalesPartItem();
sp.SalesPartItemId = i;
sp.SalesPartCode = "LEU" + i;
if(i!=2){
sp.SalesPartDescription = "Sales Part " + i;
}
else{
sp.SalesPartDescription = "TSalZes Part " + i;
}
sp.Colour = "#cccccc";
salesPartListViewItems.add(sp);
}
// Start of Search filtering
mListView = (ListView) getActivity().findViewById(R.id.salespartsList);
//click on item - edit order
mListView.setTextFilterEnabled(true);
//display the list via our custom adapter
mListView.setAdapter(new SalesPartAdapter(getActivity(), salesPartListViewItems);
EditText searchField = (EditText) getActivity().findViewById(R.id.typeFindSalesPart);
searchField.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
//TODO Search Lists from Database and filter accordingly
SalesPartAdapter SA = new SalesPartAdapter(getActivity(), salesPartListViewItems);
SA.getFilter().filter(s.toString());
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
// salesPartListViewItems.contains(s);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
I have now resolved this, the issue was that I was creating a new instance of the adapter in the text watcher. Once I set it to use the adapter that created the original list then it worked fine
Nothing happening even i am entering exact "key" name in EditText whereas it has to be show only that record in a list.
Filtering is not working, this is how my JSON looks like:
{
"data": [
{
"id": "1",
"name": "Era Locksmith",
"key": "EraLoc2015"
},
{
"id": "2",
"name": "Mac Garage Door",
"key": "MacGdr2015"
}
]
}
I am extending ArrayAdapter<....> and implementing Filterable
CompanyListAdapter.java:
public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable {
private Context context;
ArrayList<Company> products;
SharedPreference sharedPreference;
private ArrayList<Company> filteredCompanies;
private CompanyFilter mFilter = new CompanyFilter();
public CompanyListAdapter(Context context, ArrayList<Company> products) {
super(context, R.layout.company_list_item, products);
this.context = context;
this.products = products;
sharedPreference = new SharedPreference();
}
#Override
public Filter getFilter() {
return mFilter;
}
private class ViewHolder {
TextView productNameTxt;
TextView productKeyTxt;
ImageView favoriteImg;
}
#Override
public int getCount() {
return products.size();
}
#Override
public Company getItem(int position) {
return products.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.company_list_item, null);
holder = new ViewHolder();
holder.productNameTxt = (TextView) convertView
.findViewById(R.id.txt_pdt_name);
holder.productKeyTxt = (TextView) convertView
.findViewById(R.id.txt_pdt_price);
holder.favoriteImg = (ImageView) convertView
.findViewById(R.id.imgbtn_favorite);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Company product = (Company) getItem(position);
holder.productNameTxt.setText(product.getName());
holder.productKeyTxt.setText(product.getPrice() + "");
/*If a product exists in shared preferences then set heart_red drawable
* and set a tag*/
if (checkFavoriteItem(product)) {
holder.favoriteImg.setImageResource(R.drawable.heart_red);
holder.favoriteImg.setTag("red");
} else {
holder.favoriteImg.setImageResource(R.drawable.heart_grey);
holder.favoriteImg.setTag("grey");
}
return convertView;
}
/*Checks whether a particular product exists in SharedPreferences*/
public boolean checkFavoriteItem(Company checkProduct) {
boolean check = false;
List<Company> favorites = sharedPreference.getFavorites(context);
if (favorites != null) {
for (Company product : favorites) {
if (product.equals(checkProduct)) {
check = true;
break;
}
}
}
return check;
}
#Override
public void add(Company product) {
super.add(product);
products.add(product);
notifyDataSetChanged();
}
#Override
public void remove(Company product) {
super.remove(product);
products.remove(product);
notifyDataSetChanged();
}
private class CompanyFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<Company> list = products;
int count = list.size();
final ArrayList<Company> nlist = new ArrayList<Company>(count);
Company filterableCompany;
for (int i = 0; i < count; i++) {
filterableCompany = list.get(i);
if (filterableCompany.getKey().toLowerCase().contains(filterString)) {
nlist.add(filterableCompany);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredCompanies = (ArrayList<Company>) results.values;
notifyDataSetChanged();
}
}
}
Using EditText to accept "key"
CompanyListActivity.java:
EditText filterList = (EditText) view.findViewById(R.id.editKey);
filterList.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
productListAdapter.getFilter().filter(s.toString());
}
#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
}
});
I am using code provided by #Leigh
Why not use implement Filterable?
Try something like this:
Make your adapter class look like this:
public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable {
private List<Company> companies;
private List<Company> filteredCompanies;
private CompanyFilter mFilter = new CompanyFilter();
private Context context;
SharedPreference sharedPreference;
public CompanyListAdapter(Context context, ArrayList<Company> products) {
super(context, R.layout.company_list_item, products);
this.context = context;
this.products = products;
this.filteredCompanies = products;
sharedPreference = new SharedPreference();
}
#Override
public int getCount() {
return filteredCompanies == null 0 : filteredCompanies.size();
}
#Override
public Company getItem(int position) {
return filteredCompanies.get(position);
}
#Override
public Filter getFilter() {
return mFilter;
}
}
Next go ahead and create a CompanyFilter:
private class CompanyFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<Company> list = companies;
int count = list.size();
final ArrayList<Company> nlist = new ArrayList<Company>(count);
Company filterableCompany;
for (int i = 0; i < count; i++) {
filterableCompany = list.get(i);
if (filterableCompany.getName().toLowerCase().contains(filterString)) {
nlist.add(filterableCompany);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredCompanies = (ArrayList<Company>) results.values;
notifyDataSetChanged();
}
}
This way you get to apply your filter to any number of fields. Note I am using the getName() of the company class to apply the filter in my example.
EDIT:
TO use this in an Activity / Fragment for searching you can add a TextWatcher to your EditText and apply the filter onTextChanged. Something like this:
txtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
});
you need to make your adapter implement Filterable like this:
class CustomAdapter extends BaseAdapter implements Filterable {
#Override
public Filter getFilter() { ...}
try to look at this answer:
List View Filter Android
Hello guys I want to search my custom/sectioned listview. This is what I've tried so far:
MyAdapter.class:
public class MyAdapter extends BaseAdapter implements SectionIndexer, Filterable {
private ArrayList<String> filteredData = null;
private ItemFilter mFilter = new ItemFilter();
private ArrayList<String> stringArray;
private Context context;
public MyAdapter(Context _context, ArrayList<String> arr) {
stringArray = arr;
filteredData = arr;
context = _context;
}
public int getCount() {
return stringArray.size();
}
public Object getItem(int arg0) {
return stringArray.get(arg0);
}
public long getItemId(int arg0) {
return 0;
}
public View getView(int position, View v, ViewGroup parent) {
LayoutInflater inflate = (( Activity ) context).getLayoutInflater();
View view = (View) inflate.inflate(R.layout.listview_row, null);
LinearLayout header = (LinearLayout) view.findViewById(R.id.section);
String label = stringArray.get(position);
char firstChar = label.toUpperCase().charAt(0);
if (position == 0) {
setSection(header, label);
} else {
String preLabel = stringArray.get(position - 1);
char preFirstChar = preLabel.toUpperCase().charAt(0);
if (firstChar != preFirstChar) {
setSection(header, label);
} else {
header.setVisibility(View.GONE);
}
}
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(label);
return view;
}
private void setSection(LinearLayout header, String label) {
TextView text = new TextView(context);
//#33D633
header.setBackgroundColor(0xff33D633);
text.setTextColor(Color.BLACK);
text.setText(label.substring(0, 1).toUpperCase());
text.setTextSize(20);
text.setPadding(5, 0, 0, 0);
text.setGravity(Gravity.CENTER_VERTICAL);
header.addView(text);
}
public int getPositionForSection(int section) {
if (section == 35) {
return 0;
}
for (int i = 0; i < stringArray.size(); i++) {
String l = stringArray.get(i);
char firstChar = l.toUpperCase().charAt(0);
if (firstChar == section) {
return i;
}
}
return -1;
}
public int getSectionForPosition(int arg0) {
return 0;
}
public Object[] getSections() {
return null;
}
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 = stringArray;
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();
}
}
MainActivity.class:
String searchString;
MyAdapter adapter;
ArrayList<String> stringList, searchResults;
etSearch.addTextChangedListener(new TextWatcher (){
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
Log.e("TAG", cs.toString());
adapter.getFilter().filter(cs.toString());
}
});
private ArrayList<String> InitListViewData() {
String[] allWords = dbHelper.getAllWords();
stringList = new ArrayList<String>(Arrays.asList(allWords));
return stringList;
}
private void initControls(View rootView) {
etSearch = (EditText) rootView.findViewById(R.id.etSearch);
listView1 = (ListView) rootView.findViewById(R.id.myListView);// list view finding
// Adding data to array lists
listView1.setTextFilterEnabled(true);
dbConnect();
stringList = InitListViewData();
adapter = new MyAdapter(getActivity(), stringList);
listView1.setAdapter(adapter);
SideBar indexBar = (SideBar) rootView.findViewById(R.id.sideBar);
indexBar.setListView(listView1);
listView1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
//TextView tvChild = (TextView) v.findViewById(R.id.tvChild);
String selected = parent.getItemAtPosition(pos).toString();
//tvChild.getText().toString().trim();
Toast.makeText(getActivity(), "" + selected, Toast.LENGTH_SHORT).show();
}
});
}
But it's not filtering at all :( I wonder why. I already attached addTextChangedListener to my editText and added getFilter method in my BasedAdapter to no avail. Any ideas? I would gladly appreciate your help. thanks!
you can do custom search like this, pass the string value from editext on text changed method to this method.
public ArrayList<String> matchedValue(String value)
{
ArrayList<String> local=new ArrayList<String>();
for(int i=0;i<Stringarray.size();i++)
{
if(Stringarray.contains(value))
{
local.add(Stringarray.get(i));
}
}
return local;
}
it will return the matched value then update the listview adapter using this returned arraylist.