I use a custom list adapter and ArrayList for my ListView. This solution was good enough but now I need to use Map of ArrayLists, something like this:
TreeMap<String, ArrayList<ItemsModel>>
where ItemsModel is a Java bean. Earlier I used to populate this ArrayList it that way:
itemsDataArrayList.add(itemModel)
Now I faced some difficulties with Map interface. First, I don't know how to populate my new Map structure: I suppose this
mapInstance.put(itemModel.getItemName.toString(), itemsDataArrayList)
won't work because itemsDataArrayList is the list of elements, not a certain element.
Second, I'm not sure how to properly declare this map instance in my ItemsAdapter class. When I was using just ArrayList it was very simple. Some examples would be very helpful.
What I recommend you look into / try is creating your own BaseAdapter. When you override this class it will give you all the functions you need to override to populate the list view.
This has the advantage of giving you complete control of what is put into the listview and how each view is created.
Then after you get it working I recommend looking into the ViewHolder design pattern along with recycling views which is a great way of improving efficiency when scrolling the listview.
What you are really looking for seem to be a MultiMap. To your first Question - your attemp was quite good, you can only put ArrayLists as values into your TreeMap.
The Problem with this might be, that if you want to add some ItemsModel to your Map, you first need to get the List of the key, and then add the ItemsModel to that list. Additionally you need to ensure, that this list for this particular key exist, and if not, create it.
Example:
String key = "hi";
ArrayList keyList = mapInstance.get(key);
if (keyList == null) {
keyList = new ArrayList();
mapInstance.put(key, keyList);
}
keyList.add(itemsModelInstance);
A get()/contains() and so on may be somehow equal. I'd suggest you build your own Multimap<?,?> Implementation or just take an existing one, like the one from Guava (link above).
Kind regards,
avi
Related
After working on an app for a while I realize I use
adapter.clear()
and
arraylist.clear()
I can see both are working just fine, I would like to know the difference between the two!
Both are called before I start and asyncTask that updates my list with information from my server!
You should not be clearing the ArrayList directly. The ArrayAdapter makes absolutely no guarantees that it maintains the same referenced list given to it. In fact it will change when you perform a search with it's filter. Which would make arrayList.clear() fail.
Rule of thumb, if you ever need to mutate or retrieve the associating data...do it directly from the adapter. Not the list you used to construct it.
Adapter = it contains copies of diff views,arrays
aaraylist holds the data which we want to display in our view.
ex: arraylist<HashMap<String,String>> ah= new ArrayList<HashMap<String,String>>();
the above list contains hashmap
if i clear the arraylist there will be no data to show on listview or gridview so it will be empty
if i clear adapter than it will destroy the copies of array and views so the output will be same
I am banging my head for the last couple days in order to get this done but Im unable to. Someone please help me out!
Let me not tell u the whole thing and will try to explain it simply n clearly.
Im having 1 ArrayList. I am trying to replicate that into another one and trying to delete an item at a particular index. But this not only deletes the item in the replicated ArrayList but also the original ArrayList.
For ex:
var DuplicateList:ArrayList = new ArrayList();
DuplicateList = OriginalList;
DuplicateList.removeItemAt(2);
The above not only deletes the "Item 3" at Index-2 in the DuplicateList but also in the OriginalList.
I just need some workaround with this approach as this is the only way by which whatever I typed inside the controls present in an ItemRenderer of a FLEX List control that uses the OriginalList as a dataProvider is RETAINED, when I change the dataProvider of the List Control from OriginalList to DuplicateList. The following approach does not retain all the data.
var DuplicateList:ArrayList = new ArrayList();
DuplicateList.addAll(OriginalList);
DuplicateList.removeItemAt(2);
ListCntrl.dataProvider = DuplicateList;
Thanks for your help in advance...
A very, very important thing to understand:
ActionScript3 uses references to objects. Because of that, the two variables in this line of code refer to the exact same instance of an ArrayList:
DuplicateList = OriginalList;
So, when you remove an item from one reference, it is gone from the next. If you want two separate instances of ArrayList, then you need to clone it like you are suggesting later in your code.
So far, so good... but why is your ListCntrl retaining the data from the OriginalList? That doesn't make any sense at all. If you remove an item from DuplicateList and then use it as the data provider, then that item shouldn't be there. I think there is more to this story...
I have a ListView where I want each item to have an ID number attached to it (not the same as the position number). I was hoping this could be done by setting a tag to each View item in the ListView using setTag() when these Views are being created.
Right now I'm creating the ListView like this:
final ListView listview = (ListView) findViewById(R.id.listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, names);
listview.setAdapter(adapter);
The names variable in the ArrayAdapter parameters above is an ArrayList, and each string value in this list also has a unique ID that I want to link to this string somehow.
Is there any way I can get access to and modify each of the Views with a tag? One idea was to create my own extended class of ArrayAdapter and override the getView() method, but I don't really understand how it works and how I would go about doing this.
Or is there a better way to link IDs with each string like this than adding tags like I'm trying to do?
Create a ViewBinder and set the tags as the ListView is being populated with whatever you need. You can check all properties of the view to determine what tag goes where, so this should be what you're looking for.
myAdapter.setViewBinder(new MyViewBinder());
public class MyViewBinder implements ViewBinder {
#Override
public boolean setViewValue(View view, Object data, String text){
//Since it iterates through all the views of the item, change accordingly
if(view instanceof TextView){
((TextView)view).setTag("whatever you want");
}
}
}
I just used this exact same answer on another question (albeit slightly different) yesterday.
about getView , it works by using a method of recycling views. i will try to explain it in a simple way.
suppose you have tons of items that can be viewed . you don't want to really create tons of views too , since that would take a lot of memory . google thought of it and provide you the means to update only the views that need to be shown at any specific time.
so , if there is an empty space on the listview , it will be filled with a new view . if the user scrolls , the view that becomes hidden is recycled and given back to you on the getView , to be updated with the data of the one that is shown instead .
for example , if you scroll down , the upper view becomes hidden for the end user , but in fact it becomes the exact same view that is on the bottom .
in order to understand how to make the listview have the best performance and see in practice how and why it works as i've talked about , watch this video:
http://www.youtube.com/watch?v=wDBM6wVEO70
as for tags , i think you want to do something else , since the data itself (usually some sort of collection, like an arrayList) already knows where to update , because you get the position via the getView . if you want a specific view to update , you might be able to do so by using a hashmap that keeps upadting , which its key is the position in the collection , and the value is the associated view . on each time you go to getView , you need to remove the entry that belong to the view (if exists) and assign the new position with the view that you got/created .
Thanks for the answers. thisMayhem's answer would probably have been easier in the end, but on my quest to learn more I ended up making my own adapter according to this tutorial. I pass down the names and the IDs into the adapter and set the names as the text of the TextViews and the IDs as the tags.
I would rather go with the solution discussed in this thread. It is always the easiest to have all related data in same place and in this case you just create a class to hold all the information you will need for every item.
I have a class called people that has its own name, id etc...
I have a full list of people in an array list public ArrayList<people> pList;
When I click on some names I want to add the people in pList to public ArrayList<people> followList; Doing followList.add(pList.get(position)) doesn't work. What is the proper way to do this.
Also, on another click I would like to remove the particular object from the followList so I tried doing followList.remove(pList.get(position)) but obviously it doesn't work as well.
Im basically trying to have a list of people from the original list.
The followList seems to be not initialized. You should call initialize it with new ArrayList<people>() before adding to or removing from it.
Are you sure that you have instantiated the ArrayList followList, and that there is in fact a element at pList[position]?
I have implmented pagination and it display 5 records per page. Now suppose I am on page 3 and click 3'rd element then 3'rd element of page-1 is selected.
I am not able to figure out problem as I always create new list object while setting data.
I used below code
temp = new ArrayList();
this.someListAdapter = new SomeListAdapter(this, R.layout.row_facet,temp);
setListAdapter(this.someListAdapter );
Below is signature of SomeListAdapter class.
public class SomeListAdapter extends ArrayAdapter<VoNeighborhood> {
}
Please help....
There really aren't enough details here about how you do pagination with your ListView.
So I might guess you're overriding onListItemClick and using the position variable it sends you, but you then don't take into account the page you're on?
Alternatively, just don't use pagination as you have an infinite canvas to scroll your list within — I don't think I've recall seeing an Android app so far that uses pagination!