I have a AutoCompleteTextView in my layout. When a user enter "#" character in that i have to show them some suggestions. It normally names i get it from internet.
I am getting the names and i create an ArrayAdapter as shown below.
autoCtextView.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
String lsatChar = s.toString().substring(s.length()-1,s.length());
if(lsatChar.equals("#")) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(DisplayQuestionDetails.this,
android.R.layout.simple_list_item_1, namesLsist);
autoCtextView.setAdapter(adapter);
}
}
#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
}
});
But the suggestions are not shown. Am i doing anything wrong ? Please ask if need clarification on question
Do you miss autoCtextView.setThreshold(1); ?
(to start working from first character)
for example demo:
String[] strList={"a","aaa","aabb","b","bbc","cbb","c","cdd","caa","d","ddc","dda","e","eea","ebc","aec"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Creating the instance of ArrayAdapter containing list
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.select_dialog_item,strList);
//Getting the instance of AutoCompleteTextView
AutoCompleteTextView autoCtextView= (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
autoCtextView.setThreshold(1); //to start working from first character
autoCtextView.setAdapter(adapter);//set the adapter data to the AutoCompleteTextView
}
After declare autocompleteTextView than fill the first adapter.
like Ref here
public class CountriesActivity extends Activity {
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.countries);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, COUNTRIES);
AutoCompleteTextView textView = (AutoCompleteTextView)
findViewById(R.id.countries_list);
textView.setAdapter(adapter);
}
private static final String[] COUNTRIES = new String[] {
"Belgium", "France", "Italy", "Germany", "Spain"
};
}
In my fragment layout, if I don't use the ems attribute (field size in number of "m"s), the suggestions will not be shown. When it is present, the suggestions are shown.
<AutoCompleteTextView
android:id="#+id/enter_activities_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:ems="10"
android:completionThreshold="1"/>
Do this:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(DisplayQuestionDetails.this, android.R.layout.simple_list_item_1, namesLsist);
autoCtextView.setAdapter(adapter);
Before
autoCtextView.addTextChangedListener(new TextWatcher() {...
I made custom AutoComplete Textbox with the help of this blog. It works when user types "#something", e.g."#f" then all the names which matches 'f' will come up.
CustomAutoComplete.java
public class CustomAutoComplete extends AutoCompleteTextView {
private String previous = "";
private String seperator = "#";
public CustomAutoComplete(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
this.setThreshold(0);
}
public CustomAutoComplete(final Context context, final AttributeSet attrs) {
super(context, attrs);
this.setThreshold(0);
}
public CustomAutoComplete(final Context context) {
super(context);
this.setThreshold(0);
}
/**
* This method filters out the existing text till the separator
* and launched the filtering process again
*/
#Override
protected void performFiltering(final CharSequence text, final int keyCode) {
String filterText = text.toString().trim();
previous = filterText.substring(0, filterText.lastIndexOf(getSeperator()) + 1);
filterText = filterText.substring(filterText.lastIndexOf(getSeperator()) + 1);
if (!TextUtils.isEmpty(filterText)) {
super.performFiltering(filterText, keyCode);
}
}
/**
* After a selection, capture the new value and append to the existing
* text
*/
#Override
protected void replaceText(final CharSequence text) {
super.replaceText(previous + text + getSeperator());
}
public String getSeperator() {
return seperator;
}
}
Layout file:
<com.example.app.CustomAutoComplete
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/autoCompleteTextView"
android:layout_gravity="center_horizontal|top" />
MainActivity:
public class MainActivity extends ActionBarActivity {
CustomAutoComplete autoCompleteTextView;
String[] namesLsist = {"zivame","ziooo","zoooO","flipme","flipkart"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
autoCompleteTextView = (CustomAutoComplete) findViewById(R.id.autoCompleteTextView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1, namesLsist);
autoCompleteTextView.setAdapter(adapter);
}
}
Related
I'm using array adapter to implement a search view to search for hard coded elements
my code as follows
public class MainActivity extends AppCompatActivity {
ListView list;
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.toolbar);
list = (ListView) findViewById(R.id.list_view);
EditText edittext = (EditText) findViewById(R.id.editText);
edittext.addTextChangedListener(textWatcher);
adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.row_item, COUNTRIES);
}
TextWatcher textWatcher = 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) {
if (s.toString().equals(""))
list.setAdapter(null);
else {
adapter.getFilter().filter(s.toString());
adapter.notifyDataSetChanged();
list.setAdapter(adapter);
// adapter.clear();
Log.v("HEY", adapter.getCount() + "");
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
private static final String[] COUNTRIES = new String[]{
"FAAAFA", "France", "FOO"};
}
When i type F in the search for example, the count is printed 0 instead of 3
then when i apply any other query the count is 3 (ie it prints the count of previous query to current one)
So, I have an activity with a TextView and a ListView with a custom BaseAdapter. This activity looks like this:
As you can see, every item of the list is a custom layout and the basic idea is: every time the numeric EditText within it changes, the "total" TextView from the activity (which is the sum of the prices of every product) must be updated as well.
I suppose it must somehow be done from the Adapter class, but I don't know how to do it.
My Activity file looks like this (it gets products data from server via "GetCollectionProducts" AsyncTask, where I set the adapter):
public class ProductAisleActivity extends AppCompatActivity implements View.OnClickListener{
ListView productList;
Button participate;
ImageButton search;
EditText searchET;
TextView productsTotal;
Product[] colProducts;
RelativeLayout collectionHeader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_aisle);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
/* ...
Irrelevant code to this question
*/
productsTotal = (TextView) findViewById(R.id.products_aisle_total);
productsTotal.setText(
getResources().getString(
R.string.productsTotal,
String.valueOf(0.00)
)
);
productList = (ListView) findViewById(R.id.products_aisle_list);
new GetCollectionProducts().execute();
}
private class GetCollectionProducts extends AsyncTask<Void,Void,JSONArray>{
#Override
protected JSONArray doInBackground(Void... voids) {
/* Irrelevant code to this question */
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
/* Irrelevant code to this question */
productList.setAdapter(
new CollectionProductsAdapter(
ProductAisleActivity.this,
colProducts
)
);
}
}
And my Adapter file looks as follows:
public class CollectionProductsAdapter extends BaseAdapter {
Context context;
ProductAisleActivity.Product[] data;
private static LayoutInflater inflater = null;
public CollectionProductsAdapter(Context context, ProductAisleActivity.Product[] data) {
this.context = context;
this.data = data;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int i) {
return data[i];
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
if (v == null) {
v = inflater.inflate(R.layout.product_row_layout, null);
}
ProductAisleActivity.Product product = data[i];
/* ...
Irrelevant code to this question
*/
EditText productQuantity = (EditText) v.findViewById(R.id.productQuantity);
productQuantity.setText("0");
return v;
}
}
I'm stuck at this point, any help will be appreciated.
First you need to listen for any changes in the EditText so you can handle things dynamically without explicitly using something like a submit button. You can do this with a TextWatcher.
productQuanity.addTextChangedListener(new TextWatcher() {
private double originalCost = 0.0;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Before we change the text, set the originalCost
// so we can know what the change is after the edit
originalCost = getCost(s.toString());
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// You don't need to utilize this method
}
#Override
public void afterTextChanged(Editable s) {
// After the change has taken place in the text,
// get the new cost and calculate the difference
double newCost = getCost(s.toString());
double changeInCost = newCost - originalCost;
}
private double getCost(String input){
String count = input.toString();
if(TextUtils.isEmpty(count))
return 0.0;
else
return (double) Integer.parseInt(count) * product.getPrice();
}
});
Now that we have the change in cost, what do we do with it? We need to notify the activity that we have a change. We can do that with an observer, which is fine, but for fun let's use an interface to implement a listener.
Modify your adapter class
public class CollectionProductsAdapter extends BaseAdapter {
public interface CostChangedListener{
void onCostChanged(double change);
}
Context context;
ProductAisleActivity.Product[] data;
private LayoutInflater inflater = null; // THIS SHOULDN'T BE STATIC
CostChangedListener listener;
public CollectionProductsAdapter(Context context, ProductAisleActivity.Product[] data, CostChangedListener listener) {
this.context = context;
this.data = data;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.listener = listener;
}
// The rest of your code
}
Now when we update the cost in our TextWatcher we can call
if(listener != null)
listener.onCostChanged(changeInCost);
Last, to make sure we utilize this correctly, we will need to pass a listener in our CollectionProductsAdapter constructor
productList.setAdapter(new CollectionProductsAdapter(
ProductAisleActivity.this, colProducts,
new CostChangeListener(){
#Override
public void onCostChanged(double change){
double currentTotal = Double.valueOf(productTotal.getText());
double newTotal = currentTotal + change;
productTotal.setText(String.valueOf(newTotal));
}));
Obviously you may need to tweak some of this to get it to match perfectly, and I haven't tested it so some things might be off a bit, but this should get you going in the right direction. If you have any issue feel free to comment and I will try to help you through it.
Notes
Do not keep a static reference like you were with your layout inflater
It is worth taking a look at the RecyclerView or at least the ViewHolder pattern with an Adapter
You want to add a textChangedListener for changing item values as user changes values in EditText.
You can use TextChangedListener here:
EditText myEditTextField = new EditText(this);
myEditTextField.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) {
}
});
You can perform tasks according to your need. It has 3 methods:
1.beforeTextChanged
2.onTextChanged
3.afterTextChanged
So you can get your task done by the help of "afterTextChanged". You have to simply call your method of calculating price for no. of items when user enters a particular number.And it will show you the price as you want.
Hope this help!
I want to create a control in android where user can input through keyboard or enter through drop down list(spinner).
Actually the values I hard code in array in spinner is not exhaustive, so user should have the option to input through virtual keyboard also.
So Either user can enter through keyboard or select from list?
How can i achieve this in android?
You can build your own view:
public class ServerPreference extends DialogPreference {
private String value;
private EditText editText;
private Spinner spinner;
private final int server_list_id;
ArrayList<String> servers;
public ServerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPersistent(false);
setDialogLayoutResource(R.layout.server_preference_layout);
servers = new ArrayList<String>();
Resources r = context.getResources();
if (MySettings.KEY_ASR_SERVER_HOST.equals(getKey())) {
server_list_id = R.array.asrServers;
} else if (MySettings.KEY_LOG_SERVER_HOST.equals(getKey())) {
server_list_id = R.array.logServers;
} else {
server_list_id = R.array.servicesServers;
}
Collections.addAll(servers, r.getStringArray(server_list_id));
}
#Override
protected void onBindDialogView(View view) {
editText = (EditText)view.findViewById(R.id.server_preference_text);
spinner = (Spinner)view.findViewById(R.id.server_preference_spinner);
SharedPreferences pref = getSharedPreferences();
value = pref.getString(getKey(), "");
editText.setText(value);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
view.getContext(), server_list_id, android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource( android.R.layout.simple_dropdown_item_1line );
spinner.setAdapter( adapter );
updateSpinner();
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if ( position != 0 ) {
value = servers.get(position);
editText.setText(value);
}
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateSpinner();
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
});
super.onBindDialogView(view);
}
void updateSpinner() {
value = editText.getText().toString();
int index = servers.indexOf(value);
if ( index == -1 )
index = 0;
spinner.setSelection(index);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
if ( positiveResult ) {
SharedPreferences.Editor editor = getEditor();
editor.putString(getKey(),value);
editor.commit();
}
super.onDialogClosed(positiveResult);
}
public String getValue() {
return value;
}
void setValue(String value) {
this.value = value;
}
}
Layout of custom view:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText android:layout_height="wrap_content" android:layout_width="match_parent" android:id="#+id/server_preference_text" android:inputType="text">
<requestFocus></requestFocus>
</EditText>
<Spinner android:layout_height="wrap_content" android:id="#+id/server_preference_spinner" android:layout_width="match_parent"></Spinner>
</LinearLayout>
When you want to use this view, just define in XML file:
<xxx.xxxxxx.xxxxx.settings.debug.ServerPreference
android:title="ASR/VVS Server"
android:persistent="true"
android:positiveButtonText="OK"
android:dialogTitle="ASR/VVS Server"
android:key="SERVER_NAME"
android:negativeButtonText="Cancel"
android:entryValues="#array/asrServers"
android:entries="#array/asrServers"/>
I have a spinner which is populated using a CursorLoader. It gets populated correctly. However spinner.getAdapter().getCount() keeps returning 0. why is that :(
My spinner class is
public class CategorySpinner extends Spinner implements LoaderManager.LoaderCallbacks<Cursor> {
Context myContext;
private SimpleCursorAdapter adapter;
public CategorySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
myContext=context;
}
public void fillData(int projectId) {
String[] from = new String[] { Category.CATEGORYNAME };
int[] to = new int[] { R.id.label1 };
int layout = R.layout.category_list_item;
Bundle bundle=new Bundle();
bundle.putInt("ID", projectId);
EditExpenseActivity mActivity=(EditExpenseActivity)myContext;
mActivity.getLoaderManager().initLoader(0, bundle,this);
adapter = new SimpleCursorAdapter(myContext, layout, null, from, to, 0);
adapter.setDropDownViewResource(R.layout.category_list_item);
this.setAdapter(adapter);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { Category.FULL_ID,Category.CATEGORYNAME };
Uri uri = Uri.parse(MyContentProvider.CATEGORY_LIST_PATH +args.getInt("ID"));
CursorLoader cursorLoader = new CursorLoader(myContext, uri, projection,null, null, null);
return cursorLoader;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
}
The activity that is calling the spinner is EditExpenseActivity
public class EditExpenseActivity extends Activity {
private Context myContext;
private CategorySpinner sp_Category;
private Intent intent;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_edit_expense);
intent=getIntent();
final int mProjectId=intent.getIntExtra("ID",0);
myContext = this;
sp_Category = (CategorySpinner) findViewById(R.id.input_category);
//fill spinner with categories of the project with Id mProjectId
sp_Category.fillData(mProjectId);
//so far so good .. spinner is populated perfectly
int i=sp_Category.getAdapter().getCount();
}
}
Debug shows i value to be 0. why???
I have a ListView and a EditText. How can I filter ListView data when typing on EditText?
Add TextWatcher to EditText#addTextChangedListener
In onTextChanged add or remove items from your ListView's adapter. If you are subclassing ArrayAdapter it would have add and remove methods
Yes you can, just implement this code. Use the following code to implement search and filter list in android:
SearchAndFilterList.java
public class SearchAndFilterList extends Activity {
private ListView mSearchNFilterLv;
private EditText mSearchEdt;
private ArrayList<String> mStringList;
private ValueAdapter valueAdapter;
private TextWatcher mSearchTw;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_and_filter_list);
initUI();
initData();
valueAdapter=new ValueAdapter(mStringList,this);
mSearchNFilterLv.setAdapter(valueAdapter);
mSearchEdt.addTextChangedListener(mSearchTw);
}
private void initData() {
mStringList=new ArrayList<String>();
mStringList.add("one");
mStringList.add("two");
mStringList.add("three");
mStringList.add("four");
mStringList.add("five");
mStringList.add("six");
mStringList.add("seven");
mStringList.add("eight");
mStringList.add("nine");
mStringList.add("ten");
mStringList.add("eleven");
mStringList.add("twelve");
mStringList.add("thirteen");
mStringList.add("fourteen");
mSearchTw=new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
valueAdapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
};
}
private void initUI() {
mSearchNFilterLv=(ListView) findViewById(R.id.list_view);
mSearchEdt=(EditText) findViewById(R.id.txt_search);
}
}
Custom Value adapter:
ValueAdapter.java
public class ValueAdapter extends BaseAdapter implements Filterable{
private ArrayList<String> mStringList;
private ArrayList<String> mStringFilterList;
private LayoutInflater mInflater;
private ValueFilter valueFilter;
public ValueAdapter(ArrayList<String> mStringList,Context context) {
this.mStringList=mStringList;
this.mStringFilterList=mStringList;
mInflater=LayoutInflater.from(context);
getFilter();
}
//How many items are in the data set represented by this Adapter.
#Override
public int getCount() {
return mStringList.size();
}
//Get the data item associated with the specified position in the data set.
#Override
public Object getItem(int position) {
return mStringList.get(position);
}
//Get the row id associated with the specified position in the list.
#Override
public long getItemId(int position) {
return position;
}
//Get a View that displays the data at the specified position in the data set.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder viewHolder;
if(convertView==null) {
viewHolder=new Holder();
convertView=mInflater.inflate(R.layout.list_item,null);
viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem);
convertView.setTag(viewHolder);
}else{
viewHolder=(Holder)convertView.getTag();
}
viewHolder.nameTv.setText(mStringList.get(position).toString());
return convertView;
}
private class Holder{
TextView nameTv;
}
//Returns a filter that can be used to constrain data with a filtering pattern.
#Override
public Filter getFilter() {
if(valueFilter==null) {
valueFilter=new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint!=null && constraint.length()>0){
ArrayList<String> filterList=new ArrayList<String>();
for(int i=0;i<mStringFilterList.size();i++){
if(mStringFilterList.get(i).contains(constraint)) {
filterList.add(mStringFilterList.get(i));
}
}
results.count=filterList.size();
results.values=filterList;
}else{
results.count=mStringFilterList.size();
results.values=mStringFilterList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
mStringList=(ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
activity_search_and_filter_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/txt_search"
tools:context=".SearchAndFilterList"
android:hint="Enter text to search" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/list_view"
android:layout_below="#+id/txt_search"></ListView>
</RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/txt_listitem"/>
</RelativeLayout>
AndroidManifext.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.searchandfilterlistview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".SearchAndFilterList"
android:label="#string/title_activity_search_and_filter_list" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I hope this code will will helpful to implement custom search and filter listview.
You can use:
http://developer.android.com/reference/android/widget/TextView.html
addTextChangedListener( TextWatcher watcher )
to figure out when the textview was changed. I believe it should be called everytime a letter is added or removed.
Then update your list adapter to dislplay the new items by either:
creating a new list adapter and populating it with the items that satisfy the filter or
having a subclass of the BaseAdapter to accept your filter and call notifyDataSetChanged() after it has finished removing the items you no longer want
http://developer.android.com/reference/android/widget/BaseAdapter.html
Search a listview based on input in EditText
public class MainActivity extends Activity {
private ListView lv,lv2;
private EditText et;
String listview_array[]={"01634 ABOHAR","080 Bangalore","011 Delhi","Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "1234", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"};
private ArrayList<String> array_sort = new ArrayList<String>();
int textlength = 0;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.ListView01);
lv2 = (ListView) findViewById(R.id.ListView02);
et = (EditText) findViewById(R.id.EditText01);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listview_array));
int x= lv.getHeaderViewsCount ();
System.out.println("x========"+x);
lv.setAdapter(new ArrayAdapter<String>
(MainActivity.this,
android.R.layout.simple_list_item_1, listview_array));
et.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
// Abstract Method of TextWatcher Interface.
}
public void beforeTextChanged(CharSequence s,
int start, int count, int after)
{
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence s,
int start, int before, int count)
{
textlength = et.getText().length();
array_sort.clear();
for (int i = 0; i < listview_array.length; i++)
{
if (textlength <= listview_array[i].length())
{
String s2= et.getText().toString();
if(listview_array[i].toString().contains(et.getText().toString()))
{
array_sort.add(listview_array[i]);
}
}
}
lv.setAdapter(new ArrayAdapter<String>
(MainActivity.this,
android.R.layout.simple_list_item_1, array_sort));
}
});
}
}
For search in custom listview based on class item refer the link implement search on a custom listview. Modify it according to your needs.
when you use custom listView
Adapter :
public class Adapter extends ArrayAdapter {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> filteredData = new ArrayList<>();
public Adapter(#NonNull Context context, int resource) {
super(context, resource);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflate = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
#SuppressLint("ViewHolder") View vi = inflate.inflate(R.layout.ly_items, null);
try {
JSONObject js = new JSONObject(list.get(position));
TextView txtItem = vi.findViewById(R.id.txtItem);
ImageView imgItem = vi.findViewById(R.id.imgItem);
txtItem.setText(js.getString("name") + " - " + js.getInt("number"));
Picasso.get().load(js.getString("logo_url")).into(imgItem);
} catch (JSONException e) {
e.printStackTrace();
}
return vi;
}
#Override
public void add(#Nullable Object object) {
super.add(object);
list.add(object.toString());
filteredData.add(object.toString());
}
#Override
public int getCount() {
return list.size();
}
#Nullable
#Override
public Object getItem(int position) {
return list.get(position);
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
list.clear();
if (charText.length() == 0) {
list.addAll(filteredData);
} else {
for (String wp : filteredData) {
try {
JSONObject json = new JSONObject(wp);
if (json.getString("name").toLowerCase().contains(charText) || json.getString("number").contains(charText)) {
list.add(wp);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
notifyDataSetChanged();
}
}
And your class:
Adapter adapter;
ListView list;
EditText edtSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = findViewById(R.id.list);
edtSearch = findViewById(R.id.edtSearch);
adapter = new Adapter(this, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
edtSearch.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) {
adapter.filter(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
1) create a custom adapter for your list view and create a removeIfMatch(String s) method:
public void removeIfMatch(String s) {
for item in adapter:
if item.matches(s) {
data.removeItem(item);
notifyDataSetChanged();
break
}
}
2) create a callback for when the EditText contents change
3) invoke adapter.removeIfMatch(editText.getText())