In my DB class have a method that returns a Cursor. the cursor will contain data from different tables:
public Cursor fetchFavTitles() {
return myDataBase.rawQuery("SELECT rowid as _id, title, fav FROM table1 " +
"WHERE fav = 1 UNION ALL " +
"SELECT rowid as _id, title, fav FROM table2 WHERE fav = 1 UNION ALL " +
"SELECT rowid as _id, title, fav FROM table3 WHERE fav = 1 UNION ALL " +
"SELECT rowid as _id, title, fav FROM table4 WHERE fav = 1 UNION ALL " +
"SELECT rowid as _id, title, fav FROM table5 WHERE fav = 1 UNION ALL " +
"SELECT rowid as _id, title, fav FROM table6 WHERE fav = 1", null);
}
Then, I use a SimpleCursorAdapter ca to attach the Cursor to a ListView lv :
Cursor cursor = myDbHelper.fetchTitles(c);
String[] columns = {cursor.getColumnName(1)};
int[] columnsLayouts = {R.id.item_title};
ca = new SimpleCursorAdapter(this.getBaseContext(), R.layout.items_layout, cursor,columns , columnsLayouts);
lv = getListView();
lv.setAdapter(ca);
Now, if I select any item in the ListView, I want to have a reference to that item id.
I want the id to retrieve other information from the table the item belong to. And retrieve it in other activity MsgView
I tried this:
have a reference to the id passed when an item clicked
pass that value with the intent, so that the other activity will retrieve the needed data using this passed value.
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(view.getContext(), MsgView.class);
i.putExtra("id", (int) id); //
startActivity(i);
}
});
However, this didn't work. It seems that the id I'm using is not the item's id !
Any solution or ideas ?
In onItemClick method try this...
final SimpleCursorAdapter simpleCursorAdapter = (SimpleCursorAdapter) parent.getAdapter();
final Cursor cursor = simpleCursorAdapter .getCursor();
final int idColIndex = cursor.getColumnIndex(KEY_ROWID); //_id column of your table
final int rowId = cursor.getInt(idColIndex);
Used in one of my project here is link refer line number 41. Hope this help.
Edit:
Solved. See comments.
You want the position parameter not the id
See the documentation of onItemClick:
public abstract void onItemClick (AdapterView<?> parent, View view, int position, long id)
Since: API Level 1 Callback method to be invoked when an item in this AdapterView has been clicked.
Implementers can call getItemAtPosition(position) if they need to access the data associated with the selected item.
Parameters
parent: The AdapterView where the click happened.
view: The view within the AdapterView that was clicked (this will be a view provided by the adapter)
position: The position of the view in the adapter.
id: The row id of the item that was clicked.
You could create a static data member in your MsgView class that you use to store the id, or you can send a delayed message to the class, making sure that the activity gets loaded and started before the message arrives.
You can use the View.setTag() and View.getTag() methods to store any data in your views. Sometimes I have exploited this to 'tag' a Intent object to each row in a ListView. Whenever I need to lookup data for a row i just get the Intent back with getTag()
I found a solution to my problem.
Although it is not a professional solution, but it is the only one I have now. I added a new column in each table named: tableNumber so that each table will have a different number. Then, I can distinguish between items based on that number.
Thanks for your answers. and special thanks to #gopal
Related
I have a listView populated with data from my db. I use a simpleCursorAdapter to show the values.
I have a table where i can add lessons : English, french...
In another table, i can create lessons developped (i add date of beginning and end, which days, a theme for the lesson). I must provide the lesson as a FK.
When I add a lesson, in my listView i want to show per example : English - Reading, but it shows 1 - Reading. Because 1 is the value i store in my 2nd table.
How can I change 1 to English ?
Here's my code :
Cursor cursor = dbhelper.getAllCours();
String[] from = { "branche_cours", "designation" }; //here 'branche_cours' is the lesson i store as an INT, it's the FK so
int[] to = { R.id.text_branche_cours, R.id.text_designation };
adapter = new SimpleCursorAdapter(this, R.layout.list_row, cursor, from, to, 0);
lvCours.setAdapter(adapter);
adapter.notifyDataSetChanged();
The method i use getAllCours()
public Cursor getAllCours()
{
//from here, i retrieve the ID, designation and branche_cours
String Query = ("select ID as _id, date_debut, date_dernier, dixieme_point, " +
"demi_point, description, designation, lundi, mardi, mercredi, jeudi," +
" vendredi, samedi, branche_cours from " + TABLE_COURS);
Open();
Cursor cursor = db.rawQuery(Query, null);
return cursor;
}
How can I link that int to the real value ( so how can the '1' become 'English')?
One solution would be to perform an SQL JOIN operation to fetch the data from both tables:
So the SQL query should be something thing like:
SELECT table1.branche_cours, table2.designation
FROM table1
INNER JOIN table2 ON table1.ID=table2.ID;
To look up a value in another table, you can use a correlated subquery:
SELECT ID AS _id,
...,
samedi,
(SELECT name
FROM other_table
WHERE other_table.id = cours.branche_cours
) AS branche_cours
FROM cours;
I would like to know, if it is possible get the row position from ID in SQLite. I have a method that return an ID when I click on listView item, but there is a gap in the IDs when I delete an item from table and the method is not effective in this case. I found this code below that returns the position row in order, but I don't know how to implement it programmatically in my class and move the cursor and to get CTN.
SELECT _id, PRODUCER,
(SELECT COUNT(*) FROM DATA B WHERE A._id >= B._id) AS CTN FROM DATA A
_id.........PRODUCER..............CTN
1............FIAT...........................1
2............FORD.........................2
3............RENAULT...................3
5............MWM..........................4
As I said, I can get the ID with a click on listView, my question is. if is possible any way to set this ID to return the position of the row. if possible show me with an example please.
thank you :)
it's working
public static long getRowFromId(Context context, int id) {
DataBase dataBase = new DataBase(context);
SQLiteDatabase conn = dataBase.getWritableDatabase();
String query = "SELECT COUNT (*) FROM " + Data.TABLE + " WHERE " + Data.ID + " <= " + id;
return conn.compileStatement(query).simpleQueryForLong();
}
I have three column, first id, second title and third body.
Like this
id title body
1 t1 b1
2 t2 b2
3 t3 b3
So, I want to get title and display in list with listview and if I click t2 title then display body of respective clickable title.
What i did.
DatabaseHelper.java
public Cursor retriveTitle(String [] title) {
Cursor c = null;
c = myDataBase.rawQuery(
"select id,title from book,", title);
return c;
}
Main.java
private void displayTitle() {
try {
myDataBase = (new DatabaseHelper(this)).getWritableDatabase();
} catch (IOException e) {
e.printStackTrace();
}
Cursor cursor = myDataBase.rawQuery("SELECT b.id, b.title FROM book b ", new String[] { "" });
String test=cursor.getString(cursor
.getColumnIndex("title"));
//How to display title of book in listview
}
getting this:
01-18 14:20:03.401: E/AndroidRuntime(6704): Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters.
I am using already database file, according to this blog post: Using your own SQLite database in Android applications
Try out
Cursor cursor = myDataBase.rawQuery("SELECT b.id, b.title FROM book b",null);
curosr.moveToFirst();
String test=cursor.getString(cursor
.getColumnIndex("title"));
I think your query should use a "where" statement
c = myDataBase.rawQuery("select id,title from book where title=?", title);
Of course you want to pass a certain number of arguments
c = myDataBase.rawQuery("select id,title from book where title in (?, ?, ?)", new String[]{title1, title2, title3});
But then if the number of title can vary, you will need to dynamically create a string with enough question marks. See this post
IN clause and placeholders
If you still get en error, maybe providing more log could help. Also if the lo say what line fails, tell which one it is. we can't see line numbers here
Good luck
Here's how it worked out for me. In an other class, I have created a method of List type and added the column id & the name of the item in the list from the sqlite database.
Here's the piece of code to retrieve the column id of the selected item.
public List<String> list;
adapt = new MyAdapter(this, R.layout.list_inner_view, list); //custom adapter
listTask.setAdapter(adapt);
listTask.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View v, int position, long l) {
Integer id = list.get(position).getId();
//position is the position of the item in the list.
}
});
Result: the item is at 3rd position in the list. Its database column_id (auto increment) value is 12 because I have deleted previous items. So the result you expect is 12, which is the value of variable id.
If you don't understand this fully, it may be because I haven't posted my entire code. But I'll help you out with your problem.
I have an activity which has two edit text fields: one for the title and the other for the story.
The entries made two text fields are saved in the database, also the database has a ROW_ID,TITLE_ID and STORY_ID. The entries are displayed in a list view.
When an item is long clicked, I get the row id corresponding to that item.
How should I get the TITLE_ID and STORY_ID from this?
Say, you have the corresponing row id of item which is long clicked in a variable rid. Then run the following query:
String q = "SELECT * FROM TABLE_NAME where(ROW_ID like '"+rid+"')";
Cursor c = db.rawQuery(q, null); // db is a object of SQLiteDatabase type
Then retrieve TITLE_ID and STORY_ID like:
if(c.getCount() == 0)
{
//No entry found
}
else {
c.moveToFirst();
do {
String titleid = c.getString(c.getColumnIndex("TITLE_ID"));
String storyid = c.getString(c.getColumnIndex("STORY_ID"));
} while (c.moveToNext());
c.close();
Then use them as you like :)
You could query the data base for the TITLE_ID and STORY_ID that correspond to the ROW_ID.
Post what code you have and we will be able to give more specific answers.
I created a ListView with a CursorAdapter, populated by a table of my db. After I added a ContextMenu that with a long click on the desired line of ListView pick info from my table.
The problem is that: I can not collect the information of that single line of ListView, each line gives me the same result. I think I do something wrong in query.
onCreate:
private void createTabRegistry(SQLiteDatabase db)
{
String sql = "CREATE TABLE {0} ({1} INTEGER PRIMARY KEY AUTOINCREMENT, {2} TEXT,{3} INTEGER,{4} TEXT,{5} TEXT,{6} TEXT, {7} TEXT);";
db.execSQL(MessageFormat.format(sql, TabRegistry.TABLE_NAME, TabRegistry._ID,TabRegistry.TYPE, TabRegistry.DATE, TabRegistry.STATUS, TabRegistry.NUMBER, TabRegistry.MESSAGE, TabRegistry.OTHER));
}
My query in db class:
public Cursor getRegistry2(long id) {
return (getReadableDatabase().query(
TabRegistry.TABLE_NAME,
TabRegistry.COLUMNS,
TabRegistry._ID + " = " + id,
null,
null,
null,
null,
null));
}
id of ContextMenu in my activity:
AdapterView.AdapterContextMenuInfo info= (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
id = getListAdapter().getItemId(info.position);
My cursor in the activity class:
Cursor c3 = databaseHelper.getRegistry2(id);
if (c3 != null) {
c3.moveToFirst();
}
dbnumber = (c3.getString(c3.getColumnIndex(TabRegistry.NUMBER)));
How do I assign to dbnumber string the value of the line of ListView that wonder?
EDIT code that works, but reset the view of listview....
Cursor c3 = (Cursor) getListAdapter().getItem(info.position);
startManagingCursor(c3);
aaaaa = c3.getString(c3.getColumnIndex(TabRegistry.NUMBER));
c3.close();
AdapterView.AdapterContextMenuInfo has a field called id that represents the row id from the database of that selected row. You'll want to query for that id and not the position field that represents the position in the list:
rowId = info.id;
and then query your database for the rowId to get that item's data.
Edit:
You'll probably don't want to use the solution you added. You close the cursor so no more data(that is why you have to restart the activity, as you probably query the database only in the onCreate method).
I told you the check if info.id returns different values when you use long press(to show the ContextMenu) different rows in the list, that means that the ContextMenu(probably) selects different row ids for different rows).
I don't know what causes your issue(if the delete works I would say there is something in the activity), so I made a small example of what you are trying to do so you can see this type of code:
http://pastebin.com/Yri03S0T