2

I'm using SQLite in my app. I have a listView which is populated with values from the database.

When I click on an item from the listview, I go to another page, and I would like ( with an intent), to transfer the ID FROM THE DATABASE. The problem is that I'm only transfering the ID from the position of my listView, which is wrong. For example, let's say I have :

ID Name 1 David 2 Joseph

My listView will display both names. But if I delete David, the ID i'm getting when i click in Joseph is 1 and not 2 . And that's the problem !

So : I want to retrieve the ID from my database and not from my listView when I click on an item

Here's my method in my helper : UPDATED !

   public Cursor getAllCours()
{
    String Query = ("select ID as _id, nom from " + TABLE_COURS);
    Open();
    Cursor cursor = db.rawQuery(Query, null);
       return cursor;
}

And how I display it in my Activity :

  Cursor cursor = dbhelper.getAllCours();
    String[] from = { "nom" }; int[] to = { android.R.id.text1 };
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, from, to, 0);
    lv.setAdapter(adapter);

And finally, my listviewClickListener :

  lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            //I THINK THE ERROR IS HERE !
            long itemid= lv.getItemIdAtPosition(i);
            int id= (int)itemid;
            String a =lv.getItemAtPosition(i).toString();
            Intent b = new Intent(AffichageCours.this,AffichageNotes.class);
            Bundle args = new Bundle();
            args.putString("nom_cours",a);
            args.putInt("id",id);
            b.putExtras(args);
            startActivity(b);
        }

    });
}

My TABLE_COURS columns:

 private static final String TABLE_COURS = "cours";
private static final String COLONNE_IDCOURS = "ID";
private static final String COLONNE_COURS = "nom";

 private static final String CREATE_COURS ="CREATE TABLE cours " +
        "("+COLONNE_IDCOURS+" INTEGER PRIMARY KEY AUTOINCREMENT , "
        +COLONNE_COURS+" TEXT NOT NULL)";

How i delete with my Context Menu :

 @Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    switch(item.getItemId())
    {
        case R.id.supprimer:
            dbhelper.deleteCours(lv.getItemAtPosition(info.position).toString());
            adapter.remove(adapter.getItem(info.position)); //the error is here..
            adapter.notifyDataSetChanged();
            return true;

Thank you guys !

David
  • 221
  • 3
  • 13
  • you dont need `getItemIdAtPosition`: see the last parameter passed to `onItemClick` method, of course you need to use a right adapter that supports your db IDs like `SimpleCursorAdapter`, not `ArrayAdapter` – pskink Apr 17 '17 at 08:50
  • 1
    Ok, but how do I do it using a SimpleCursorAdapter ? – David Apr 17 '17 at 08:55
  • as simple as this: https://thinkandroid.wordpress.com/2010/01/09/simplecursoradapters-and-listviews/, it uses `this.setListAdapter(mAdapter);`, you would simply call `lv.setAdapter(...);` instead – pskink Apr 17 '17 at 08:59
  • Don't you have an example for my problem ? Like the code ? It's a bit complicated the link you sent me.. – David Apr 17 '17 at 09:09
  • you have 6 lines of code, what is unclear in those? what columns do you have in TABLE_COURS? – pskink Apr 17 '17 at 09:30
  • Cursor cursor = db.rawQuery("select ID as _id, Name from " + TABLE_COURS, null); String[] from = { "Name" }; int[] to = { android.R.id.text1 }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, from, to, 0); lv.setAdapter(adapter); – pskink Apr 17 '17 at 09:37
  • err, replace `Name` with `nom` since this is the name of a column in your db – pskink Apr 17 '17 at 09:55
  • And where do I write that code ? What does android.R.id.text1 means ? – David Apr 17 '17 at 10:06
  • no, this is the code you should add in your activity, so remove `getAllCours` method and the whole code in your activity replace with those 5 lines of the code i sent you – pskink Apr 17 '17 at 10:09
  • I can't even do the rawQuery... – David Apr 17 '17 at 10:13
  • why cant you? whats wrong with rawQuery? – pskink Apr 17 '17 at 10:14
  • it doesn't recognize rawQuery.. do i need to extend my class or something ? – David Apr 17 '17 at 10:15
  • I think the problem is because I'm not writting that code in my databasehelper, so it does not recognize raeQuery or table_cours as well... – David Apr 17 '17 at 10:17
  • Yes but that code is in my DatabaseHelper whcich extends SQLiteOpenHelper – David Apr 17 '17 at 10:18
  • so add `Cursor getAllCours()` method in your helper and just return the `Cursor` – pskink Apr 17 '17 at 10:19
  • And I write the code you sent me ? – David Apr 17 '17 at 10:19
  • and instead of `Cursor cursor = db.rawQuery("select ID as _id, Name from " + TABLE_COURS, null);` call `Cursor cursor = dbhelper.getAllCours();` – pskink Apr 17 '17 at 10:21
  • Do i have to change something in my method of my DatabaseHelper ? – David Apr 17 '17 at 10:25
  • Ii'm gettint an error here (incompatible types) **Cursor cursor = dbhelper.getAllCours();** String[] from = { "nom" }; int[] to = { android.R.id.text1 }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, from, to, 0); lv.setAdapter(adapter); registerForContextMenu(lv); – David Apr 17 '17 at 10:25
  • you have to add `Cursor getAllCours()` method returning just the `Cursor`, not `List`, simply return `db.rawQuery("select ID as _id, nom from " + TABLE_COURS, null)` – pskink Apr 17 '17 at 10:26
  • check my code please, i updated it. Iis it correct like that ? And my listViewClickListener, I have to change it as well, don't I ? – David Apr 17 '17 at 10:35
  • in `getAllCours` remove everything related to `coursListe` (all you need is just `Cursor`, nothing more) and in `onItemClick` method see now the last parameter – pskink Apr 17 '17 at 10:40
  • the last parameter you mean long l ? – David Apr 17 '17 at 10:47
  • https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html – pskink Apr 17 '17 at 11:00
  • Ok, but how do i get it , with which method i get the ID ? – David Apr 17 '17 at 11:07
  • the last parameter is an ID, that last parameter passed to `onItemClick` method – pskink Apr 17 '17 at 11:07
  • yes, but how do I get it from my listView ? – David Apr 17 '17 at 11:08
  • did you try to `Log.d` the last parameter? `Log.d("SOME_TAG", "onItemClick id: " + l);` – pskink Apr 17 '17 at 11:09
  • Yes, it gives me the ID, but now I'm not able to delete a row from my ListView. I'll edit my question and post the code of my ContextMenu – David Apr 17 '17 at 11:22

3 Answers3

0

I think the problem is that you are asking for the Id of the row in the ListView not the actual data that row is holding up. In the onItemClick method change this:

long itemid= lv.getItemIdAtPosition(i);

For this:

String courId = adapter.getItem(i);

The key here is to try to get the data from the ArrayAdapter not directly from the ListView.

mikehc
  • 999
  • 8
  • 22
  • `"not directly from the ListView"` what do you mean? what is data taken from the `ListView`? – pskink Apr 17 '17 at 09:04
  • How does the ListView has notion of the ID that you want? What is exactly the data you are putting in the ArrayAdapter? – mikehc Apr 17 '17 at 09:18
  • My listView contains the collumn NAME. But when I click i want to pass the collumn ID from the name chosen. But ID FROM DATABASE – David Apr 17 '17 at 09:23
  • If you are not passing the ID to the ListView or the adapter in any way there's no way to obtain such ID unless you somehow sync the data by position between what you show in the list and the in memory array/list of data. I recommend you to follow the approach by @M. Ashish. Dump your sql data into POJOs, create a custom adapter to show the data and get the original data by querying the adapter as I say in the answer. – mikehc Apr 17 '17 at 19:49
  • `"there's no way to obtain such ID"`, and this is why OP should use `CursorAdapter`, the docs say: *"The Cursor must include a column named "_id" or this class will not work"*, this `_id` column is used in `long CursorAdapter#getItemId(int position)` method implementation - see his edited code and how simple it is right now by just using `SimpleCursorAdapter` – pskink Apr 18 '17 at 09:33
0

You should have use Java Objects so it will be easy for you.

Suppost you have stored Contacts in dataBase(contains fields: Name, Mobile and Address). So create a POJO for that:

class Contacts{
    private String name;
    private String mobile;
    private String address;

    //write getters and setters
}

Then, whenever you are accessing database fetch all contacts you want to show and store in ArrayList<Contacts> mContactList;

And then pass this list in your ListView's adapter to show data in listView.

CustomAdapter adapter = new CustomAdapter(context, layoutResource, mContactList);

Then you can retrieve the object on clicking a particular list item on the basis of position;

lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
           Contacts contact = mContactList.get(i);
           // now you can do whatever you want;
        }

    });
Ashish M
  • 763
  • 6
  • 13
  • `"You should have use Java Objects"`, no, OP's data model is a `Cursor`, so he should use some kind of `CursorAdapter`, not `ArrayAdapter` – pskink Apr 17 '17 at 10:01
  • Yes, he can also do that, But main point is accessing database frequently for small things is not a good idea. – Ashish M Apr 17 '17 at 10:10
  • this is what sqlitedb is for, there is no need to replicate its data in ram – pskink Apr 17 '17 at 10:13
  • `CursorAdapter` is deprecated and not recommended for usage by Google. I agree with the approach suggested by @M.Ashish. – mikehc Apr 17 '17 at 19:45
  • @mikehc `"CursorAdapter is deprecated and not recommended for usage by Google "`, since when? do you mean that one `CursorAdapter` constructor which is deprecated (but two others are recommended)? – pskink Apr 19 '17 at 06:35
0

Since you are not using a custom adapter, why dont you try this inside onItemClickListener

String idThatYouWant = listeCours.get(i).getId();
Nirup Iyer
  • 1,215
  • 2
  • 14
  • 20