I need to change just first row in my ListView. I used such way:
private void updateAdapter(int number) {
String value = Integer.toString(number);
list_.clear();
list_.add(value);
adapter_.notifyDataSetChanged();
}
But, does anybody know another way, like myAdapter.update(newValue)? I use simple adapter
private ArrayAdapter<String> adapter_;
and ListView
<ListView
android:id="#+id/list_view"
android:paddingBottom="150dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Basically, if your add or remove elements from your data source (which I assume is list_ here) and you call notifyDataSetChanged(), the ListView will get recalculated in the designated way based on your (changed) data source.
Therefore it wouldn't make sense to directly update your adapter (with the proposed function adapter.update()).
If you're worried about performance (which I think is your motivation here when only changing the first row) check Using an ArrayAdapter with ListView to see how the population of a ListView works.
Get the element by using getItem (int position) from the SimpleAdapter class. No you can change the object inside the adapter.
After change value call...
listAdapter.notifyDataSetChanged();
... to refresh your UI.
See doc: SimpleAdapter - getItem(int pos)
Related
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 have a ListFragment backed by an ArrayAdapter that gets populated by a Loader. When the user clicks on one of the items, I want to pass a reference to the selected item, as well as the rest of the list items to another fragment. My question is how should I get all of the items from the adapter? Here are the possibilities that I see:
1. Keep a reference to the backing List
Create the adapter like so:
List<DomainObject> items = new ArrayList<DomainObject>();
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine, items);
and then simply pass items or a copy of it to the next activity.
The downside I see of this is that I'm relying on the undocumented fact that the same list that I pass to the constructor contains the items later on.
2. Iterate through the adapter
When an item is clicked, iterate through the adapter and build up the list. This seems like an unnecessary amount of work. The items are contained in a List in the adapter and I'm manually copying each item to a new list.
3. Keep a separate list of items when adding to adapter
Before adding an item to the adapter, add it to a separate list that I maintain in the fragment. This is also wasteful as the list of items is copied in the ArrayAdapter and the fragment.
I'm a little late to the game, but I've run up against a similar issue.
One way to deal with #1 would be to maintain the reference to the list within a subclass of ArrayAdapter, so that your reuse is controlled by the adapter object.
Something like:
public class DomainAdapter extends ArrayAdapter<DomainObject> {
private final List<DomainObject> items;
public DomainAdapter(Context context, List<DomainObject> items) {
super(context, R.layout.mine, items);
this.items = items;
}
public List<DomainObject> getItems() {
return items;
}
}
The solution that I've gone with in the meantime is just to not use ArrayAdapter. In cases where you're fighting against this API, it seems like it's better just to use the less fully-featured (and complex) BaseAdapter. You can read more about the decision to go with BaseAdapter instead of ArrayAdapter in this article: Android Adapter Good Practices.
A quick test says that method 1 works. It seems the quickest and cleanest, but since it is undocumented you may want to test it across the intended platforms and whenever they update in case the underlying structure of ArrayAdapter changes.
I am using compile SDK version 22 and min SDK Version 10.
The best method is to "keep a reference to the List" BUT not passing "items" variable/parameter to the Constructor:
List<DomainObject> items = new ArrayList<DomainObject>();
listAdapter = new ArrayAdapter<DomainObject>(getActivity(), R.layout.mine);
In this way you only instantiate the ArrayList as an empty array and you will have to manage YOUR list by yourself.
I think first method is best way to do this.
I dont think, Data would be original for the Another Activity. because, You would pass items through bundle, so the object is written on bundle first and then in next Activity we read from bundle.
However, if you are using some other way to pass the list, use list.clone() to create new Object, instead of passing original one.
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 an ArrayList of an object which has properties Object.name and Object.url.
I want to loop through the ArrayList and apply the Object's "name" to an android ListView. I also want to keep the Object's other properties in tact, so that i can call the "url" property in the onClick method.
What i have now is this:
main_list.setAdapter(new ArrayAdapter<RomDataSet>(this, android.R.layout.simple_list_item_1, android.R.id.text1, mRoms));
But clearly that is not what I need...
Any help would be appreciated :)
1.) You have your ArrayList:
main_list
2.) Create a ListView in your XML file (say, main.xml) and grab its id. That is, given:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/liveFeed"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Do something like this:
ListView livefeed = (ListView)this.findViewById(R.id.liveFeed);
within your activity (if you're in somewhere else such as an OnClickListener, replace the "this" with the View variable that was passed as a variable into the OnClickListener).
3.) Define your ArrayAdapter. Note that one of its parameters (the third one in your case) will be a TextView id. This is because the ArrayAdapter class, by default, returns a TextView in the ListView. If you override the ArrayAdapter class, you can use custom layouts to have items with custom Views within your ListView, but this is not necessary for what you've outlined in your question, and it seems like you've got it already.
4.) Set the adapter to the ListView (given an ArrayAdapter named 'aa'):
livefeed.setAdapter(aa);
Now the way the ArrayAdapter works is it invokes each Object's toString() method and sets each TextView in the ListView to this String. So make a toString() method in your Object's class that returns its name property:
public String toString(){return name;} //assuming name is a String
Also note that, if you add Objects to the ArrayList, notify the ArrayAdapter that you have so it can accordingly update your ListView with the modifications (given an ArrayAdapter named 'aa'):
aa.notifyDataSetChanged();
Let me know if you need any more help. As always, check the answer check mark if this answered your question.
Also note that, at one point you may wish to cross reference your ArrayAdapter and ArrayList between your activity and Object class. It's very helpful to make these fields static in order to do so.
EDIT:
You wanted to also know how to access a specific Object when you click on an item in the ListView. Here it is (given your ListView is named livefeed):
livefeed.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//in here you may access your Object by using livefeed.getItemAtPosition(position)
//for example:
Object current = livefeed.getItemAtPosition(position);
//do whatever with the Object's data
}
});
I am having a situation where I want to update my Custom List View using BaseAdapter whenever my Database is updated. I have tried calling invalidate() on this Custom List but it didn't work, similarly I even tried having a timer to update my list after sometime, that didn't work either. Please let me know of possible solution.
Update:
This is how I am making my custom list view
li= (ListView)findViewById(R.id.id_lv_row);
ColorDrawable divcolor = new ColorDrawable(Color.DKGRAY);
registerForContextMenu(li);
li.setDivider(divcolor);
li.setDividerHeight(2);
li.setAdapter(new FriendsPositionAdapter(this));
BaseAdapter.notifyDataSetChanged() should do the trick as long as the data behind the adapter actually changed. That's all you need to do to refresh the list.
Invalidate is for repainting views only, you have to tell to the List adapter (BaseAdapter) that dataset has changed.
When the data changes, asign the new dataset to the adapter, and later call notifyDataSetChanged()...
in order to make functional notifyDataSetChanged() the adapter data must be changed. Remember that the original data that change is not reflected automatically to the adapter.
//here i retrieve the new list, named "beans"
lista = (BeanList) result.getDataObject();
Vector<Bean>beans = list.getBeanList();
((BeanListAdapter)listAdapter).syncData(beans);
((BeanListAdapter)listAdapter).notifyDataSetChanged();
//now the syncData method
public void syncData( List<PINPropiedad> newData ){
for(Object o : newData){
add(o);
}
}