Java/Android Arraylist giving addresses - java

I am trying to display a list in android using guidance from vogella's tutorial for sqlite in android :
this is part of my ProjectListDataSource class (This gets all data from the sqlite database):
public List<ProjectList> getAllProjects() {
List<ProjectList> projects = new ArrayList<ProjectList>();
Cursor cursor = database.query(ProjectListHelper.TABLE_PROJECT_LIST,
allColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
projects.add(cursorToProjectList(cursor));
cursor.moveToNext();
}
// make sure to close the cursor
cursor.close();
return projects;
}
private ProjectList cursorToProjectList(Cursor cursor) {
ProjectList projList = new ProjectList();
projList.setId(cursor.getLong(0));
projList.setProjName(cursor.getString(1));
projList.setProjComment(cursor.getString(2));
projList.setProjDateTime(cursor.getString(3));
return projList;
}
And this is my activity class :
public class ProjectListActivity extends ListActivity implements
OnClickListener {
private static final String TAG = "ProjectListActivity";
private ProjectListDataSource datasource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_projectlist);
Log.d(TAG, "On Creat'd");
init();
}
private void init() {
// Getting data from database and adding to ListView
datasource = new ProjectListDataSource(this);
datasource.open();
List<ProjectList> values = datasource.getAllProjects();
ArrayAdapter<ProjectList> adapter = new ArrayAdapter<ProjectList>(this,
android.R.layout.simple_list_item_activated_1, values);
setListAdapter(adapter);
}
But on doing that I am getting unexpected result like this (see image) :
http://i.imgur.com/tQMooi8.png
But the database has records like this (see image):
http://i.imgur.com/HfY2azs.png
Can anyone please explain and give a solution as to why I cant get the list view to show the records as in the database...
Thanks,
Viney

Basic adapters, like ArrayAdapter or CursorAdapter, will map only one value to a single view. Here, a ProjectList object to a TextView with the id of android.R.id.simple_list_item_activated_1
You need a single layout(for a single view within the ListView) with multiple views to which you will map id, name, date, comment, etc. You need to extend one of the adapters. Preferably BaseAdapter or CursorAdapter.

There are several issues here, depending on what you want to display.
The reason you're seeing the object string reference in your list is because you're using a plain ArrayAdapter, which simply calls toString() on the objects in the array. If you override toString() in ProjectList, you can display what you want (though that's normally not the best way to solve this problem).
Another option which would allow you to keep using a plain ArrayAdapter would be to create an array of strings from the ProjectList objects of the data you want to display. A bit wasteful, but that's another option.
What you normally want to do is extend ArrayAdapter and override getView(). In getView() you assign the data you want to display in the view.
If you want to display all the data from your ProjectList objects in a single list item, you'll also need to create a custom layout to represent the row.

Related

Pass number of repeated database column instances into TextView with CursorAdapter

I am fairly beginner and currently writing an app which contains a list of Restaurants. I am using a SQLite database to store the "Restaurant" objects and am using a CursorAdapter to display them into a ListView.
Currently the fields are a photo, the name of the restaurant and its location.
I want to have one more TextView which shows how many times that certain restaurant appears in the database. I'm having trouble figuring out how to do this inside my CursorAdapter class.
Below is my bindView method in the CursorAdapter class where the existing views get updated.
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find individual views that we want to modify in the list item layout
ImageView foodImageView = (ImageView) view.findViewById(R.id.food_image_view);
TextView restaurantNameTextView = (TextView) view.findViewById(R.id.restaurant_name_text_view);
TextView restaurantLocationTextView = (TextView) view.findViewById(R.id.restaurant_location_text_view);
// Find the columns of restaurant attributes that we're interested in
int foodPictureColumnIndex = cursor.getColumnIndex(RestaurantEntry.COLUMN_FOOD_PHOTO_URL);
int restaurantNameColumnIndex = cursor.getColumnIndex(RestaurantEntry.COLUMN_RESTAURANT_NAME);
int restaurantLocationColumnIndex = cursor.getColumnIndex(RestaurantEntry.COLUMN_RESTAURANT_LOCATION);
// Read the restaurant attributes from the Cursor for the current restaurant
String foodPhoto = cursor.getString(foodPictureColumnIndex);
String restaurantName = cursor.getString(restaurantNameColumnIndex);
String restaurantLocation = cursor.getString(restaurantLocationColumnIndex);
// Update the Views with the attributes for the current restaurant
Picasso.with(mContext).load(foodPhoto).into(foodImageView);
restaurantNameTextView.setText(restaurantName);
restaurantLocationTextView.setText(restaurantLocation);
}
Answered my own question; used a temporary ArrayList to track how many times a certain name appears in the database table

Android Array Adapter with ArrayList and ListView not updating when the arraylist is changed

I have an android app with a screen that comprises of a ListView, which I am using to display a list of devices. These devices are held in an array.
I am trying to use the ArrayAdapter to display what is in the array on the screen in a list.
It works when I first load the SetupActivity class, however, there is the facility to add a new device in the addDevice() method, which means the array holding the devices is updated.
I am using notifyDataSetChanged() which is supposed to update the list but it doesn't seem to work.
public class SetupActivity extends Activity
{
private ArrayList<Device> deviceList;
private ArrayAdapter<Device> arrayAdapter;
private ListView listView;
private DevicesAdapter devicesAdapter;
private Context context;
public void onCreate(Bundle savedInstanceState) //Method run when the activity is created
{
super.onCreate(savedInstanceState);
setContentView(R.layout.setup); //Set the layout
context = getApplicationContext(); //Get the screen
listView = (ListView)findViewById(R.id.listView);
deviceList = new ArrayList<Device>();
deviceList = populateDeviceList(); //Get all the devices into the list
arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
listView.setAdapter(arrayAdapter);
}
protected void addDevice() //Add device Method (Simplified)
{
deviceList = createNewDeviceList(); //Add device to the list and returns an updated list
arrayAdapter.notifyDataSetChanged(); //Update the list
}
}
Can anyone see where I am going wrong?
For an ArrayAdapter, notifyDataSetChanged only works if you use the add, insert, remove, and clear functions on the Adapter.
Use clear to clear the adapter - arrayAdapter.clear()
Use Adapter.addAll and add the newly formed list - arrayAdapter.addAll(deviceList)
Call notifyDataSetChanged
Alternatives:
Repeat this step after new devicelist is formed - but this is
redundant
arrayAdapter = new ArrayAdapter<Device>(this, android.R.layout.simple_list_item_1, deviceList);
Create your own class derived from BaseAdapter and ListAdapter that
gives you more flexibility. This is most recommended.
While the accepted answer solves the problem, the explanation of why is incorrect, and since this is an important concept I thought I'd attempt to clarify.
Slartibartfast's explanation that notifyDataSetChanged() only works when add, insert,remove, or clear is called on the adapter is incorrect.
That explanation is true of the setNotifyOnChange() method, which if set to true (as it is by default) will automatically call notifyDataSetChanged() when any of those four actions occur.
I think the poster confused the two methods. notifyDatasetChanged() itself does not have those restrictions. It just tells the adapter that the list it is looking at has changed, and it does not matter how the change to the list actually happened.
While I can't see the source code for your createNewDeviceList(), I would guess your problem came from the fact that you had the adapter referencing the original list you created, and then you created a new list in createNewDeviceList(), and since the adapter was still pointing to the old list it could not see the changes.
The solution slartibartfast mentioned works because it clears the adapter and specifically adds the updated list to that adapter. Thus you don't have the problem of your adapter pointing to the wrong place.
Hope this helps someone!
your method addDevice is causing an endless loop. Dont call a method from itself like you are doing here :
deviceList = addDevice();

java android load items to listview from database?

Okay so i have a database, and i want it so you can favorite items.
Would i make it so you can save items then it will load it into a list view?
this is my load thing
//Calls the database, gets a list of names.
// if listofnames.size()==0 keep name, otherwise
// change name to first name.
ArrayList<String> nameList = new ArrayList<String>();
favList = db.getName();
if(favList.size()>0){
name.setText(favList.get(0));
But that just sets a text i want it to add items..
You may use ArrayAdapter or SimpleAdapter or BaseAdapter - through which you may bind dataSource (List<T>) to the ListView.
You can do this as follows
public class MyClass extends ListActivity{
public void onCreate(Bundle bundle){
//get the names from database
setListAdapter(new ArrayAdapter<E>(this,R.layout.xml_filename,your_list);
}
}
Remember in this case your xml file should be the TextView (I.e the items what list view should contain). You cannot pass an xml file with a ListView directly.
If you have still some problem, then post your code which can be solved.
You can follow the given link for more clarification.
http://developer.android.com/resources/tutorials/views/hello-listview.html

Inserting EditText & Spinner data to SQLite?

I'm trying to figure out how to capture data from a form using EditText & Spinner's and insert it into a SQLite database. I am able to write the hard coded attributes but when I try to use R.id.fieldName it throws an error due to being an Integer vice a String.
public class PetAdd extends Activity {
DBAdapter db = new DBAdapter(this);
private OnClickListener btnPetAddListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
db.open();
long id;
id = db.insertPet("name", "type", "breed", "sex", "notes");
/**id = db.insertPet(R.id.petName, R.id.SpinnerPetType, R.id.petBreed, R.id.SpinnerPetGender, R.id.EditTextPetAddOptions);*/
db.close();
}
};
I'm still trying to learn all this stuff and my brain is fried from looking at a plethora of online tutorials, examples and Google documentation. If anyone can show me how to do this or direct me to a barney style tutorial that breaks it down for me to understand what's going on, it'd be greatly appreciated.
R.id.fieldName is a numeric reference to the item in your Activity (provided it's part of your layout).
You'll need to call findViewById(R.id.fieldName) to get a refererene to it. You'll also need to cast it to the correct type of view (in your case EditText) and then call getText().toString() on the whole thing.
Putting it all together...
EditText myField = (EditText)findViewById(R.id.userName); //assuming you have a field named userName in your XML
String userNameValue = myField.getText().toString();
Oh, and welcome to Stack... don't forget to mark answers as correct and up-vote them when they're helpful.
If you use R.id.name you are in fact using internally generated int that Android uses. You need the raw data your spinner has.
I suggest you play with getItem and getItemId in your Spinner. If you are using a SimpleAdapter you can expect to get the ID of your item with getItemId.
The implementation of getItem is up to you. I usually use BaseAdapter or in the case of Spinners, ArrayAdapter, which has several convenient methods.
And with the EditText you need to call getText() to the EditText.

Best way to refill data in ListAdapter (ListView)

I do use this code for refill ListView with data after they change
// ListView lv;
// MyListAdapter la;
// DataClass dc;
dc.remove(object_id);
lv.setAdapter(la);
Is this the best way since we can't use notifyDataSetChanged() which is available only in ArrayAdapter ?
Solution
//MyListAdapter.java
private ArrayList<DataSetObserver> observers = new ArrayList<DataSetObserver>();
public void registerDataSetObserver(DataSetObserver arg0) {
observers.add(arg0);
}
public void unregisterDataSetObserver(DataSetObserver arg0) {
observers.remove(arg0);
}
public void notifyDataSetChange() {
for (DataSetObserver d : observers) {
d.onChanged();
}
}
public void remove(int position) {
[DataClass object].remove(position);
notifyDataSetChange();
}
For a CursorAdapter I use the following code:
mAdapter.getCursor().requery();
If you are using custom adapter or as you commented: only want ListAdapter as member variable. Instead of using private CustomAdapter mAdapter; (which i would recommended to avoid creating unnecessary objects).
You can use DataSetObserver part and ListAdapter.registerDataSetObserver(DataSetObserver observer). DataSetObserver.onChanged() will be called by the BaseAdapter implementation, so it should work for all adapter.
BaseAdapter.notifyDataSetChanged():
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
You can use ArrayAdapter, which accepts Lists instead of Arrays. This way you can use notifyDataSetChanged() on it.
It seems that you think something wrong as I was did.
As you know, ListAdapter hasn't notifyDataSetChanged.
It seems that Cursor is the best match with a ListView. Doc. says that "Frequently that data comes from a Cursor, but that is not required. The ListView can display any data provided that it is wrapped in a ListAdapter."
If you check both links registerDataSetObserver ([DataSetObserver]2 observer), you can notice something. ListAdapter go well with a cursor. So why don't you try to use other adapters.
I think the best way to refresh adapter is using or extending BaseAdapter(with ListView). And use notifyDataSetChanged after change your dataset. In my case it works well and softly(invalidating list view and items, and scroll position is just there! Not going to first position).

Categories