I completed the Notepad Tutorial Part 2 and everythings works fine.
But there is one thing I just can´t figure out why it is working ;)
The onListItemClick callback retreives the parameters:
ListView l - Check
View v - Check
position - Position of the item the user clicked on, starting with a zero based index (right?)
id - Row ID of the item the user clikced on
This seems to be the same rowId like used in the SqlLite DB table "notes"...but where the hell does
the ListActivity know about that we use this column as row Id?
I didn´t find any mapping between the List and the DB table, just the Cursor we bound in fillData.
But there is only a mapping between the Title column and the text1 id in the UI.
So where is the rowId binding? And what if I wanted to change that binding to another source?
Thx in advance
Alex
The SimpleCursorAdapter (in the fillData() method) binds the data of the database cursor to the listview. Whenever an item is clicked the CursorAdapter realizes which item is clicked and handes over the id to the listactivity.
This is NOT a rowID like in SQL. Databases are completely different from form elements.
rowID in this context is simply a 0-based index to tell you what you are clicking on. Your Cursor is simply filling data into the ListView from a table. Unless you are making direct queries with ContentProviders or SQLite queries, you shouldn't have to select the rows.
I hope this helps!
Related
Ok, I have a database with id column as timestamp
I made an activity list from the db.
I want to manage the db (delete rows) using the list, but the thing is I don't want to
View the whole timestamp, in every row I'll put only the time with some info and
I want to group the list ,as in contacts grouped by alphabet, by the date.
First, how can I make group in an activity list? (Making groups to the output list not the db)
Second, what is the best way to implement this? When user chooses an item and confims delete
I should delete it from the db but I have only patial timestamp...
(My only link to the db is the timestamp - I don't actually know where to store it in the list and I don't want to put it as a string in the text view, do a substring to get it back - is there another way to do this?)
I tried to search tthe web for some examples but I only found a simple ones.
Thnx :-)
?
I think what you're trying to do is create a database of tasks identified by a timestamp. You probably don't want to use a timestamp as a unique ID for the row. Instead, use an integer and qualify it as "PRIMARY KEY" when you create the database.
group the list? I'm not sure why you want to do this in the structure of the database. It's more common to group the list in the output, and leave the db itself in as flat a structure as possible.
Retrieve the primary key when you display a list of tasks. When the user clicks a task, use the primary key to choose the task to delete. You don't have to display the primary key; it serves as a behind-the-scenes "link" between the displayed info and the db row.
http://www.vogella.com/articles/AndroidListView/article.html
I should use cursor adapter for managing db.
And this one for grouping a list:
http://code.google.com/p/android-amazing-listview/
Thnx for the efforts
I'm just starting to dive into some basic Android development and have been experimenting with a ListView and integrating it with a SimpleCursorAdapter. I look through a lot of online code samples, but I also have a book to use as a reference (Professional Android 2 Application Development).
In the book they work out an example To-Do list application that stores the list items in a SQLite database with an auto-incrementing, integer, primary key field.
A user can create new list items, but can also delete a selected item from the list. In the code, when the delete occurs, the primary key field is restricted (within the WHERE clause of the SQL statement) by the position attribute of the item as opposed to the item's rowid.
To me, this seems like an incorrect implementation. Looking at the SQLite documentation for AUTOINCREMENT, it says that this value will always increase and old values will never be re-used on the same table. So if you're deleting and adding things to the list, it would seem that the position and row id can get out of sync rather quickly.
Am I correct, then, to assume that the row id is the correct way to "index" into the database table and not the list position? I think the position would be safe to use if one is using the regular ListAdapter, but doesn't seem suitable when indexing into the database.
You can use the position to get a cursor to a particular list entry (and this cursor would be the 'row' in the 'table' corresponding to the row id):
Cursor cursor = (Cursor)parent.getItemAtPosition(pos);
int rowCol = c.getColumnIndex("_id");
Then you should see that cursor.getLong(rowCol) == id
That is definitely bad practice. I always use the row id to delete, and use the position id to retrieve the cursor's row id. I have the first edition of that book at home, I'm going to take a look at it myself later.
I am retreiving 20 names from an sqlite database and displaying them in the form of listview. They are unsorted. I use filter and sort them alphabetically so that I avoid unnecesary scrolling. I have an edittext too. When I type a key, it matches the listitems and filters the list. Each listitem has a respective text with it,
The problem now here is, when I sort and filter, the position of the listitem changes. When I click on that, it displays its current positions text and the listitem's text.
For example: I have a 3 DB entries
ROWID NAME DESCRPTION
1 RASHMI I AM FRM INDIA
2 RICHA I AM FROM USA
3 STELLA I AM FROM CANADA.
My list view displays only the NAME column. Now when I press S in the edittext, STELLA comes up from position 3 to position 1. When I click on that listitem, it displays I AM FROM INDIA instead of I AM FROM CANADA. Every action is taking place from SQLite DB.
post your adapter code.
if you are changing the cursor on the adapter as you probably are. be sure to get the cursor from the adapter by calling
Cursor c = adapter.getCursor()
c.moveToPosition(position);
String description = c.getString(c.getColumnIndex("DESCRIPTION"));
the key thing is to move the cursor to the desired position in the list. also be sure you are using the attached cursor to the listView not a previously saved instance or from your first query when you were assigning it to the adapter.
I am very new to Android.
Can anybody tell me how can I get the selected item from the ListView when the data is coming from a Cursor
Thanks.
If you created a ListActivity (which has a ListView in it), the onListItemClick()-method is called every time a entry in the list is clicked. This method has a parameter long id which contains the ID of your selected Item.
The idea behind this is, that every entry in your SQLite Database has a unique ID (using auto_increment). If you set your ListActivity up with a SimpleCursorAdapter, you'll need to have a column named _id (if you have a ID-column with another name, use the AS-function). This column is automatically used to determine which ID the clicked entry has.
So lets say one of your entry's has the ID 12 and this ID is in the column _id. If you select this entry from your ListView, the onListItemClick()-method's id-parameter will contain the value 12.
This is the easiest way if you're using a Database for your content (like in a Notebook).
You set an OnItemClickListener for the ListView using the setOnItemClickListener method.
Within that method you have the selected position and you can call your adapter's getItem method for that position.
You should probably override getItem in your adapter to return a properly constructed object from your domain.
I have a listview which is populated by a SimpleCursorAdapter that is binding data to the view from a cursor from a sqlite database. I would like to have a context menu option to delete the a list item when it is long pressed, so I register the ListView for a context menu by calling registerForContextMenu(historyListView). I've been trying to remove the row from the database by getting the row id in OnCreateContextMenu and storing it as a private field called lastSelectedId, then if the remove context item is selected in OnContextItemSelected, removing the row from the database by checking the _id column against lastSelectedId.
This isn't working.
So -
(1.) is the row as given by
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
lastSelectedId = info.id;
the same as the _id column in the database?
and (2.) if not, how else can I delete the item in onContextItemSelected() based on the _id of the row in the database?
EDIT: Sorry about not explaining why this approach wasn't working more in-depth: What happens is that nothing happens when I attempt to delete the row: I call mDB.delete(DB_TABLENAME,"_id=" + lastSelectedId, null); on the database and then I call bookmarksListAdapter.notifyDataSetChanged(); on my SimpleCursorAdapter. Then I see no change in the entries in my listview, which differs from my expected behavior that the row which I called remove on will disappear.
When you say it isn't working, what isn't working? Does it not delete the entry? Does it not display the updated list? How are you deleting the row? Can you share some more code?
In general, id is generally the _id of the database (if you use the standard conventions). Are you using your own content provider? You need to notify system that the database changed so it can be requeried - this is typically done if you followed the ContentProvider samples from the SDK (look at notifyChange), and if you use a managed query.
Figured it out. I needed to re-do the cursor after the database was changed (for some reason I had thought that this would be done automatically - my mistake) bookmarksDbCursor.requery() fixed it for me.