I have a AutoCompleteTextView and ProgressBar right of it and visibility of ProgressBar is invisible at beginning.
I am setting adapter to AutocompleteTextView in onCreate of my activity with custom class PlacesAutoCompleteAdapter and xml file autocomplete which contains the TextView,
actvFrom.setAdapter(new PlacesAutoCompleteAdapter(this,
R.layout.autocomplete));
In PlacesAutocompleteAdapter class i am implementing Filterable interface.
private class PlacesAutoCompleteAdapter extends ArrayAdapter<String>
implements Filterable {
private ArrayList<String> resultList;
public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public String getItem(int index) {
return resultList.get(index);
}
#Override
public android.widget.Filter getFilter() {
android.widget.Filter filter = new android.widget.Filter() {
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// TODO Auto-generated method stub
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
#Override
protected FilterResults performFiltering(
final CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
// Retrieve the autocomplete results.
// TODO Auto-generated method stub
resultList = autocomplete_fill_data(constraint
.toString());
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
};
return filter;
}
}
In autocomplete_fill_data function i am doing call to the server and adding it to ArrayList myCollection and returning it.
public ArrayList<String> autocomplete_fill_data(String value) {
myCollection = new ArrayList<String>();
// call to server
...
myCollection.add(result);
return myCollection;
}
AutoComplete is working fine but the problem is i am not able to show the ProgressBar whenever there is call to server.
I tried all this,
Using addTextChangedListener
autocomplete.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
if (s.length() >= 1) {
System.out.println("Count ="+count);
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.INVISIBLE);
}
}
But Problem with this is even though you stopped typing text the progressBar will be still rotating. I wanted to hide the ProgressBar as soon as the user stops writing the text.
In performFiltering i tried to hide the progressBar but the autocomplete box is getting stuck as you type.
Is there any other way so i can try to hide the progressBar as the user stops typing the text.
you should try to use
public void afterTextChanged(Editable s)
autocomplete.addTextChangedListener(new TextWatcher()
{
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
progressBar.setVisibility(View.GONE);
}
Related
I have getFilter in my recyclerView adapter class. It is not working properly if I search a name that starts with 'A' there is no change in the list results. Suppose I search a name that starts with 'S', the name will come to the top of the list. Also I try the same thing with phone number and pincode. It doesn't show anything. This is What I am trying:
EditText.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) {
if(adapter!=null){
adapter.getFilter().filter(s);
}
}
});
This above code I used to send the characters to get filter method:
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString().toLowerCase();
if(charString.isEmpty()){
mDataFiltered = mData;
}
else{
List<Guru> filteredList = new ArrayList<Guru>();
for(Guru row:mData){
if(row.getName().toLowerCase().contains(charString) ||
row.getMobile().contains(charString) || row.getOfficePincode().contains(charString)|| row.getHomePincode().contains(charString) ){
filteredList.add(row);
}
}
mDataFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mDataFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.values!=null){
mDataFiltered = (List<Guru>) results.values;
notifyDataSetChanged();
}
}
};
Here I am doing the filter function. If you know the mistake just ping me.
I don't know what happens but my searchView not working well when I input a 2 words value in search bar.
for example:
my listview displayed like this
You save me
Above All
I am not ashamed
In searchbar I want to search the song "You save me" with the keyword of "You". The result was fine and displayed the exact match but when I am trying to input the "You save" keyword the result doesn't appear anything in listview. It seems that searchview doesn't work when the inputted value has space between 2 words.
how can I fix this problem?
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
try this
searchView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
return true;
}
});
addTextChangeListener();
now create this method
private void addTextChangeListener() {
searchView.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().trim().toLowerCase();
final ArrayList<CityDataModel> filteredList = new ArrayList<>();
final CharSequence finalQuery = query;
new Thread(new Runnable() {
#Override
public void run() {
// Clear the filter list
filteredList.clear();
// If there is no search value, then add all original list items to filter list
if (TextUtils.isEmpty(finalQuery)) {
filteredList.addAll(cities);
} else {
// Iterate in the original List and add it to filter list...
for (CityDataModel item : cities) {
if (item.getCity_name().toLowerCase().contains(finalQuery.toString().toLowerCase())
) {
// Adding Matched items
filteredList.add(item);
}
}
}
// Set on UI Thread
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
// Notify the List that the DataSet has changed...
adapter = new SearchCityAdapter(SearchCityClass.this, filteredList);
recyclerSearchCity.setAdapter(adapter);
if (filteredList.size() == 0) {
tvNoCityFound.setVisibility(View.VISIBLE);
} else {
tvNoCityFound.setVisibility(View.GONE);
}
}
});
}
}).start();
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
Okay, guys. This post is very old but seems that no more has interested to answers my question, so I decided to answer my old question in case someone has the same issue as mine.
Very important: Use RecyclerView instead of ListView for better performance.
Create Recyclerview adapter and implement this class Filterable to your adapter.
then add this code.
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
final String text = charSequence.toString().toLowerCase();
List<SongsEntity> list;
if (text.isEmpty()) {
list = entitySongs; //"entitySongs" is your original arraylist
}else {
List<SongsEntity> songlist = new ArrayList<>();
for (SongsEntity song : entitySongs) {
if ((song.getTitle().toLowerCase().trim().contains(text)))
{
songlist.add(new SongsEntity(song.getId(), song.getTitle(), song.getArtist(),song.getLyrics()));
}
}
list = songlist;
}
FilterResults results = new FilterResults();
results.values = list;
return results;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
songFiltered = (List<SongsEntity>) filterResults.values; // //"songFiltered" is your filtered arraylist
notifyDataSetChanged();
}
};
}
I don't remember the exact cause of that issue but I fixed that issue with this code above.
I am trying to add a filter to my adapter class (which extends BaseAdapter).
Every thing is working very fine after launching application , But when activity is being re-created (by screen rotation or calling onCreate) the app stops working and makes a force close error
When I remove this Line there is no problem on re-creating activity
MainActivity.this.adapter.getFilter().filter(cs);
But debugger shows error is on
super.onCreate(savedInstanceState);
here is my Main Activity onCreate function:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Updator().execute();//Updator is a AsyncTask to update adapter
EditText inputSearch = (EditText) findViewById(R.id.editText1);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int start, int before, int count)
{
MainActivity.this.adapter.getFilter().filter(cs);//after screen rotation - application stops working when executing this line
}
#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
}
});
}
and this is my filter method in Custom adapter class:
private class CustomListFilter extends Filter
{
#Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults results = new FilterResults();
String prefix = constraint.toString().toLowerCase();
if (prefix == null || prefix.length() == 0)
{
results.values = original;
results.count = original.size();
}
else
{
final ArrayList<App> nlist = new ArrayList<App>();
int count = original.size();
App pkmn;
String value;
for (int i=0; i<count; i++)
{
pkmn = original.get(i);
value = pkmn.getName().toLowerCase();
if (value.contains(prefix))
{
nlist.add(pkmn);
}
}
results.values = nlist;
results.count = nlist.size();
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
mApps = (ArrayList<App>)results.values;
if (mApps.size() > 0)
notifyDataSetChanged();
else
notifyDataSetInvalidated();
}
}
My guess (without see a logcat trace) would be that you are getting a null pointer exception on the problem line:
MainActivity.this.adapter.getFilter().filter(cs);
This is either due to adapter being null, or the return of getFilter() being null.
Make sure you create a non null variable when your Activity is being re-created!
i need to perform search functionality in separated listview with the help of EditText. I used edittext.addTextChangedListener() method and i got the solution. But the EditText box accepts only one character, when i am trying to enter second character it causes force close.
I used the following code.
edtSearch.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 cs, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
sAdapter.clear();
textlength = edtSearch.getText().length(); //getting text from EditText
Log.e("textlength",""+textlength);
array_name.clear(); array_friendid.clear(); array_status.clear(); array_image.clear();array_thumb.clear();
for (int i = 0; i < fullname.length; i++) {
if (textlength <= fullname[i].length()) {
if(edtSearch.getText().toString().equalsIgnoreCase((String)fullname[i].subSequence(0,textlength))) {
Log.e("arrayname",fullname[i]);
array_name.add(fullname[i]);
array_friendid.add(friendid[i]);
array_status.add(status[i]);
array_image.add(imageurl[i]);
array_thumb.add(thumbnailurl[i]);
array_header.add(fullname[i].substring(0, 1));
}
}
}
you can put an control below ,
if(textlength > 3)
for (int i = 0; i < fullname.length; i++)
{
I think you can utilize Filter class to achieve what you want. Simply override getFilter() method of your list adapter. Here is the sample code:
#Override
public Filter getFilter() {
if(mFilter == null){
mFilter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults;
//Do your search and initialize filterResults
...
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results != null && results.values != null) {
notifyDataSetChanged();
}
}
};
}
return mFilter;
}
The advantage of a Filter class is that it performs filtering on a separate thread.
I am trying to search data by ListView data coming from a websevice..
Description: if I enter [abc] in search editview[searchText] and if I click serachbutton(buttonSearch), it must show all related data in listview(listView)
Ex: abc, abacd, abcderg etc. in this way...
This topic is new for me.
Here is my code. Please help me do it.
I have tried, but I was not able to figure out how to do this.
worklistview.java
ArrayList<Patient> patientListArray;
listView = (ListView) findViewById(R.id.workListview);
objectAdapter = new WorkListAdapter(this, patientListArray);
listView.setAdapter(objectAdapter);
listView.setTextFilterEnabled(true);
searchText = (EditText) findViewById(R.id.searchView);
searchText.addTextChangedListener(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) {
dataAdapter.getFilter().filter(s.toString());
}
});
WorkListAdapter.java
public Filter getFilter() {
Filter myFilter = new Filter() {
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (!patientListArray.isEmpty()){
clear();
}
for (int i = 0; i < patientListArray.size(); i++) {
if(patientListArray.get(i).getName().toLowerCase().startsWith(constraint.toString().toLowerCase())){
add(patientListArray.get(i));
}
}
notifyDataSetChanged();
}
private void add(Patient patient) {
}
private void clear() {
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
return null;
}
};
return myFilter;
}
Graphically, you need a layout with an EditText (TextWatcher) and a listview. Then, the adapter of your listview will be always listening the changes on your TextWatcher using a filter ( dataAdapter.getFilter().filter(s.toString()); )
More details here
Good luck.