Android list -- how to find the wanted item? - android

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());
}
});
}
}

Related

Scrolling ListView

In listView I marked a line selected by a particular color, scrolling down the list and going back up - a marked line becomes colored even though there is still a mark (I did a test for it). Have you encountered such a phenomenon and if so how can you handle it.
'''
public class CustomDesignList extends AppCompatActivity {
ArrayList<Fruit> list;
ListView listView;
FruitAdapter adapter;
String[] fruitNames= {"apple", "apricot", "banana", "cherry", "coconut", "grapes",
"kiwi","mango", "melon","orange", "peach","pear",
"pineapple","strawberry", "watermelon"};
int[] imageResourceArray= {R.drawable.apple,R.drawable.apricot,R.drawable.banana,
R.drawable.cherry,R.drawable.coconut,R.drawable.grapes,
R.drawable.kiwi,R.drawable.mango,R.drawable.melon,R.drawable.orange,
R.drawable.peach,R.drawable.pear,R.drawable.pineapple,
R.drawable.strawberry,R.drawable.watermelon};
int[] arrCounter=new int[15];// מערך מונים לסימון ברשימה
int sum=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_design_list);
for(int i = 0; i< arrCounter.length;i++)
arrCounter[i] = 0;
listView=findViewById(R.id.lvCustom);
list=new ArrayList<>();
for(int i=0; i<fruitNames.length;i++)
list.add(new Fruit(fruitNames[i],
(int)((Math.random() * (100 - 10 + 1)) + 10),
imageResourceArray[i]));
//Connect all data to all elements in the list
//Layout where we defined what one element in the list would look like
adapter=new FruitAdapter(this,R.layout.my_custom_list,this.list);
//Connect the full list of data to xml
this.listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
arrCounter[position]++;
if( arrCounter[position] %2==1)
{
view.setBackgroundColor(Color.parseColor("#EBBEF3"));
sum+=list.get(position).getFruitWeight();//
}
else
{
view.setBackgroundColor(Color.TRANSPARENT);
sum-=list.get(position).getFruitWeight();//
}
}
});
}'''
You have a bunch of problems here.
1)You shouldn't be using ListView these days. RecyclerView replaced it most of a decade ago.
2)In a ListView click handler, you can't change anything in the UI. If you do and you don't really know what you're doing, you're going to screw it up. Like you did here. Instead of changing the UI, you should change the data in the adapter, and then tell the view to reload new data from the adapter. Anything else and you're going to have problems when the views recycle themselves on scroll.
I'd really look at changing to recycler view, but at a minimum you need to change how your click handler works completely so that it doesn't make any UI changes directly and only changes the data.

Hiding Listview until search is initiated

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.

Add item in a ListView

I have a Activity that's creating a Check list, if I close the activity with back Button the list is saved in a Database.
The list from the Database is used as the MainActivity content.
This is how my app will look:
If I press the List Item button, a new element should be added to the list. How can I add and sisplay a new Item (Layout with Checkbox and EditText)?
Do I need an Adapter? I don't want the 'list item' part repeated.
That looks so after i press 4 times
Activity
private ArrayAdapter mAdapter;
onCreate
ListView lv = (ListView) findViewById(R.id.my_list);
List<String> initialList = new ArrayList<String>(); //load these
mAdapter = new ArrayAdapter(this, android.R.id.text1, initialList)
lv.setadapter(mAdapter);
When the event happens
mAdapter.add(newString);
The add method in ArrayAdpater will automatically take care of the notifyDataSetChanged() call for you and update the display.
TextWatcher you might not need this part, it's if you want the text added as soon as the text is changed which your question seems to indicate - that is risky because you might get partial entries, so i recommend a done button instead, in which case you just do the afterTextChanged stuff in the onClick method.
EditText editText = (EditText) findViewById(R.id.my_edit_text);
editText .addTextChangedListener(new TextWatcher(){
#Override
public void afterTextChanged(Editable arg0) {
//TODO: check it isnt emtpy
String text = arg0.getText().toString();
mAdapter.add(text);
//Hide the add item views again
arg0.setText("");
arg0.setVisibility(View.GONE);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) { /*nothing*/ }
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) { /*nothing*/ }
});
You can add plus button in your list as footerview as your image then new item add in your arraylist by the action(onClicklistener) of footer view button then call youradapter.notifyDataSetChanged().

Searching a listview when the array is in the strings xml

I am having an issue with my function that searches my list. The list array used to be attached to a String[] in the actual .java files but I moved the array into the strings xml file to implement another feature of using different languages in the app. Therefore translating the listview
Anyway, I understand why the code is doing the following but I can't work out how to solve it...
Resources res = getResources();
final String[] items = res.getStringArray(R.array.societies_array);
listView2 = (ListView) findViewById(R.id.societieslist);
EditText inputSearch = (EditText) findViewById(R.id.inputSearch);
// Adding items to listview
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
// When user changed the Text
System.out.println(cs);
SocietiesScreen.this.adapter.getFilter().filter(cs);
}
#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
}
});
The onclick listener of thelist is depend on the index of the list so when not searched it works fine but when I search for a particular option the new 'first option' now gets assigned a new index number instead of keeping it's original
Hope that makes sense and I have given enough code, if you need anything else just let me know
Thanks
I think I've already answered a very similar question, here. You should also watch "the world of listView" lecture.
Basically, if you use a custom BaseAdapter, you can create a new mode for filtered items, which is enabled as long as there is something in the search field.
When this mode is enabled, items are retreived from a filtered list instead of from the original list.
If you don't use your own BaseAdapter, check out this link.

How to filter text in a ListView properly?

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

Categories

Resources