0

I'm building an app that uses SQLite for persistence and also incorporates a CursorAdapter. I am able to add items into the ListView and the SQLite table and can view those items on app restart. I'm also able to delete items and view the changes once I restart again. I've added an edit function with an onClickListener where once I click on an item, it is supposed to take me to the edit screen where I can edit that specific item. This is what I have:

Mainactivity.java

public class MainActivity extends AppCompatActivity {
    DatabaseHelper databaseHelper;
    private final int REQUEST_CODE = 10;
    ArrayList <String> toDoItems;
    ArrayAdapter<String> adapter;
    SimpleCursorAdapter altAdapter;
    Cursor itemListCursor;
    ListView listItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listItems = (ListView) findViewById(R.id.listViewItems);
        toDoItems = new ArrayList<>();
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, toDoItems);
        databaseHelper = new DatabaseHelper(this);
        getItemListAsCursor();
        altAdapter = new SimpleCursorAdapter(
                this,
                android.R.layout.simple_list_item_1,
                itemListCursor,
                new String[]{TO_DO},
                new int[]{android.R.id.text1},
                0);

        listItems.setAdapter(altAdapter);

        listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
                itemDeleteFromDatabase(id);
                getItemListAsCursor();
                altAdapter.swapCursor(itemListCursor);
                return true;
            }
        });

        listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
                Intent intent = new Intent(MainActivity.this, EditItemActivity.class);
                intent.putExtra("itemName", toDoItems.get(pos));
                intent.putExtra("itemPos", id);
                startActivityForResult(intent, REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        itemListCursor.close();
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
            String item = data.getStringExtra("item");
            int itemPosition = Integer.parseInt(data.getStringExtra("itemPos"));
            toDoItems.add(itemPosition, item);
            databaseHelper.insertData(item);
            toDoItems.remove(itemPosition + 1);
            itemDeleteFromDatabase((long) (itemPosition + 1));
            adapter.notifyDataSetChanged();
        }
    }

    public void addItem(View v) {
        EditText newItem = (EditText) findViewById(R.id.itemInputEditText);

        if (newItem.getText().length() == 0) {
            Toast.makeText(this, "You need to enter a to do.", Toast.LENGTH_SHORT).show();
        } else {
            String item = newItem.getText().toString();
            databaseHelper.insertData(item);
            getItemListAsCursor();
            altAdapter.swapCursor(itemListCursor);
            adapter.notifyDataSetChanged();
            newItem.setText("");
        }
    }

    public  void getToDos(){
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        Cursor cursor = database.rawQuery("select * from student",null);
        if (cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) {
                String name = cursor.getString(cursor.getColumnIndex("todo"));
                adapter.add(name);
                adapter.notifyDataSetChanged();
                cursor.moveToNext();
            }
        }
    }

    public void getItemListAsCursor() {
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        itemListCursor = database.query(TABLE_NAME,null,null,null,null,null,null);
    }

    public boolean itemDeleteFromDatabase(Long id) {
        SQLiteDatabase database = databaseHelper.getWritableDatabase();
        boolean databaseDelete = database.delete(TABLE_NAME, ID + "=?", new String[]{Long.toString(id)}) > 0;
        return databaseDelete;
    }
}

EditItemActivity.java

public class EditItemActivity extends AppCompatActivity {
    EditText editToDo;
    Long itemPos;
    Button saveChanges;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_item);

        editToDo = (EditText) findViewById(R.id.edit_todo_item);
        saveChanges = (Button)findViewById(R.id.save_changes);

        String itemName = getIntent().getStringExtra("itemName");
        editToDo.setText(itemName);
        itemPos = getIntent().getLongExtra("itemPos", 0);

        saveChanges.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onSubmit();
            }
        });
    }

    public void onSubmit() {
        Intent item = new Intent();
        item.putExtra("itemName", editToDo.getText().toString());
        item.putExtra("itemPos", itemPos);
        setResult(RESULT_OK, item);
        finish();
    }
}

but when I click on an item, I get the infamous indexOutOfBounds exception. This is the stacktrace:

FATAL EXCEPTION: main
                                                                         Process: ca.ozbek.preworktodoapp, PID: 13721
                                                                         java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
                                                                             at java.util.ArrayList.get(ArrayList.java:411)
                                                                             at ca.ozbek.preworktodoapp.MainActivity$2.onItemClick(MainActivity.java:65)

I know that because I am using a CursorAdapter that I should be using id in my intent.putExtra("item", toDoItems.get(pos)); and intent.putExtra("itemPos", String.valueOf(pos)); lines of code instead of pos but I can't do that because id is a long value.

Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78
  • Why is it that you believe you can't use a long? You can pass long's via intents and retrieve them e.g. In the calling activity you could have `intent.putExtra("itemid",id);` along with `itemid = getintent().getLongExtra("itemid",0);` in the called activity. Checking `itemid` for 0 which would indicate no `id` passed/retrieved (although this would likely not happen). – MikeT Sep 12 '17 at 20:33
  • But when I do that, the edit activity only has the id of the item. – Onur-Andros Ozbek Sep 15 '17 at 13:59
  • I'll post the full java codes. – Onur-Andros Ozbek Sep 15 '17 at 14:02
  • You have three options, use the id to then query the data or to pass the additional data via the intent i.e. use multiple intentPutExtra's with corresponding get????Extra's or you can also pass objects but they need to be either serializable or parcelable. [How do I pass an object from one activity to another on Android?](https://stackoverflow.com/questions/2906925/how-do-i-pass-an-object-from-one-activity-to-another-on-android) – MikeT Sep 15 '17 at 20:04

1 Answers1

1

If you create a DBHelper Class life with be very easy to handle all CRUD functions So your list has a position and your record has an ID when you click the btnDelete in what ever Activity you are on use code like this

// Calls the Method deleteDBRow in DatabaseHelper
// which acts on the TABLE_INFO to remove a record by getting the record ID
            helper.deleteDBRow(String.valueOf(dbList.get(position).getID()));
            ListActivity.removeListRow(position);

// Code line above calls Method in ListActivity to notify recycler view of changes // NOTICE the List keeps items by position not ID <== READ

OK now over in your DBHelper Class you implement this method code below

/* Delete a record from database table named "TABLE_INFO" */
/* based on the selected records id in Col_ID*/
public void deleteDBRow(String rowid){

    db = this.getWritableDatabase();
    db.delete(TABLE_INFO, Col_ID + " = ?", new String[] { rowid });
    db.close();
    return;
}
Vector
  • 3,066
  • 5
  • 27
  • 54