I can retrieve a list of all items of a spinner by:
List<String> list = new ArrayList<String>();
for (int i =0; i<spinner.getCount(); ++i)
{
String item = String.valueOf(spinner.getItemAtPosition(i));
list.add(item);
}
Or storing the item list globally...
Is there any more elegant way, something like .getItemList()?
My concern is the iteration (linear complexity), I would prefer to directly get the list from the adapter (possibly constant complexity?)
See http://developer.android.com/reference/android/widget/Adapter.html and http://developer.android.com/reference/android/widget/SpinnerAdapter.html (which inherits from Adapter)
You will find that the method you're looking for doesn't exist
Your solution is about as elegant as it gets
Related
I'm adding list items containing a checkbox to a list in my fragment class like this:
public class CheckboxList extends Fragment {
...
listViewToDo = (ListView)myView.findViewById(R.id.listViewToDo);
//creates list of names of the default list items
arrayListToDo = new ArrayList<String>();
if(!arrayListToDo.contains("Menu1"))arrayListToDo.add("Menu1");
if(!arrayListToDo.contains("Menu2"))arrayListToDo.add("Menu2");
if(!arrayListToDo.contains("Menu3"))arrayListToDo.add("Menu3");
//sets the checkboxes
arrayListCheck = new ArrayList<>();
for(int i = 0; i < arrayListToDo.size(); i++){
CheckBox cb = new CheckBox(myView.getContext());
cb.setText(arrayListToDo.get(i));
arrayListCheck.add(cb);
}
arrayAdapterCheck = new ArrayAdapter<CheckBox>(listViewToDo.getContext(),
android.R.layout.simple_list_item_checked, arrayListCheck);
listViewToDo.setAdapter(arrayAdapterCheck);
...
I want it to do it this way because the user shall be able to add and delete specific list items.
Though that works fine, my checkboxes look like this:
Can someone tell me what I'm doing wrong?
Ok my fault, I did'nt know that I need a custom ArrayAdapter to use other objects then strings to display in my list.
This helped me a lot to get a better understanding of the Adapter and to write my own one for the checkboxes:
http://techlovejump.com/android-listview-with-checkbox/
I am using a collection of ArrayList to fill my Listview. My ListView contains two separate rows types.
Header and Footer.
I am trying to achieve the ExpandableListView Functionality on my Listview from which I am trying to remove some items on click of header till next header.
I am using this function to loop through items and removing items
private void removeItems(int value)
{ Log.e(Constant.LOG, items.size()+"");
for (int i = value;i < items.size(); i++) {
if(!items.get(i).isSection())
items.remove(i);
}
Log.e(Constant.LOG, items.size()+"");
adapter = new EntryAdapter(this, items, this);
mListView.setAdapter(adapter);
}
QUESTION IS : I am not able to remove all items from the list in one shot, some stays there !
I have tried looping through adapter.count(); but no luck
My List :
SECTION 1
ITEM 1
ITEM 2
Item N
Section 2
But when I click on Section 1 not all ITEMS get deleted in one shot WHY!
I am not able to use Expandable Listview at this stage because activity contains many more complex functionality on List. Please help me where I am going wrong!
Create a new ArrayList<Collection> , Then add your item in it and then use removeAll(collection).
TRY THIS:
private void removeItems(int value)
{ Log.e(Constant.LOG, items.size()+"");
ArrayList<Collection> deleteItems= new ArrayList<Collection>();
for (int i = value;i < items.size(); i++) {
if(!items.get(i).isSection())
deleteItems.add(items.get(i));
}
items.removeAll(deleteItems);
Log.e(Constant.LOG, items.size()+"");
adapter = new EntryAdapter(this, items, this);
mListView.setAdapter(adapter);
}
EDIT
Every time you are deleting an item, you are changing the index of the elements inside .
e.g : let suppose you are deleting list1 , then list[2] becomes list1 and hence your code will skip list1 next time because now your counter would be moved to 2.
Here are other ways by which you can achieve this also,
Removing item while iterating it
So what exactly I did now. Instead of looping through items again I did like this :
I created another list and parallely populate it with the main array.
items.add(user);
// after populating items did this
newItems.addAll(items); // same collection ArrayList
and finally I can play with the main array by using removeAll and addAll methods.
items.removeAll(newItems); // remove items
items.addAll(afterPosition,newItems); // add items after position
I have a ListView which uses CHOICE_MODE_MULTIPLE.
Once the user has made their selections, I need to remove the selected items from the list.
I have used getCheckedItemPositions() to return the SparseBooleanArray of checked items.
All the documentation and related questions I've read indicate that to remove items from a list efficiently, you should use an Iterator, but I can't figure out how to do this.
I have achieved the same operation by looping though the items in the ListView by index and using a temporary clone of the items list to look up which items should be removed (see code below). But supposedly looping through indexes like this to remove items from a List = Bad Coding Monkey. I'm told I should do it with an Iterator instead. But how?
protected void removeItems() {
SparseBooleanArray itemsSelectionState = mItemsListView.getCheckedItemPositions();
ArrayList<String> itemsClone = (ArrayList<String>) mItems.clone();
for (int i = 0; i < mItemsListView.getCount(); i++) {
if (itemsSelectionState.get(i) == true) {
mItems.remove(itemsClone.get(i));
}
}
mItemsListView.clearChoices();
mItemsListAdapter.notifyDataSetChanged();
}
You need the position anyway to lookup the boolean value in the Sparse array. there's not much point in using an iterator if you have to maintain an index value to determine if you should remove that item.
Yes, I think your approach is valid. The iterator does have a remove() method, but you would still need have an index handy. If the id's are stable (with ArrayList based adapters, the id usually equals the position) then it might be more efficient to use getItemIds () and iterate through that list, using the id's as positions.
// could also store ids[] and pre-allocate mItemsClone to ids.length
for (long id : ..getItemIds() ){
itemsClone.put( mItems.get( (int) id) );
}
and that might be a bit more efficient since it's only one pass
I would like to find a specific item in the list and have it selected by default. If I can find out the position, I can call ListView.setItemSelected(position, true)
I'm using a SimpleCursorAdapter to show a list of categories and this can change dynamically so I can't just find the index and hard code.
How do you find the position of a list item by a String without use of the OnClickListener?
Hard to say what might be best for your implementation without seeing your code but maybe an implementation like this one
SimpleCursorAdapter myAdapter;
...
//search here
int count = myAdapter.getCount();
for(int i=0; i < count; i++){
if("desired string".equals(myAdapter.getItem()){
listView.setItemSelected(i, true);
}
}
is it possible to programatically access specific rows in a list of CheckedTextViews to change the state of their textboxes?
my program has a listview which has several CheckedTextViews which the user can press to toggle state.
I want to save the state of the checkboxes when the user leaves the activity, so I have in my onPause method:
public void onPause(){
super.onPause();
SparseBooleanArray positions;
positions = listView.getCheckedItemPositions();
ListAdapter items = listView.getAdapter();
int j = items.getCount();
ArrayList<Long> ids = new ArrayList<Long>();
for (int k =0; k < j;k++){
if(positions.get(k)==true){
ids.add(items.getItemId(k));
}
}
this.application.getServicesHelper().open();
this.application.getServicesHelper().storeServices(ids,visit_id);
this.application.getServicesHelper().close();
}
which very simply iterates the list view, adds the checked items to an ArrayList and then saves that list of ids to the database.
My problem lise in trying to reset the list once a user goes back to that activity.
so far in my onStart method, I recall the checked items from the database, but I do not know how to march the ids returned to the listview elements. can I do something like:
listView.getElementById(id_from_database).setChecked?
I know I cant use getElementById but I have it here to show what I mean
Thanks in advance
Kevin
You can call
listView.setItemChecked(int position, boolean value)
This is what Ive ended up doing.. but it seems like a complete hack.
Basically I have to set up a double for loop.. one to iterate through my list elements, and one to iterate through the cursor that I have retreived my check list state (a simply array of ids of elements that were checked when state was last saved)
my outer for iterates through the list elements checking each id against a loop through the list of ids to be set as checked. if they equal each other then set that item as checked.
// mAdapter is contains the list of elements I want to display in my list.
ServiceList.this.setListAdapter(mAdapter);
// Getting a list of element Ids that had been previously checked by the user. getState is a function I have defined in my ServicesAdapter file.
Cursor state = ServiceList.this.application.getServicesHelper().getState(visit_id);
int checks = state.getCount();
int check_service;
int c = mAdapter.getCount();
if(checks>0){
state.moveToFirst();
for (int i=0; i<checks; i++) {
// set check_service = the next id to be checked
check_service = state.getInt(0);
for(int p=0;p<c;p++){
if(mAdapter.getItemId(p)==check_service){
// we have found an id that needs to be checked. 'p' corresponds to its position in my listView
listView.setItemChecked(p,true);
break;
}
}
state.moveToNext();
}
}
ServiceList.this.application.getServicesHelper().close();
Please tell me there is a more efficient way of achieving this!!
Thanks
Kevin