Im following a tutorial and i have created a database class and a activity class. Here is my activity class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new CommentsDataSource(this);
datasource.open();
List<Comment> values = datasource.getAllComments();
// Use the SimpleCursorAdapter to show the
// elements in a ListView
ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
My db is a bit different but most of the stuff is the same as in tutorial. Comment is just a setter/getter class.
Now the problem is that in my list i want to display comment name but i get "com.example.blabla.Comment#40dca9d0". I think it is because i am passing the whole comment class to the adapter. How would be the right way to pass the name?
Here is the link to tutorial, i must be missing something because it seems to work there but i dont know what exactly: http://www.vogella.com/articles/AndroidSQLite/article.html#sqliteoverview_sqliteopenhelper
// Will be used by the ArrayAdapter in the ListView
#Override
public String toString() {
return comment;
}
Did you make sure you added this to your Comment class?
In java the default implementation of toString() is Class#Hashcode which is what currently yours is showing, hence you need to override the default implementation by returning the comment.
You do not see toString() being called because it says in DOCS(parag2)
However the TextView is referenced, it will be filled with the
toString() of each object in the array. You can add lists or arrays of
custom objects. Override the toString() method of your objects to
determine what text will be displayed for the item in the list.
Related
I have a List<Service> received from getParcelableArrayListExtra() Now I need to populate the received objects into a android ListView
I have try to populate the ListView in the following way. The ListView is populated to show the Object reference ids. Instead of showing contants.
How do i show the contents in this list.
The implementation is as follow :
List<Service> serviceCart = getIntent().getParcelableArrayListExtra("serviceCart");
ListView listView = (ListView) findViewById(R.id.lv_choosed_services);
ArrayAdapter<Service> serviceArrayAdapter = new ArrayAdapter<Service>(this,android.R.layout.simple_list_item_1,serviceCart);
listView.setAdapter(serviceArrayAdapter);
Open ArrayAdapter and go to read from line no 405 to 410
final T item = getItem(position);
if (item instanceof CharSequence) {
text.setText((CharSequence) item);
} else {
text.setText(item.toString());
}
What you are doing:
If your item is String Adpater.getView(params) will use it, otherwise it will use item.toString(). In your Service.java you don't have a toString() so application uses default default toString()
What you should do:
Its best to create custom ArrayAdapter and populate your view
Override toString() in your Service.java and use only those values you want to populate in your adapter like service_name and/or service_code and default implementation will do the rest.
Note:
Please read Naming Conventions, its not recommended to name your objects like service_name it should be serviceName.
I have a ListActivity that is currently displaying a list of type Data objects. These type Data objects have custom data:
String title;
The following is in my ListActivity constructor:
List<Data> values = dataInterface.getAllData();
ArrayAdapter<Data> adapter = new ArrayAdapter<Data>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
The application displays on screen all the Data objects without error.
The problem is that the text displayed for each list item is:
Data#42731008
Data#427362c0
and so on.
I understand these are the object id's of the Data objects. Instead, I want to display the Strings found in Data.title. I can't figure out how to accomplish this.
If you don't want to use a custom Adapter, then define the public String toString() method in your Data class as follows:
public String toString {
return title;
}
It will be used by the ArrayAdapter when it represents the object in the ListView.
In your adapter :
holder.myTextview.setText(getItem(position).getTitle());
The point is in the getItem(position).getTitle(), because your custom adapter extends ArrayAdapter<Data>, getItem(position) will return an instance of Data.
After that, you just need to get the title from the Data using getTitle(); (depends on your setter - getter in you Data class).
Just comment if you dont understand something or if i miss understand you :)
I asked a question before about splitting string but maybe it wasn't clear enough.
I made a simple activity which has an example to what my problem is.
I have a message and it's a long one coming from a server.
I need to split this message and put it inside a listview, I'll show you my code.
public class Page1 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity6);
String message = "0---12,,,2013-02-12 08:04,,,this is a test,,,0---11,,,2013-02-12 08:05,,,and this is why it is damaged,,,0---10,,,2013-02-12 08:06,,,what comes from select data randomly";
String[] variables = message.split(",");
ListView listView1 = (ListView) findViewById(R.id.listView12);
String[] items = { variables.toString() };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items);
listView1.setAdapter(adapter);
}
}
Now let's say that the split is commas ", " so it will be
0---12 ------->ID1
2013-02-12 08:04 ------------>date1
this is a test ----------->subject1
0---11 ------->ID2
2013-02-12 -8:05 ------------>date2
and this is why it is damaged ----------->subject2
And so on, now what I can't do is that I want to put these strings in a loop and write them to a listview such that the subject1 should be in item1 and date1 should be in subitem1 like this
Subject1
Date1
------
Subject2
Date2
------
This is how the listview should look like
Can anyone help me with this please?
You would need to create a custom ArrayAdapter to populate a ListView from your objects the way you want.
The advantage of this technic is that you gain a Views recycle mechanism that will recycle the Views inside you ListView in order to spend less memory.
In Short you would have to:
1. Create an object that represents your data for a single row.
2. Create an ArrayList of those objects.
3. Create a layout that contains a ListView or add a ListView to you main layout using code.
4. Create a layout of a single row.
5. Create a ViewHolder that will represent the visual aspect of you data row from the stand point of Views.
6. Create a custom ArrayAdapter that will populate the rows according to you needs, in it you will override the getView method and use the position parameter you receive for the corrent row View to indicate the row index.
7. Finally assign this ArrayAdapter to your ListView in onCreate.
You can get an idea of how to implement this by reading this blog post I wrote:
Create a Custom ArrayAdapter
Please note that ArrayAdaper is designed for items containing only one single TextView. From the docs:
A concrete BaseAdapter that is backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView
Consider subclassing ArrayAdapter (docs) and override its getView method.
I've been playing around with ArrayAdapters and I've reached a point where I'm getting different results from two almost identical ArrayLists + ArrayAdapter combinations.
The first one:
An ArrayList of 'Restaurant' objects, an ArrayAdapter that uses this ArrayList and a ListView that binds this ArrayAdapter.
private ArrayList<Restaurant> model = new ArrayList<Restaurant>();
private ArrayAdapter<Restaurant> restaurantAdapter = null;
...
public void onCreate(Bundle savedInstanceState){
...
restaurantAdapter = ArrayAdapter<Restaurant>(this, android.R.layout.simple_list_item_1, model);
...
listView.setAdapter(restaurantAdapter);
...
}
The second one:
An ArrayList of String objects, an ArrayAdapter that uses this ArrayList and a AutoCompleteTextView that binds this ArrayAdatper.
private ArrayList<String> prevAddressList = new ArrayList<String>();
private ArrayAdapter<String> addListAdapter = null;
...
public void onCreate(Bundle savedInstanceState){
...
addListAdapter = ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, prevAdddressList);
...
autoCompleteField.setAdapter(addListAdapter);
...
}
I have a save button, on click, I'm creating a restaurant object with a name and an address and adding it to the first adapter, additionally, I want to create a list of previously used address so they are "auto completed" next time they are typing it, so I'm taking the text, and adding it to the second adapter.
...onSave = new View.OnClickListener(){
...
restaurantAdapter.add(r); //r is a Restaurant object.
addListAdapter.add(autoCompleteField.getText().toString());
...
}
Now, everything is working properly. I get the Restaurants displayed in a ListView. The AutoComplete is working as expected.... but I noticed something when I was checking the values while debugging:
The actual ArrayLists, model (Restaurant) is getting updated after adding an object to the adapter , but prevAddressList (String) is not.
Unless, I set the AutoCompleteTextField empty.... then, the prevAddressList gets updated after adding something to the second adapter.
Already tried using notifyDataSetChanged(), but it makes no difference (and it is set to true on every adapter by default anyway).
Other behavior that differs between the two adapters is that in the first one (Restaurant), values are going to the mObjects field, while in the second one (String) they are going to mOriginalValues instead.
I'm completely stomped. The only difference between those two adapters is that one is type "Restaurant" and the other is type "String".
Any ideas? Maybe I'm missing something very obvious? Let me know if you need the full code.
thanks
Instead of adding it to the adapter, try adding the object to your list and then calling notifyDataSetChanged on your adapter. The adapter should pick up your changes and your list of course will have the object you just added.
For anyone coming here from google:
Unable to modify ArrayAdapter in ListView: UnsupportedOperationException
This might explain the behavior, although I have to test it myself.
I have this ListView that is using an array adapter:
//global
ArrayList<Location> locations=new ArrayList<Location>(); //array list of location objects
ArrayAdapter<Location> theLocations;
ListView listView;
then in onCreateView of my Fragment:
theLocations = new ArrayAdapter<Location>(mContext,
R.layout.location_row, locations);
listView.setAdapter(theLocations);
This works pretty well I think, though if I try to update this adapter it freaks out...
//in my fragment, another dialog makes this call here to update the list.
public void onUIUpdate(Location l) { //listener call back when dialog "ok" clicked
locations.add(l); //it is okay with this.
theLocations.notifyDataSetChanged(); //dies
}
It dies with the error:
07-23 08:03:28.655: ERROR/AndroidRuntime(509): java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
does that mean it doesn't like the Location in the ArrayAdapter ??? does this mean I have to make my own custom listadapter? If I don't call theLocations.notifyDataSetChanged() everything is okay but then nothing updates... :(
I should note that the toString() in the Location class is override to return a String name;
after a comment I tried this:
public void onUIUpdate(Location l) {
locations.add(l);
//theLocations.notifyDataSetChanged();
WrapperListAdapter wr = (WrapperListAdapter)listView.getAdapter();
ArrayAdapter aa=(ArrayAdapter)wr.getWrappedAdapter();
aa.notifyDataSetChanged();
}
LOL no luck here, was a stab in the dark. Also wandering if its the addHeaderView I used on the ListView? I am not sure if it makes it immutable in the future using addHeaderView?
I won't comment about ListView design, it is very ugly, but I do listView.getAdapter().getWrappedAdapter().notifyDataSetChabged(); and it works.