I have a question:
I have a listview (from custom adapter) with a searchbar on top of it. Everything works ok, the only thing I need is when opening the activity to keep the listview hidden, or invisible, until the search has started in the searchbar (in other words, to keep the listview hidden until I start typing something in the searchbar).
You can find the code here:
How to start new intent after search-filtering listview?
Plus a suggested solution, which unfortunately did not work, you can see here:
Android search list invisible by default? Can it be done?
I am looking forward to your replies guys and I thank you in advance.
Try adding TextWatcher to your search EditText. This will detect when you type something in your search:
EditText search= (EditText) findViewById(R.id.search);
search.addTextChangedListener(filterTextWatcher);
TextWatcher method:
private TextWatcher filterTextWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
//Change the visibility here
list.setVisibility(View.VISIBLE);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
};
I think you may be thinking about an AutoCompleteTextView? It requires that you load the list data into its adapter then set the adapter.
// Get a reference to the AutoCompleteTextView in the layout
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_country);
// Get the string array
String[] countries = getResources().getStringArray(R.array.countries_array);
// Create the adapter and set it to the AutoCompleteTextView
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, countries);
textView.setAdapter(adapter);
Google's Guide: here.
Related
I'm facing an issue without being able to find an answer. I have an editText with a TextWatcher to find a list of results in a database. I display the result in a PopupMenu. It looks like this :
final List<SearchResult> searchResults = new ArrayList<>();
final PopupMenu menu = new PopupMenu(getActivity(), binding.bottomSheetWriteNews.editTextNewsSubCategory);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
binding
.bottomSheetWriteNews
.editTextNewsSubCategory
.setText(item.getTitle());
return false;
}
});
final Realm realm = Realm.getDefaultInstance();
binding.bottomSheetWriteNews.editTextNewsSubCategory.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
searchResults.clear();
menu.getMenu().clear();
RealmResults<SubCategory> subCategoriesResult = realm.where(SubCategory.class).contains("name", s.toString(), Case.INSENSITIVE).findAll();
for(SubCategory subCategory : subCategoriesResult) {
searchResults.add(new SearchResult(subCategory.getId(), subCategory.getName(), false));
menu.getMenu().add(subCategory.getName());
}
menu.show();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
My issue is every-time I click on the Keyboard the PopupMenu is dismiss instead of typing the character I wanted. That's annoying and unusable for users. I want the click on keyboard to not dismiss the PopupMenu. I know that in the official documentation it's written Touching outside of the popup will dismiss it, but I'm using Google Keep, and they have the same feature (typing text display a PopupMenu to filter results) without my issue.
Thanks for your help !
Instead of using popup menu you can use
spinner or (list view or recycler view )
and do notifyDataSetChanged().
So that the layout won't get piling(off and on)
Hope it will help you.
Responding to my own answer after I found an alternative solution with a coworker. There is a specific EditText named autoCompleteTextView which can take an ArrayAdapter. And it will do the search for you. Here is how I implemented it :
final Realm realm = Realm.getDefaultInstance();
RealmResults<SubCategory> subCategoriesResult = realm.where(SubCategory.class).findAll();
List<String> categoryName = new ArrayList<>();
for(SubCategory subCategory : subCategoriesResult) {
categoryName.add(subCategory.getName());
}
String[] stringArray = categoryName.toArray(new String[0]);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_dropdown_item_1line, stringArray);
binding.bottomSheetWriteNews.autoCompleteTextViewNewsSubCategory.setAdapter(adapter);
And nothing more ! After typing two characters the list of result will show as a PopupMenu.
In any case, if someone has a solution to avoid dismiss after clicking on keyboard when a PopupMenu is showed, I'm interested. Thanks !
i'm making a dictionary. I want to filter search word with the search textbox.
Here the example:
Ame(雨)
飴(Ame)
But when i type into the textbox "ame", only Ame(雨) is show.
I want both words show. Here my code:
I load all the word into ArrayList "wordlist"
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, wordList);
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
Thank you.
I don't think this is possible from default filter behavior. You could write your own custom logic.
This article might help you http://www.androidbegin.com/tutorial/android-search-listview-using-filter/
I do have a list of possibly several thousands items (just testing with shorter list with about 200 items). The information is stored in SQLite, the ContentProvider, loader and SimpleCursorAdapter is used. The list is sorted lexicographically, and the android:fastScrollEnabled is used. The list scrolls smoothly -- no problem when one knows the exact name of the item.
Occasionally, I would like to find the items that contain some substring somewhere in the middle of their name. The `... LIKE "%wanted%" is a solution for me. However, I would like to give the user an incremental filtering -- i.e. the list content be updated during typing the substring. The reasoning is that it may not be neccessary to type many characters, and one should find the item as soon as possible. The goal is not to find one or none item. The goal is to filter the list so that manual scrolling be acceptable to overview the candidate items and select one of them by touch.
I have met the SearchView widget that looks nicely at the action bar. Anyway, reading something more about it in the doc, I am not sure if it is the right tool for me. Or if the recommended implementation is the one for me. (I am an android beginner, I am even not sure if I understand it well.)
Is it possible to use the widget for incremental filtering of the list in the same activity that has the SearchView in the Action Bar? Can you point me to some code that possibly shows how to implement the wanted behaviour?
Sample code to try out :
public class AndroidListViewFilterActivity extends Activity {
ArrayAdapter<String> dataAdapter = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Generate list View from ArrayList
displayListView();
}
private void displayListView() {
//Array list of countries
List<String> countryList = new ArrayList<String>();
countryList.add("Aruba");
countryList.add("Anguilla");
countryList.add("Netherlands Antilles");
countryList.add("Antigua and Barbuda");
countryList.add("Bahamas");
countryList.add("Belize");
countryList.add("Bermuda");
countryList.add("Barbados");
countryList.add("Canada");
countryList.add("Costa Rica");
countryList.add("Cuba");
countryList.add("Cayman Islands");
countryList.add("Dominica");
countryList.add("Dominican Republic");
countryList.add("Guadeloupe");
countryList.add("Grenada");
//create an ArrayAdaptar from the String Array
dataAdapter = new ArrayAdapter<String>(this,R.layout.country_list, countryList);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(),((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
EditText myFilter = (EditText) findViewById(R.id.myFilter);
myFilter.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());
}
});
}
}
I'm trying to update the list of an AutocompleteTextView dynamically using and ArrayAdapter. In order to update this View I use a TextWatcher to monitor any changes that may occur in the AutocompleteTextView.
The problem is that the list isn't updating at all and I can't understand why. I've been looking for something like that on internet and I've found couple of different approaches but still I can't understand why this one, that should be the simplest one, isn't working. Any explaination would be much appreciated.
Target AVD: Google APIs level 10, Android 2.3.3
Here is the simplified code:
public class AutocompleteActivity extends Activity implements TextWatcher {
ArrayAdapter<String> adapter = null;
AutoCompleteTextView acTextView = null;
ArrayList<String> addresses = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.autocompleteview);
acTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete_address);
adapter = new ArrayAdapter<String>(this, R.layout.listitem, addresses);
adapter.setNotifyOnChange(true);
acTextView.addTextChangedListener(this);
acTextView.setAdapter(adapter);
}
#Override
public void onTextChanged(CharSequence text, int start, int before, int after) {
try {
adapter.add("test");
}
catch (Exception e) {
e.printStackTrace();
}
}
In your source code, TextWatcher is supplied to the AutoCompleteTextView, this is the real problem.
If you look at AutoCompleteTextView source code, you will find AutoCompleteTextView has its
own TextWatcher, named "MyWatcher". Becauseof this, AutoCompleteTextView can not repond to your typing action.
I've tried to filter my ListView from my EditText box, but currently, it's not working.
I have a ListView that get data properly and they are added to my own ListView using a ArrayAdapter class and my own ArrayList class. When I for example, typing in "table" I want it to sort from the loaded titles in my ListView and than it should show me the items that are left and matching table.
My current code:
private ArrayList<Order> orders; /* ArrayList class with my own Order class to
define title, info etc. */
private OrderAdapter adapter; //Own class that extends ArrayAdapter
orders = new ArrayList<Order>();
adapter = new OrderAdapter(this, R.layout.listrow, orders); /* listrow defining a
single item in my ListView */
setListAdapter(adapter); //Set our adapter to a ListView
search.addTextChangedListener(filterTextWatcher); //search is my EditText
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) {
adapter.getFilter().filter(s); //Filter from my adapter
adapter.notifyDataSetChanged(); //Update my view
}
};
Okay, so how can I achieve this? When I entering some value into the EditText box everything disappear, even if there is a match.
Thanks in advance and tell me if you need more code snippets or if this question i unclear!
The built-in filter implemented by ArrayAdapter converts the contained object to string by calling toString() method. It is this string that will be used to perform the matching. If you are only trying to match one string field in your Order object, you can override the toString() method for your Order class to return that field. If you want to perform more flexible matching, such as matching multiple fields, check out this post which shows how to create a custom filter:
Custom filtering in Android using ArrayAdapter