I'm using a list view to displace names. The user needs to be able to add a name to the bottom of the list view and to be able to delete names within. The names are saved using SharedPreferences and loaded into an original string array which I then load to an ArrayAdapter. The problem with this method is that, unless I fill up the entire string array, I get a NPE for the ArrayAdapter. So my solution was to set the string array to only be as big as the number of names. This means, however, that I cannot add a name to the list, as the list is only so long.
What's the best way to be able to add and remove strings from a list view and still be able to tell what they are?
After changing values of listview data please put code
notifyDataSetChanged();
Use the List<T> overload rather than the static array for the ArrayAdapter constructor. Then you can add or remove items to your List<T> and call notifyDataSetChanged() once you are done. Using a dynamic data structure like a List<T> will avoid any NPE.
Related
Good day.
I have an RecycleView list with data from JSONArray. Customer can select or de-select any item from this list by click on it.
So every RecycleView’s item can be in two states: marked (selected) or not.
How best to realize this opportunity? By creating a new separate array with additional “selected” boolean property and loading data into this array when creating a list as a RecycleView’s data source?
Or extend JSONArray with this property and use single data sourse (JSONArray)?
I have little programming experience under Android but see the following advantages and disadvantages:
JSONArray unhandled so needs to use try/catch construction at all
points of work with him;
JSONArray more visible in the code due to named elements like jsonList.put("selected", "false");
work with traditional java array must be faster;
any changes in source JSONArray (in fact, with each new request to the server) needs to full recreation of this ‘buffer’ separate java array.
I suggest you using separate array in adapter for holding item state. In my mind it more flexible when you not need to modify model and keep all logic inside adapter.
You can use different types depends on situation, not only traditional java arrays.
For example, mu solution to hold checked or not state for item in recyclerview:
Declare array to hold state:
SparseBooleanArray itemStateChecked= new SparseBooleanArray();
In onClick() put value for this item:
if (!itemStateChecked.get(item.id))
itemStateChecked.put(item.id, true);
else
itemStateChecked.delete(item.id);
In onBindViewHolder() restore state:
if (itemStateChecked.get(1))
mCheckView.setChecked(true);
else
mCheckView.setChecked(false);
SparseArray accept only primitive as key and SparseBooleanArray returns false if mapping not found.
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
In Android I have a class contains 2 properties. I've created many objects from it and put them into an ArrayList, then using ArrayAdapter to bind the List to a TableView as you see. Once the list is changed, the view will be updated.
The question is, how can I bind my properties with these 2 TextViews in a table-row (a so-called ViewGroup in Android)...? I've tried to take data from the list into 2 String-array: dates and values, but that's odd...
In the getView() method of your adapter, use setTag(), passing in the object you want to attach. You can then, for example, retrieve the object in onListItemClick() (assuming you're using a ListView) by calling Log logItem = (Log) view.getTag().
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]?