I need to let the user to choose city in the preferences, there are many cities so I used this project to search in the list, its working great, but I need to implement it inside preferences xml, and not in a regular layout.
here is what I had before, [Main Activity class, works fine in regular layout]:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* Getting array of String to Bind in Spinner
*/
final List<String> list = Arrays.asList(getResources().getStringArray(R.array.sports_array));
/**
* Search MultiSelection Spinner (With Search/Filter Functionality)
*
* Using MultiSpinnerSearch class
*/
MultiSpinnerSearch searchSpinner = (MultiSpinnerSearch) findViewById(R.id.searchMultiSpinner);
final List<KeyPairBoolData> listArray = new ArrayList<KeyPairBoolData>();
for(int i=0; i<list.size(); i++) {
KeyPairBoolData h = new KeyPairBoolData();
h.setId(i+1);
h.setName(list.get(i));
h.setSelected(false);
listArray.add(h);
}
/***
* -1 is no by default selection
* 0 to length will select corresponding values
*/
searchSpinner.setItems(listArray, "Multi Selection With Filter", -1, new MultiSpinnerSearchListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
for(int i=0; i<items.size(); i++) {
if(items.get(i).isSelected()) {
Log.i("TAG", i + " : " + items.get(i).getName() + " : " + items.get(i).isSelected());
}
}
}
});
}
in the layout I had:
<com.androidbuts.multispinnerfilter.MultiSpinnerSearch
android:id="#+id/searchMultiSpinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_marginTop="20dp" >
</com.androidbuts.multispinnerfilter.MultiSpinnerSearch>
and the original class was:
public class MultiSpinnerSearch extends Spinner implements OnCancelListener {
private List<KeyPairBoolData> items;
//private boolean[] selected;
private String defaultText;
private MultiSpinnerSearchListener listener;
MyAdapter adapter;
public MultiSpinnerSearch(Context context) {
super(context);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuffer spinnerBuffer = new StringBuffer();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected() == true) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = "";
spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = spinnerText.substring(0, spinnerText.length() - 2);
else
spinnerText = defaultText;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { spinnerText });
setAdapter(adapterSpinner);
if(adapter != null)
adapter.notifyDataSetChanged();
listener.onItemsSelected(items);
}
#Override
public boolean performClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(defaultText);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
//builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// items = (ArrayList<KeyPairBoolData>) adapter.arrayList;
Log.i("TAG", " ITEMS : " + items.size() );
dialog.cancel();
}
});
builder.setOnCancelListener(this);
builder.show();
return true;
}
public void setItems(List<KeyPairBoolData> items, String allText, int position,
MultiSpinnerSearchListener listener) {
this.items = items;
this.defaultText = allText;
this.listener = listener;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { defaultText });
setAdapter(adapterSpinner);
if(position != -1)
{
items.get(position).setSelected(true);
//listener.onItemsSelected(items);
onCancel(null);
}
}
public interface MultiSpinnerSearchListener {
public void onItemsSelected(List<KeyPairBoolData> items);
}
// // Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<KeyPairBoolData> arrayList;
List<KeyPairBoolData> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<KeyPairBoolData> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.alert_dialog_listview_search_subview, null);
holder.textView = (TextView) convertView.findViewById(R.id.alertTextView);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final KeyPairBoolData data = arrayList.get(position);
holder.textView.setText(data.getName());
holder.checkBox.setChecked(data.isSelected());
convertView.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ViewHolder temp = (ViewHolder) v.getTag();
temp.checkBox.setChecked(!temp.checkBox.isChecked());
int len = arrayList.size();
for (int i = 0; i < len; i++)
{
if (i == position)
{
data.setSelected(!data.isSelected());
Log.i("TAG", "On Click Selected : " + data.getName() + " : " + data.isSelected());
break;
}
}
}
});
holder.checkBox.setTag(holder);
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<KeyPairBoolData>) 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
List<KeyPairBoolData> FilteredArrList = new ArrayList<KeyPairBoolData>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<KeyPairBoolData>(arrayList); // 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++) {
Log.i("TAG", "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
}
And here is what I'm trying to do, PreferencesSpinner Class (almost same as above):
public class PreferencesSpinner extends DialogPreference implements OnCancelListener {
private List<KeyPairBoolData> items;
public Spinner spinner;
//private boolean[] selected;
private String defaultText;
private PreferencesSpinnerListener listener;
MyAdapter adapter;
public PreferencesSpinner(Context context) {
super(context);
}
public PreferencesSpinner(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public PreferencesSpinner(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuffer spinnerBuffer = new StringBuffer();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected() == true) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = "";
spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = spinnerText.substring(0, spinnerText.length() - 2);
else
spinnerText = defaultText;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { spinnerText });
spinner.setAdapter(adapterSpinner);
if(adapter != null)
adapter.notifyDataSetChanged();
listener.onItemsSelected(items);
}
public boolean performClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(defaultText);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
//builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// items = (ArrayList<KeyPairBoolData>) adapter.arrayList;
Log.i("TAG", " ITEMS : " + items.size() );
dialog.cancel();
}
});
builder.setOnCancelListener(this);
builder.show();
return true;
}
public void setItems(List<KeyPairBoolData> items, String allText, int position,
PreferencesSpinnerListener listener) {
this.items = items;
this.defaultText = allText;
this.listener = listener;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { defaultText });
spinner.setAdapter(adapterSpinner);
if(position != -1)
{
items.get(position).setSelected(true);
//listener.onItemsSelected(items);
onCancel(null);
}
}
public interface PreferencesSpinnerListener {
public void onItemsSelected(List<KeyPairBoolData> items);
}
// // Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<KeyPairBoolData> arrayList;
List<KeyPairBoolData> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<KeyPairBoolData> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.alert_dialog_listview_search_subview, null);
holder.textView = (TextView) convertView.findViewById(R.id.alertTextView);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final KeyPairBoolData data = arrayList.get(position);
holder.textView.setText(data.getName());
holder.checkBox.setChecked(data.isSelected());
convertView.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ViewHolder temp = (ViewHolder) v.getTag();
temp.checkBox.setChecked(!temp.checkBox.isChecked());
int len = arrayList.size();
for (int i = 0; i < len; i++)
{
if (i == position)
{
data.setSelected(!data.isSelected());
Log.i("TAG", "On Click Selected : " + data.getName() + " : " + data.isSelected());
break;
}
}
}
});
holder.checkBox.setTag(holder);
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<KeyPairBoolData>) 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
List<KeyPairBoolData> FilteredArrList = new ArrayList<KeyPairBoolData>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<KeyPairBoolData>(arrayList); // 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++) {
Log.i("TAG", "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
}
with Preferences.xml:
<com.androidbuts.multispinnerfilter.PreferencesSpinner
android:key="spinner"
android:title="spinner Title"
android:summary="Summary"/>
and of course, Preferences class:
public class Preferences extends PreferenceActivity {
public PreferencesSpinner searchSpinner;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
final List<String> list = Arrays.asList(getResources().getStringArray(R.array.sports_array));
final List<KeyPairBoolData> listArray = new ArrayList<KeyPairBoolData>();
for(int i=0; i<list.size(); i++) {
KeyPairBoolData h = new KeyPairBoolData();
h.setId(i+1);
h.setName(list.get(i));
h.setSelected(false);
listArray.add(h);
}
searchSpinner = (PreferencesSpinner) findPreference("spinner");
searchSpinner.setItems(listArray, "all text", -1, new PreferencesSpinner.PreferencesSpinnerListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
}
});
}
anyone can help me with the migration to preferences Activity?
Thanks!
Whoever need it, Here is the answer:
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
final List<String> list = Arrays.asList(view.getResources().getStringArray(R.array.sports_array));
final List<KeyPairBoolData> listArray = new ArrayList<KeyPairBoolData>();
for(int i=0; i<list.size(); i++) {
KeyPairBoolData h = new KeyPairBoolData();
h.setId(i+1);
h.setName(list.get(i));
h.setSelected(false);
listArray.add(h);
}
setItems(listArray, "all text", -1, new PreferencesSpinnerListener() {
#Override
public void onItemsSelected(List<KeyPairBoolData> items) {
}
});
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
//builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// items = (ArrayList<KeyPairBoolData>) adapter.arrayList;
Log.i("TAG", " ITEMS : " + items.size() );
dialog.cancel();
}
});
builder.setOnCancelListener(this);
}
Hope that's help..
Related
I recently posted my Question for MultiSpinner values to choose Multiple values from Spinner dialog. I've done successfully with following class.
MultiSpinnerSearch.java
package com.example.multiplechoicelistwithfilter;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
public class MultiSpinnerSearch extends Spinner implements OnCancelListener {
private List<Hello> items;
//private boolean[] selected;
private String defaultText;
private MultiSpinnerListener listener;
public MultiSpinnerSearch(Context context) {
super(context);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuffer spinnerBuffer = new StringBuffer();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected() == true) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = "";
spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = spinnerText.substring(0, spinnerText.length() - 2);
else
spinnerText = defaultText;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_dropdown_item_1line,
new String[] { spinnerText });
setAdapter(adapter);
listener.onItemsSelected(items);
}
#Override
public boolean performClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(defaultText);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
final MyAdapter adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
//builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SparseBooleanArray sp = listView.getCheckedItemPositions();
for(int i=0;i<items.size();i++) {
items.get(i).setSelected(sp.get(i));
}
dialog.cancel();
}
});
builder.setOnCancelListener(this);
builder.show();
return true;
}
public void setItems(List<Hello> items, String allText, int position,
MultiSpinnerListener listener) {
this.items = items;
this.defaultText = allText;
this.listener = listener;
// all selected by default
//selected = new boolean[items.size()];
//for (int i = 0; i < selected.length; i++)
// selected[i] = false;
if(position != -1)
{
items.get(position).setSelected(true);
listener.onItemsSelected(items);
onCancel(null);
}
}
public interface MultiSpinnerListener {
public void onItemsSelected(List<Hello> items);
}
}
MyAdapter class:
package com.example.multiplechoicelistwithfilter;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
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.CheckedTextView;
import android.widget.Filter;
import android.widget.Filterable;
public class MyAdapter extends BaseAdapter implements Filterable {
List<Hello> arrayList;
List<Hello> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<Hello> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
CheckedTextView textView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(android.R.layout.select_dialog_multichoice, null);
holder.textView = (CheckedTextView) convertView;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(arrayList.get(position).getName());
holder.textView.setChecked(arrayList.get(position).isSelected());
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<Hello>) 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
List<Hello> FilteredArrList = new ArrayList<Hello>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<Hello>(arrayList); // 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++) {
Log.i("TAG", "" + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
I am getting output successfully as below, but in first image suppose
i am select first two image and then filtering word 'ball' it gives me
filtered result with selected checkbox as before.
You can see that first two items not selected before but it shows
selected while filtering.
I am stuck with this silly problem since last couple of hours. Help me.
Your help would be appreciated. Thanks.
I have created my own lib and uploaded on Git:
May It will help you all:
MultiSelectSpinner is allows to Select Multiple Items from Spinner and SEARCH/ FILTER Item from Spinner Items.
public class MultiSpinnerSearch extends Spinner implements OnCancelListener {
private List<KeyPairBoolData> items;
//private boolean[] selected;
private String defaultText;
private MultiSpinnerSearchListener listener;
MyAdapter adapter;
public MultiSpinnerSearch(Context context) {
super(context);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
#Override
public void onCancel(DialogInterface dialog) {
// refresh text on spinner
StringBuffer spinnerBuffer = new StringBuffer();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).isSelected() == true) {
spinnerBuffer.append(items.get(i).getName());
spinnerBuffer.append(", ");
}
}
String spinnerText = "";
spinnerText = spinnerBuffer.toString();
if (spinnerText.length() > 2)
spinnerText = spinnerText.substring(0, spinnerText.length() - 2);
else
spinnerText = defaultText;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { spinnerText });
setAdapter(adapterSpinner);
if(adapter != null)
adapter.notifyDataSetChanged();
listener.onItemsSelected(items);
}
#Override
public boolean performClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(defaultText);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View view = inflater.inflate(R.layout.alert_dialog_listview_search, null);
builder.setView(view);
final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setFastScrollEnabled(false);
adapter = new MyAdapter(getContext(), items);
listView.setAdapter(adapter);
EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
//builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// items = (ArrayList<KeyPairBoolData>) adapter.arrayList;
Log.i("TAG", " ITEMS : " + items.size() );
dialog.cancel();
}
});
builder.setOnCancelListener(this);
builder.show();
return true;
}
public void setItems(List<KeyPairBoolData> items, String allText, int position,
MultiSpinnerSearchListener listener) {
this.items = items;
this.defaultText = allText;
this.listener = listener;
ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(),
R.layout.textview_for_spinner,
new String[] { defaultText });
setAdapter(adapterSpinner);
if(position != -1)
{
items.get(position).setSelected(true);
//listener.onItemsSelected(items);
onCancel(null);
}
}
public interface MultiSpinnerSearchListener {
public void onItemsSelected(List<KeyPairBoolData> items);
}
// // Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<KeyPairBoolData> arrayList;
List<KeyPairBoolData> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<KeyPairBoolData> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.alert_dialog_listview_search_subview, null);
holder.textView = (TextView) convertView.findViewById(R.id.alertTextView);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final KeyPairBoolData data = arrayList.get(position);
holder.textView.setText(data.getName());
holder.checkBox.setChecked(data.isSelected());
convertView.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ViewHolder temp = (ViewHolder) v.getTag();
temp.checkBox.setChecked(!temp.checkBox.isChecked());
int len = arrayList.size();
for (int i = 0; i < len; i++)
{
if (i == position)
{
data.setSelected(!data.isSelected());
Log.i("TAG", "On Click Selected : " + data.getName() + " : " + data.isSelected());
break;
}
}
}
});
holder.checkBox.setTag(holder);
return convertView;
}
#SuppressLint("DefaultLocale")
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<KeyPairBoolData>) 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
List<KeyPairBoolData> FilteredArrList = new ArrayList<KeyPairBoolData>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<KeyPairBoolData>(arrayList); // 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++) {
Log.i("TAG", "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected());
String data = mOriginalValues.get(i).getName();
if (data.toLowerCase().contains(constraint.toString())) {
FilteredArrList.add(mOriginalValues.get(i));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
}
Thanks :) Keep Sharing :)
In android How to use searchview in listview ?
Listview conatins imageview and multiple textviews
when I used to to type some text in search the list view want to display based on my search
How to perform this
Thanks in advance
Create a custom adapter like this
public class PlanetAdapter extends ArrayAdapter<Planet> implements Filterable {
private List<Planet> planetList;
private Context context;
private Filter planetFilter;
private List<Planet> origPlanetList;
public PlanetAdapter(List<Planet> planetList, Context ctx) {
super(ctx, R.layout.img_row_layout, planetList);
this.planetList = planetList;
this.context = ctx;
this.origPlanetList = planetList;
}
public int getCount() {
return planetList.size();
}
public Planet getItem(int position) {
return planetList.get(position);
}
public long getItemId(int position) {
return planetList.get(position).hashCode();
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
PlanetHolder holder = new PlanetHolder();
// First let's verify the convertView is not null
if (convertView == null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.img_row_layout, null);
// Now we can fill the layout with the right values
TextView tv = (TextView) v.findViewById(R.id.name);
TextView distView = (TextView) v.findViewById(R.id.dist);
holder.planetNameView = tv;
holder.distView = distView;
v.setTag(holder);
}
else
holder = (PlanetHolder) v.getTag();
Planet p = planetList.get(position);
holder.planetNameView.setText(p.getName());
holder.distView.setText("" + p.getDistance());
return v;
}
public void resetData() {
planetList = origPlanetList;
}
/* *********************************
* We use the holder pattern
* It makes the view faster and avoid finding the component
* **********************************/
private static class PlanetHolder {
public TextView planetNameView;
public TextView distView;
}
/*
* We create our filter
*/
#Override
public Filter getFilter() {
if (planetFilter == null)
planetFilter = new PlanetFilter();
return planetFilter;
}
private class PlanetFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = origPlanetList;
results.count = origPlanetList.size();
}
else {
// We perform filtering operation
List<Planet> nPlanetList = new ArrayList<Planet>();
for (Planet p : planetList) {
if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
nPlanetList.add(p);
}
results.values = nPlanetList;
results.count = nPlanetList.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
planetList = (List<Planet>) results.values;
notifyDataSetChanged();
}
}
}
}
Create POJO(getter setter class) for planets
then in your activity
// The data to show
List<Planet> planetsList = new ArrayList<Planet>();
PlanetAdapter aAdpt;
ListView lv = (ListView) findViewById(R.id.listView);
aAdpt = new PlanetAdapter(planetsList, this);
lv.setAdapter(aAdpt);
you can use like this for filtering
// TextFilter
lv.setTextFilterEnabled(true);
EditText editTxt = (EditText) findViewById(R.id.editTxt);
editTxt.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"] - Start ["+start+"] - Before ["+before+"] - Count ["+count+"]");
if (count < before) {
// We're deleting char so we need to reset the adapter data
aAdpt.resetData();
}
aAdpt.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
iam solved this problem , also using base adapter You can try this
public class SubjectsActivity extends Activity {
private ImageView imgNavBarSubjectBook;
private ArrayList<String> arrSubjectResponse;
private ArrayList<String> arrChapterName;
private ArrayList<String> arrFileUrl;
private ArrayList<String> arrFileSize;
private ListView listChapter;
private TextView subjectName;
private EditText edtSearch;
private int textlength = 0;
// Google Analytics starts from here
private EasyTracker easyTracker = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_subjects);
easyTracker = EasyTracker.getInstance(SubjectsActivity.this);
subjectName = (TextView) findViewById(R.id.txtSubjectName);
imgNavBarSubjectBook = (ImageView) findViewById(R.id.img_nav_bar_Subject_book);
arrSubjectResponse = new ArrayList<String>();
arrChapterName = new ArrayList<String>();
arrFileUrl = new ArrayList<String>();
arrFileSize = new ArrayList<String>();
imgNavBarSubjectBook.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
Typeface tf = Typeface.createFromAsset(getAssets(), "Georgia.ttf");
subjectName.setTypeface(tf, Typeface.BOLD);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
arrSubjectResponse = bundle
.getStringArrayList("arr_subject_response");
for (int i = 1; i < arrSubjectResponse.size(); i = i + 8) {
arrChapterName.add(arrSubjectResponse.get(i + 2));
arrFileUrl.add(arrSubjectResponse.get(i + 6));
arrFileSize.add(arrSubjectResponse.get(i + 5));
}
}
listChapter = (ListView) findViewById(R.id.listChapter);
subjectName.setText(CoursesAdapter.Subject_Name);
listChapter.setAdapter(new SubjectAdapter(SubjectsActivity.this,
arrChapterName, arrFileUrl, arrFileSize));
edtSearch = (EditText) findViewById(R.id.edtSearchSubjects);
edtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
textlength = edtSearch.getText().length();
arrChapterName.clear();
arrFileUrl.clear();
for (int i = 1; i < arrSubjectResponse.size(); i = i + 8) {
String name = arrSubjectResponse.get(i + 2);
String searchtext = String.valueOf(s);// edtSearch.getText().toString();
if (textlength <= arrSubjectResponse.get(i + 2).length()) {
if (name.toLowerCase().indexOf
(searchtext.toLowerCase()) != -1) {
Log.d("",
"------------Entered add value to list-----");
arrChapterName.add(arrSubjectResponse.get(i + 2));
arrFileUrl.add(arrSubjectResponse.get(i + 6));
arrFileSize.add(arrSubjectResponse.get(i + 5));
}
}
}
listChapter.setAdapter(new SubjectAdapter(
SubjectsActivity.this, arrChapterName, arrFileUrl,
arrFileSize));
Log.d("", "Chapter------->" + arrChapterName);
Log.d("", "Fileurl---------->" + arrFileUrl);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
#Override
public void onStart() {
super.onStart();
EasyTracker.getInstance(this).activityStart(this);
}
#Override
public void onStop() {
super.onStop();
EasyTracker.getInstance(this).activityStop(this);
}
}
Here is the code, I used a custom adapter, and applied the Filter method, now the ListView does not update when the backspace key is entered, on when one switches back from an item activity. please help me.. and how to display no result to filtered list..
public class ItemListAdapter extends ArrayAdapter<ItemVO>
{
private ArrayList<ItemVO> itemList;
private ArrayList<ItemVO> fiems;
private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
private Context context;
private Filter filter;
public ItemListAdapter(Context context, int textViewResourceId,ArrayList<ItemVO> stateList)
{
super(context, textViewResourceId, stateList);
this.context = context;
this.itemList = new ArrayList<ItemVO>();
this.itemList.addAll(stateList);
this.fiems=new ArrayList<ItemVO>();
this.fiems.addAll(stateList);
}
private class ViewHolder
{
TextView code;
CheckBox name;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null)
{
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.listview_items, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.textView1);
holder.name = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
holder.name.setOnClickListener( new View.OnClickListener()
{
public void onClick(View v)
{
CheckBox cb = (CheckBox) v;
ItemVO item = (ItemVO) cb.getTag();
item.setSelected(cb.isChecked());
}
});
}
else
{
holder = (ViewHolder) convertView.getTag();
}
ItemVO state = itemList.get(position);
holder.code.setText(state.getItemdescription());
holder.name.setChecked(state.isSelected());
holder.name.setTag(state);
return convertView;
}
#Override
public Filter getFilter()
{
if (filter == null)
filter = new PkmnNameFilter();
return filter;
}
private class PkmnNameFilter extends Filter
{
#SuppressWarnings("unused")
#SuppressLint("DefaultLocale")
#Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values
String prefix = constraint.toString().toLowerCase();
if (prefix == null || prefix.length() == 0)
{
ArrayList<ItemVO> list = new ArrayList<ItemVO>(fiems);
results.values = list;
results.count = list.size();
}
else
{
final ArrayList<ItemVO> list = new ArrayList<ItemVO>(fiems);
final ArrayList<ItemVO> nlist = new ArrayList<ItemVO>();
int count = list.size();
for (int i=0; i<count; i++)
{
final ItemVO pkmn = list.get(i);
final String value = pkmn.getItemdescription().toLowerCase();
if (value.startsWith(prefix))
{
nlist.add(pkmn);
}
/*else
{
final Toast toast= Toast.makeText(context, "No Items Found", Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 1000);
}*/
}
// set the Filtered result to return
results.values = nlist;
results.count = nlist.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
itemList = (ArrayList<ItemVO>)results.values; // has the filtered values
clear();
int count = itemList.size();
for (int i=0; i<count; i++)
{
ItemVO pkmn = (ItemVO)itemList.get(i);
add(pkmn);
notifyDataSetChanged(); // notifies the data with new filtered values
}
}
}
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
boolean notifyChanged = true;
}
}
In main activity for editetxt..
dataAdapter = new ItemListAdapter(this,R.layout.listview_items, itemList);
lv.setAdapter(dataAdapter);
final EditText searchBox=(EditText) findViewById(R.id.filter_text);
//searchBox.addTextChangedListener(this);
lv.setTextFilterEnabled(true);
// Add Text Change Listener to EditText
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// Call back the Adapter with current character to Filter
Log.d("Constants.TAG", "*** Search value changed: " + cs.toString());
CateringList.this.dataAdapter.getFilter().filter(cs);
dataAdapter.notifyDataSetChanged();
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }
#Override
public void afterTextChanged(Editable arg0) {
//if(arg0.length()==0)
// {
// }
}
});
You just need a validation if the ArrayList have data put it in your getView() method
if (itemList == null || itemList.size() == 0){
//do your code here
holder.code.setText("No Result");
}
Brother change this line:
clear();
int count = itemList.size();
for (int i=0; i<count; i++)
{
ItemVO pkmn = (ItemVO)itemList.get(i);
add(pkmn);
notifyDataSetChanged();
}
To this:
itemList = (ArrayList<ItemVO>)results.values;
notifyDataSetChanged();
Try this one:
private ArrayList<ItemVO> mItemList;
public Filter getFilter()
{
return new Filter(){
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oResults = new FilterResults();
final ArrayList<ItemVO> result = new ArrayList<ItemVO>();
If (mItemList == null)
mItemList = itemList;
if (constraint != null){
if (mItemList != null && mItemList.size > 0){
//loop
for (final ItemVO item : mItemList){
final String value = item.getItemdescription().toLowerCase();
if (value.startsWith(constraint.toString())){
result.add(item);
}
}
}
}
}
oResults.values = result;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
itemList = (ArrayList<ItemVO>)results.values;
notifyDataSetChanged();
}
}
this is happening because listItems of your adapter are removed, but when you press backspace, they are not added back. For example,you have total 10 items in recyclerview, when you press 'A' you get 4 filtered items. Here 6 items removed from your actual listItems( which had 10 items before). But these removed items never added back.
Solution:
Check backpress and before filtering, make temp copy of you fullList First. And call filtering.
I am not sure if i can help you. Try to change this:
CateringList.this.dataAdapter.getFilter().filter(cs);
dataAdapter.notifyDataSetChanged();
You access dataAdapter in two different ways, and also i think you don't need to call here notifyDataSetChanged, so put instead:
dataAdapter.getFilter().filter(cs);
Also, if you want to display list with no results rty:
dataAdapter.getFilter().filter("");
EDIT :
Add this code to listen for edit text changes:
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) {
Log.d("Constants.TAG", "*** Search value changed: " + cs.toString());
dataAdapter.getFilter().filter(cs);
};
And after initializing EditText put:
searchBox.addTextChangedListener(filterTextWatcher);
EDIT 2:
Change this:
if (prefix == null || prefix.length() == 0)
{
//ArrayList<ItemVO> list = new ArrayList<ItemVO>(fiems);
results.values = null;
results.count = 0;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
itemList = (ArrayList<ItemVO>)results.values; // has the filtered values
if(itemList != null) {
clear();
int count = itemList.size();
for (int i=0; i<count; i++)
{
ItemVO pkmn = (ItemVO)itemList.get(i);
add(pkmn);
}
notifyDataSetChanged(); // notifies the data with new filtered values
}
I've solved with this workaround... hope this one suit to you as well :)
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// Call back the Adapter with current character to Filter
Log.d("Constants.TAG", "*** Search value changed: " + cs.toString());
CateringList.this.dataAdapter.getFilter().filter(cs);
dataAdapter.notifyDataSetChanged();
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
dataAdapter.itemList = OriginalItemList;
}
#Override
public void afterTextChanged(Editable arg0) {
//if(arg0.length()==0)
// {
// }
}
});
before the search search text was changed... just assign back the original data state to the adapter to filter again.
Every time you call onQueryTextChange, just refresh the data to your recyclerview
#Override
public boolean onQueryTextChange(String newText) {
rvAdapter = new RecyclerViewAdapter(Context, <list of files>);
recyclerView.setAdapter(rvAdapter);
rvAdapter.getFilter().filter(newText);
return true;
}
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.
I'm trying to filter a listview with arrayadapter. The arraydapter parameter is a String[][]. The problem is that anything happens. I must override the Filter interface? In that case plase, can someone provide some hints?
Every position of the array I'm trying to filter is like
galleryValues[0][0] -> "tiulo"
[0][1] -> "desc"
[0][2] -> "etc"
I tryied to filter it:
lstContinente = (ListView)findViewById(R.id.list);
lstContinente.setTextFilterEnabled(true);
adapter = new PortaitArrayAdapter(cx,galleryValues);
lstContinente.setAdapter(adapter);
ed_busqueda.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
adapter.notifyDataSetChanged();
}
});
The adapter code:
public class PortaitArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[][] values;
private List<Imagen> imagenes = null;
private LayoutInflater mInflater;
public ImageLoader imageLoader;
public PortaitArrayAdapter(Context context, String[][] values) {
super(context, R.layout.gallery_row);
this.context = context;
this.values = values;
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imagenes = new ArrayList<Imagen>();
for (int i = 0; i < 20; i++) imagenes.add(new Imagen());
Bitmap def = BitmapFactory.decodeResource(this.context.getResources(),R.drawable.ic_launcher);
imageLoader=new ImageLoader(this.context,def, imagenes);
}
#Override
public int getCount (){
return this.values.length;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.gallery_row, parent, false);
holder.txtTitulo = (TextView) convertView.findViewById(R.id.txt_gallery_titulo);
holder.txtDesc = (TextView) convertView.findViewById(R.id.txt_gallery_desc);
holder.txtFecha = (TextView) convertView.findViewById(R.id.txt_gallery_fecha);
holder.txtEst = (TextView) convertView.findViewById(R.id.txt_gallery_est);
holder.imageView = (ImageView)convertView.findViewById(R.id.lst_img_gallery);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
/*LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.gallery_row, parent, false);*/
//ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
Bitmap bmp;
Log.v("Position --> ",String.valueOf(position));
try {
byte b[] = imagenes.get(position).getImageData();
if (b != null) {
bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
if (bmp != null) holder.imageView.setImageBitmap(bmp);
} else {
String urlBase = galleryValues[position][0].substring(0, galleryValues[position][0].lastIndexOf("/")+1);
String urlToEncode = galleryValues[position][0].substring(galleryValues[position][0].lastIndexOf("/")+1, galleryValues[position][0].length());
urlToEncode = URLEncoder.encode(urlToEncode,"UTF-8");
String url = urlBase.concat(urlToEncode);
url = url.replace("+", "%20");
Log.v("UrlFinal --> ",url);
imageLoader.DisplayImage(String.valueOf(position),url,act,holder.imageView, position,null);
}
} catch (Exception e) {
Log.e(this.getClass().getName(),"Exception en pos = " + position + " error:" + e.getMessage());
e.printStackTrace();
}
holder.txtTitulo.setText(galleryValues[position][1] + ", " + galleryValues[position][2]);
String[] dates = galleryValues[position][4].split("/");
String date = dates [1] + "/" + dates[0] + "/" + dates[2];
Date d1 = new Date(date);
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
holder.txtDesc.setText(galleryValues[position][3]);
holder.txtFecha.setText(df.format(d1));
holder.txtEst.setText(getText(R.string.num_fotos_gallery) + galleryValues[position][5] + " - " + getText(R.string.num_videos_gallery) + galleryValues[position][6] + " - " + getText(R.string.num_exp_gallery) + galleryValues[position][7]);
return convertView;
}
}
private static class ViewHolder {
TextView txtTitulo;
TextView txtDesc;
TextView txtFecha;
TextView txtEst;
ImageView imageView;
}
Convert your String array to ArrayList and pass it to Adapter and use below code or change below code with your String[].
You need to implement Filterable to your Adapter class and Override getFilter()
Checkout this complete example for filtering custom Adapter.
public class ListFilterActivity extends ListActivity {
private List<String> list = new ArrayList<String>();
List<String> mOriginalValues;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MyAdapter adapter = new MyAdapter(this, getModel());
setListAdapter(adapter);
EditText filterEditText = (EditText) findViewById(R.id.filterText);
// Add Text Change Listener to EditText
filterEditText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Call back the Adapter with current character to Filter
adapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
private List<String> getModel() {
list.add("Linux");
list.add("Windows7");
list.add("Suse");
list.add("Eclipse");
list.add("Ubuntu");
list.add("Solaris");
list.add("Android");
list.add("iPhone");
list.add("Windows XP");
return list;
}
}
// Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
List<String> arrayList;
List<String> mOriginalValues; // Original Values
LayoutInflater inflater;
public MyAdapter(Context context, List<String> arrayList) {
this.arrayList = arrayList;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView textView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row, null);
holder.textView = (TextView) convertView
.findViewById(R.id.textview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(arrayList.get(position));
return convertView;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,FilterResults results) {
arrayList = (List<String>) 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
List<String> FilteredArrList = new ArrayList<String>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<String>(arrayList); // 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);
if (data.toLowerCase().startsWith(constraint.toString())) {
FilteredArrList.add(data);
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
Here I mention the code of how We can filter the listView Data using custom Adapter
Its really help you
ListViewAdapter.java
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
public List<AllFoodItem> allFoodItemlist;
public ArrayList<AllFoodItem> arraylist;
public ListViewAdapter(Context context, List<AllFoodItem> allFoodItemlist) {
mContext = context;
this.allFoodItemlist = allFoodItemlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<AllFoodItem>();
this.arraylist.addAll(allFoodItemlist);
}
#Override
public int getCount() {
return allFoodItemlist.size();
}
#Override
public AllFoodItem getItem(int position) {
return allFoodItemlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder {
TextView foodname, quantity, calorie;
}
public View getView(final int position, View view, ViewGroup parent) {
Holder holder = new Holder();
view = inflater.inflate(R.layout.program_list, null);
// Locate the TextViews in listview_item.xml
holder.foodname = (TextView) view.findViewById(R.id.textView1);
// Set the results into TextViews holder.foodname.setText(allFoodItemlist.get(position).getName().toString());
return view;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
allFoodItemlist.clear();
if (charText.length() == 0) {
allFoodItemlist.addAll(arraylist);
} else {
for (AllFoodItem wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
allFoodItemlist.add(wp);
}
}
}
notifyDataSetChanged();
}
}
MainActivity.java
use the ListViewAdapter class apply filter on EditText by using filter() method
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
foodname = (inputSearch.getText().toString()).trim();
// filter the data of edit Text using filter method in ListViewAdapter
String text = inputSearch.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 afterTextChanged(Editable arg0) {
userGet();
// TODO Auto-generated method stub
}
});