This is a follow up question to this question:
Retrieving the selected items from a multi-select ListView
I'm using a ListView with mode CHOICE_MODE_MULTIPLE_MODAL.
Is there a way to get the indexes of all checked Items ? In the question I posted above, there's a suggestion to use the method getCheckedItemPositions(), but I don't want to iterate over the entire list and check if it returns true so this is not what I need. I want to do something like this (pseudo code):
int[] checkedPositions = list.getCheckedIndexes();
for(int index : checkedPositions)
{
list.remove(index);
}
Is there a way to do something like that?
It may use less code if such a method exists to return an array of checked items, but that method would likely use the same time complexity as just iterating yourself.
Try getCheckedItemIds as mentioned in the documentation :
Returns the set of checked items ids.
To make it works correctly , in the adapter getItemId make it returns the position of the item
Related
I want to display "best" below only those comments that match the sequence of the top three best comments.
CommentAdapter
for (GoodsComment num : list) {
if (item.getSeq() == num.getSeq()) {
holder.txtBest.setVisibility(View.VISIBLE);
} else {
holder.txtBest.setVisibility(View.GONE);
}
}
This code works but only one
Assuming you are doing this inside the adapter, you should not use the for loop. Create an array containing sequence numbers of best comments and put it as a variable in the adapter.
Then in the adapter, getView() (for Listview) or bindView() (for RecyclerView) check if the sequence number is in the array you created earlier.
This should show the "best" flag in all the matching rows.
try to use integer flag and each time increment flag then check if flag = 3 or not
Are you updating the list item item every time after the for loop?
Morning everyone
Currently I have an ArrayList which allows me to remove by a set of item position which is perfect in most situations. But I was wondering if it was possible to remove my something e.g. a long variable.
My current ArrayList which is currently set on my recyclerView adapter.
private ArrayList<NoteInfoModal> mAdapter = new ArrayList (List)
Under the NoteInfoModal we also have the getters and setters for multiple rows that I use for my recyclerView e.g. Name, Description, Col ID etc...
Removing an item at the moment I simply use the following code below
mAdapter.remove(position)
Is there a way of altering this ArrayList so I can for example delete a result from this arraylist without using the position but instead an item inside the arraylist e.g. col id?
Thank you
Yes, but you will have to run a for-each loop for that.
//suppose you have col_Id;
for(NoteInfoModel noteInfoModel : mAdapter) {
if(noteInfoModel.getColId == col_Id) {
mAdapter.remove(noteInfoModel);
break;
}
}
Sure, instead of using the position to remove, you simply put in the Object you want to remove from the ArrayList:
mAdapter.remove(yourObject)
take a look at the official documentation.
Ganesh Gudghe also mentioned, that its neccessary to implement hashCode() and equals() for your class NoteInfoModal.
I am doing this:
// Member variable
List<String> items = null;
// in onCreate
items = new ArrayList<String>();
// later on in a Task (onPostExecute)
items.add(NewItem);
adapter.notifyDataSetChanged();
My List is in Alphabetical order. When I add an item, it simply puts it at the bottom. Any way to put it in the proper place?
(Yes it will be in proper order the second time you come back to this page, but not on adding it)
Edit: I am first putting it in order through a SQL script call.
My suggestion to your answer is that, as and when you add an item on ListView try to set the adapter again on the list at the time of adding item.
this way you get the refreshed data on your ListView.
I decided to research any methods for ArrayList and did not find any. I did find this, however:
items.add(NewItem);
Collections.sort(items);
Worked perfectly! I had to import Collections into the project.
Let's say a list has 4 items, how can I get a view from each menu item of a list by position?
Unfortunately the items that are in the ListView are generally only those that are visible. You should iterate on the ListAdapter instead.
For example, in some of my code, I have this:
SimpleCursorAdapter adapter = (SimpleCursorAdapter) this.getListAdapter();
int iNum = adapter.getCount();
for(int i=0; i<iNum; i++)
{
Cursor c = (Cursor) adapter.getItem(i);
// Now you can pull data from the cursor object,
// if that's what you used to create the adapter to start with
}
EDIT:
In response to jeffamaphone's comments, here's something else... if you are trying to work with each UI element then getChildAt is certainly more appropriate as it returns the View for the sub-item, but in general you can still only work with those that are visible at the time. If that's all you care about, then fine - just make sure you check for null when the call returns.
If you are trying to implement something like I was - a "Select All / Select None / Invert Selection" type of feature for a list that might exceed the screen, then you are much better off to make the changes in the Adapter, or have an external array (if as in my case, there was nowhere in the adapter to make the chagne), and then call notifyDataSetChanged() on the List Adapter. For example, my "Invert" feature has code like this:
case R.id.selectInvertLedgerItems:
for(int i=0; i<ItemChecked.length; i++)
{
ItemChecked[i] = !ItemChecked[i];
}
la.notifyDataSetChanged();
RecalculateTotalSelected();
break;
Note that in my case, I am also using a custom ListView sub-item, using adapter.setViewBinder(this); and a custom setViewValue(...) function.
Furthermore if I recall correctly, I don't think that the "position" in the list is necessarily the same as the "position" in the adapter... it is again based more on the position in the list. Thus, even though you are wanting the "50th" item on the list, if it is the first visible, getChildAt(50) won't return what you are expecting. I think you can use ListView.getFirstVisiblePosition() to account and adjust.
See here, this question answers the similar problem you mentioned here
In an android ListView, how can I iterate/manipulte all the child views, not just the visible ones?
As the title, how can I remove the filtering on an ArrayAdapter used by an AutoCompleteTextView to get the original list back?
A little more background:
It all started from the sad fact that the "position" value passed in to onItemClick() is useless. The "position" refers to the position AFTER the array has been filtered, but I need to know its REAL position. So, what I'm trying to do is when I've got the text of the selected item (by using getItemAtPosition(position)), I compare it one-by-one with the original string array that backs the ArrayAdapter. However, I found that when onItemClick() is called, the adapter is already filtered, I no longer have access to the original array. So I thought if I can remove the filter, maybe I can get back the original array and look for the selected item in it.
ArrayAdapter<String> mAdapter;
public void onCreate() {
// Create an adapter and remembere it as a class member.
mAdapter = new ArrayAdapter<String>(this, layoutId);
// Add 100 strings to it and attach it to an AutoCompleteTextView
for (int i = 0; i < 100; i++)
mAdapter.add("random text");
((AutoCompleteTextView)findViewById(id)).setAdapter(mAdapter);
}
#Override
public void onItemClick(AdapterView<?> actv, View view, int position, long id) {
if (actv.getAdapter().equals(mAdapter))
Log.d("The adapter contained in actv is the same one I created earlier.");
// And, I can get the text of the item the user selected
String selected = (String)actv.getItemAtPosition(position);
// However, although the adapter passed in is still the same one, but the
// number of items in it is only 1! Because the array has been filtered.
int numItems = actv.getAdapter.getCount();
// So, I'm thinking if I can somehow remove the filtering here, then I can
// get back those 100 items, and do a search like following:
for (int i = 0; i < actv.getAdapter.getCount(); i++)
if (selected == actv.getAdapter.getItem(i))
break; // Eureka!!!
}
To tackle the problem of obtaining the REAL position of the selected item:
Is there a way to utilize the "id" value? Like, assign each item an id, then hopefully onItemClick() would pass back the correct id.
Like I said above, remove the filter (is it possible), get back the original 100 items, and perform a one-by-one search.
This is the last resort, I know it'll work, but I don't want to do it: Once I get the text of the selected text, I go back to the source of the data (from a database), query those 100 items out, and perform the search.
Another lame last resort: To avoid the overhead on accessing the database again as in #3, when in onCreate(), while creating the ArrayAdapter, I use an ArrayList of my own to remember all those 100 strings.
Am I doing it all wrong? What's the "right" way of obtaining the real position of the selected item from an AutoCompleteTextView?
Thank you very much!
(I read somewhere, some buy that seemed to be from Google Android team, said that one should use getFirstVisiblePosition() to resolve the position. But I can't figure out how.)
I don't know if you're still interested, but I found this answering a similar question: Problem with AutoCompleteTextView and Spinner using the same Adapter
Copying the method in the AutoCompleteTextView source code:
Filter filter = mAdapter.getFilter();
filter = null;
See my response in the above question for the grepcode link.
This is actually pretty simple to solve.. Instead of adding each element to the adapter as you get it (I'm assuming your random text part is just for example purposes), instead use the following:
First build your array into a variable, call it myArray..
then initialize your adapter like this:
mAdapter = new ArrayAdapter<String>(this, layoutId, myArray);
Now make sure that myArray is a class variable so you can reference it from anywhere else in the class.. Of course if you need access to this from another class you'd want to make a getter for it... Then you can easily iterate over the array to see if the value selected is in the array.. You'll have the whole set of data there instead of trying to get it from the adapter.
Here is a good example on using a validator for a similar looking use case:
Android, Autocomplettextview, force text to be from the entry list
In my case, I have address that can be set either by autocomplete or clicking on the map. If user click on the map, editText text should be set to address selected from the map, and in that case filtering should be disable temporarily.
I code like this:
public void OnAddressFound(String address) {
// Temporary disable autocomplete
editTextSearch.setAdapter(null);
editTextSearch.setText(address);
// Enable autocomplete again
setAutoCompleteAdapter();
}
where setAutoCompleteAdapter() is called during onCreate, and again in temporary disable/enable filter:
void setAutoCompleteAdapter() {
PlacesAutoCompleteAdapter adapter = new PlacesAutoCompleteAdapter(this, R.layout.item_autocomplete_map_search, autoCompleteList);
editTextSearch.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Hope its help you also.
I found the solution, kinnda tricky but its works
after i looking inside of the source, i found that th treshold variable used as filtering validation, here we just need to set the treshold to maximum int so filtering never perform.
threshold = Integer.MAX_VALUE
or
setThreshold(Integer.MAX_VALUE)