Drew Szurko
Drew Szurko

Reputation: 1621

OnClickListener _id from ListView does not match the correct row _id in SQLite

I'm new to Android. I have a SQLite backend where each row is unique (think of a person). I then display this data in a ListView for each person. When the ListView item is clicked, it will go to a subview, which has all the information for the specific parent ListView item. The problem I'm encountering is when I set the OnItemClickListener for the ListView, the int position and long id start at 0. When I pass either of those through an intent for the first item in a list view, I get an "android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0". It's because my row id in SQlite starts at 1, and the int position or long id start at 0. What is the best way to fix this? I've read you can add 1 to the postion or id, but if a user sorts their ListView a different way, won't it pass the wrong ID to the database? Thank you

MainActivity

   final ArrayList<Person> objects = db.getAllPersons();
        final CustomAdapter customAdapter = new CustomAdapter(this, objects);
        customAdapter.notifyDataSetChanged();
        final ListView listView = (ListView) findViewById(R.id.content_list);
        listView.setAdapter(customAdapter);

//Listen for ListView item click

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {


                Intent intent = new Intent(MainActivity.this, PersonProfile.class);
                intent.putExtra("id", id;
                startActivity(intent);

            }
        });

PersonActivity

    public class PersonProfile extends AppCompatActivity {
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.person_profile);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

//Get unique ID from MainActivity
            int personID = getIntent().getExtras().getInt("id");

//Fetch individual from the database based on unique ID
            DatabaseHandler db = new DatabaseHandler(this);
            db.getReadableDatabase();
            Person person = db.getPerson(personID);
            db.close();

//Set TextView budget using unique ID
            String budget = String.valueOf(person.getBudget());
            TextView textViewBudget = (TextView) findViewById(R.id.person_budget);
            textViewBudget.setText(budget);

        }    

Upvotes: 0

Views: 233

Answers (2)

Drew Szurko
Drew Szurko

Reputation: 1621

I implemented the SimpleCursorAdapter as recommend by pskink. It required some other code changes, but I agree this is the simplest way to go.

Here's what my classes looked like after

MainActivity

DatabaseHandler db = new DatabaseHandler(this);
    db.getWritableDatabase();
    Cursor cur = db.getAllPersons();
    String[] columns = new String[]{"name", "budget"};
    int[] to = new int[]{R.id.name, R.id.budget};

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.row_layout, cur, columns, to);
    final ListView listView = (ListView) findViewById(R.id.content_list);
    listView.setAdapter(adapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            Intent intent = new Intent(MainActivity.this, PersonProfile.class);
            intent.putExtra("id", id);
            startActivity(intent);

        }
    });

PersonActivity

public class PersonProfile extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.person_profile);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    Long intent = getIntent().getExtras().getLong("id");
    DatabaseHandler db = new DatabaseHandler(this);
    db.getReadableDatabase();

    String budgetSet = db.getPerson(intent);


    TextView textViewBudget = (TextView) findViewById(R.id.person_budget);

    textViewBudget.setText(budgetSet);

    db.close();

}

DatabaseHandler

Cursor getAllPersons() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.query(TABLE_PERSON, new String[]{KEY_ID,
            KEY_NAME, KEY_BUDGET}, null, null, null, null, null);

    return cursor;
}

Upvotes: 1

Tiago Oliveira
Tiago Oliveira

Reputation: 1602

If your listview has a starting value of 0 and your db a starting value of 1, just like you said you can just add 1 to the id, but if the user shorts the listview diferent you will have a problem since the user 4 may have the index of 1 in the listview.

My sugestion is to add the database id to the Person class when you click on the item you can call for exemple

objects.get(listiewClickedPosition).getUserID();

If im not missing something this will retrive the correct index, even if the listview is shorted diferently

If you want to short it diferently you change the order of objects after that you call notifyDataSetChanged()

Upvotes: 0

Related Questions