Skip to content Skip to sidebar Skip to footer

How To Retrieve Multiple Data When Clicked On Listview?

I want all edit text content that I have saved in SQL to be displayed on the edit bills activity when I click on the list item, but I am only able to retrieve the name and display

Solution 1:

There are two parts/questions.

First to retrieve the data, so that it can be displayed in the editbills activity, you can utilise the row's id that is passed to the activity in conjunction with the getRecordById method.

I'd suggest that adding a method to the editbills class will simplyfy matters.

privatevoidpopulateDisplay(int id) {

        Cursorcsr= dbAdapter.getRecordById(id);
        if (csr.moveToFirst()) {
            editText.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_NAME)));
            editText2.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_AMOUNT)));
            editText3.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_DUEDATE)));
        }
        csr.close();
    }

You could invoke the above method after retrieving the id from the Intent using :-

populateDisplay(selectedID);

To update based upon the content's of the EditTexts un-comment the updateRecord method in DBAdapter.java and the change :-

button.setOnClickListener(newView.OnClickListener() {
    @OverridepublicvoidonClick(View view) {
        Log.d("test", "adding");
        db.open();
        longid= db.insertRecord(editText.getText().toString(), editText2.getText().toString(), editText3.getText().toString());
        db.close();
        Toast.makeText(Editbills.this," Added", Toast.LENGTH_LONG).show();
        Intentq=newIntent(getApplicationContext(),bills.class);
        startActivity(q);

    }
});

to :-

    mButton.setOnClickListener(newView.OnClickListener() {
        @OverridepublicvoidonClick(View v) {
            if (dbAdapter.updateRecord(
                    selectedId,
                    editText.getText().toString(),
                    editText2.getText().toString(),
                    editText3.getText().toString())
                    ) {
                Log.d("TEST","Row successfully updated.");
                Toast.makeText(getApplicationContext(),"Row Updated.",Toast.LENGTH_LONG).show();
                populateDisplay(selectedId);
            } else {
                Toast.makeText(getApplicationContext(),"Row not Updated",Toast.LENGTH_LONG).show();
            }
            Intentq=newIntent(getApplicationContext(),bills.class);
            startActivity(q);
        }
    });

You will additionally have to add a line initialise the dbAdapter i.e. dbAdapter = new DBAdapter(this); i.d suggest adding this line immediately after the line setContentView(R.layout.activity_editbills);

  • Note the above code is in-principle and has not been thoroughly tested so it may contains errors.

Edit complete working example :-

The following code is basically an implementation of the above, except modified to utilise a Bill class. Rather than an ArrayList<String> as the source for the Adapter it has ArrayList<Bill>.

Thus all the data (id, name, amount and duedate) is available.

You should notice that I've overridden the toString method to return a String that combines the name, amount and duedate. The ArrayAdapter uses the object's toString method to populate the view.

Saying that the critical value is the rowid or an alias of rowid as this can be used to identify a row even if the other data is identical (as would happen when running this example more than once due to the addSomeData method). Hence, only the id is extracted and passed to the Editbills activity when an item in the list is long clicked (changed from just clicked to reduce the potential for accidental use).

Bill.java

publicclassBill {

    private long id;
    privateString name;
    privateString amount;
    privateString duedate;

    publicBill(long id, String name, String amount, String duedate) {
        this.id = id;
        this.name = name;
        this.amount = amount;
        this.duedate = duedate;
    }
    /*
            Note if this Constructor used then setId should be used
     */publicBill(String name, String amount, String duedate) {
        newBill(0,name,amount,duedate);
    }

    public long getId() {
        return id;
    }

    publicvoidsetId(long id) {
        this.id = id;
    }

    publicStringgetName() {
        return name;
    }

    publicvoidsetName(String name) {
        this.name = name;
    }

    publicStringgetAmount() {
        return amount;
    }

    publicvoidsetAmount(String amount) {
        this.amount = amount;
    }

    publicStringgetDuedate() {
        return duedate;
    }

    publicvoidsetDuedate(String duedate) {
        this.duedate = duedate;
    }

    /*
            As ArrayAdapter uses toString method change this
            to return all items
     */@OverridepublicStringtoString() {
        return name + " " + amount + " " + duedate;
    }
}

MainActivity.java

This is the equivalent to your Bills.java without a lot of the bloat such as FAB. :-

publicclassMainActivityextendsAppCompatActivity {

    publicstaticfinalStringID_INTENTEXTRA= DBAdapter.KEY_ROWID + "_INTENTEXTRA"; //<<<< ADDED

    DBAdapter mDBAdapter;
    Cursor mCsr;
    ListView mrecycleview;
    ArrayAdapter adapter; //<<<< NOT ListAdapter
    Context context; // ADDEDprivatestaticfinalStringTAG="assignments";

    ArrayList<Bill> mBillList = newArrayList<>();

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        mrecycleview = this.findViewById(R.id.mRecycleView);

        mDBAdapter = newDBAdapter(this);
        addSomeData();

        adapter = newArrayAdapter<Bill>(
                this,
                android.R.layout.simple_list_item_1,
                mBillList
        );
        mrecycleview.setAdapter(adapter);
        mrecycleview.setOnItemLongClickListener(newAdapterView.OnItemLongClickListener() {
            @OverridepublicbooleanonItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                Billb= (Bill) adapter.getItem(position);
                Intenti=newIntent(context,Editbills.class);
                i.putExtra(ID_INTENTEXTRA,b.getId()); //Get ID
                startActivity(i);
                returntrue;
            }
        });
        rebuildBillList();
    }

    //<<<< ADDED Method to refresh the ListView resumed@OverrideprotectedvoidonResume() {
        super.onResume();
        rebuildBillList();
    }

    // Add some data (note will add 2 rows each time it is run)privatevoidaddSomeData() {
        mDBAdapter.insertRecord("Bill1","2018-10-02","English");
        mDBAdapter.insertRecord("Bill2","2018-09-03","Mathematics");
        mDBAdapter.insertRecord("Bill3","2018-11-04", "Geography");
    }

    publicvoidrebuildBillList() {
        mBillList.clear();
        mCsr = mDBAdapter.getAllAsCursor();
        while (mCsr.moveToNext()) {
            mBillList.add(newBill(
                            mCsr.getLong(mCsr.getColumnIndex(DBAdapter.KEY_ROWID)),
                            mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_NAME)),
                            mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_AMOUNT)),
                            mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_DUEDATE))
                    )
            );
        }
        adapter.notifyDataSetChanged();
    }
}
  • Note the above adds 3 rows each time it is run.

Editbills.java

publicclassEditbillsextendsAppCompatActivity {
    Button button;
    privatestaticfinalStringTag="assignments";
    DBAdapterdb=newDBAdapter(this);
    private String selectedName;
    privatelong selectedID;
    DBAdapter dbAdapter;
    private EditText editText,editText2,editText3;
    Context context;
    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editbills);
        context = this;
        dbAdapter = newDBAdapter(this); //<<<< ADDED
        button=(Button)findViewById(R.id.button);
        editText =(EditText)findViewById(R.id.edittext);
        editText2=(EditText)findViewById(R.id.edittext2);
        editText3 =(EditText)findViewById(R.id.edittext3);
        //get the intent extra from the ListDataActivityIntentreceivedIntent= getIntent();

        //now get the itemID we passed as an extra
        selectedID = receivedIntent.getLongExtra(MainActivity.ID_INTENTEXTRA,-1L); //NOTE: -1 is just the default value
        populateDisplay(selectedID);

        //now get the name we passed as an extra//selectedName = receivedIntent.getStringExtra("name");//set the text to show the current selected name//editText.setText(selectedName); <<<< commented out
        button.setOnClickListener(newView.OnClickListener() {
            @OverridepublicvoidonClick(View view) {

                /*
                Log.d("test", "adding");
                db.open();
                long id = db.insertRecord(editText.getText().toString(), editText2.getText().toString(), editText3.getText().toString());
                db.close();
                Toast.makeText(Editbills.this," Added", Toast.LENGTH_LONG).show();
                *//*
                * <<<< Not the way as it ends/closes the existing activity
                Intent q = new Intent(getApplicationContext(),MainActivity.class);
                startActivity(q);
                */Stringtoast="Updated.";
                if (dbAdapter.updateRecord(selectedID,
                        editText.getText().toString(),
                        editText2.getText().toString(),
                        editText3.getText().toString())) {
                } else {
                    toast = "Not Updated.";
                }
                Toast.makeText(context,toast,Toast.LENGTH_LONG).show();
                finish(); //<<<< ends/closes this activity and returns to calling activity
            }
        });
    }

    privatevoidpopulateDisplay(long id) {
        Cursorcsr= dbAdapter.getRecordById(id);
        if (csr.moveToFirst()) {
            editText.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_NAME)));
            editText2.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_AMOUNT)));
            editText3.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_DUEDATE)));
        }
        csr.close();
    }
}
  • Basically as per the original answer.

DBAdapter.java

publicclassDBAdapter {
    publicstaticfinalStringKEY_ROWID="id";
    publicstaticfinalStringKEY_NAME="name";
    publicstaticfinalStringKEY_AMOUNT="amount";
    publicstaticfinalStringKEY_DUEDATE="duedate";
    privatestaticfinalStringTAG="DBAdapter";

    privatestaticfinalStringDATABASE_NAME="billsdb";
    privatestaticfinalStringDATABASE_TABLE="bills";
    privatestaticfinalintDATABASE_VERSION=2;


    // Replaces DATABASE_CREATE using the one source definitionprivatestaticfinalStringTABLE_CREATE="CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE + "(" +
                    KEY_ROWID + " INTEGER PRIMARY KEY, " + // AUTOINCREMENT NOT REQD
                    KEY_NAME + " DATE NOT NULL, " +
                    KEY_AMOUNT + " VARCHAR ," +
                    KEY_DUEDATE + " DATE " +
                    ")";

    private Context context;

    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    publicDBAdapter(Context ctx)
    {
        this.context = ctx;
        DBHelper = newDatabaseHelper(context);
    }

    privatestaticclassDatabaseHelperextendsSQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @OverridepublicvoidonCreate(SQLiteDatabase db)
        {
            db.execSQL(TABLE_CREATE); // NO need to encapsulate in try clause
        }

        @OverridepublicvoidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS contacts"); //????????
            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }

    //---opens the database--- NOT NEEDEDpublic DBAdapter open()throws SQLException
    {
        db = DBHelper.getWritableDatabase();
        returnthis;
    }

    //---closes the database--- NOT NEEDEDpublicvoidclose()
    {
        DBHelper.close();
    }

    //---insert a record into the database---publiclonginsertRecord(String name, String amount, String duedate)
    {
        ContentValuesinitialValues=newContentValues();
        initialValues.put(KEY_NAME, name);
        initialValues.put(KEY_AMOUNT, amount);
        initialValues.put(KEY_DUEDATE, duedate);
        return DBHelper.getWritableDatabase().insert(DATABASE_TABLE,
                null,
                initialValues
        );
    }

    //---deletes a particular record---publicbooleandeleteContact(long rowId)
    {
        return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }

    //---retrieves all the records--- SEE FOLLOWING METHODpublic Cursor getAllRecords()
    {SQLiteDatabasedb= DBHelper.getWritableDatabase();
        Stringquery="SELECT * FROM " + DATABASE_TABLE;
        Cursordata= db.rawQuery(query,null);
        return data;
    }


    //As per getAllRecords but using query convenience methodpublic Cursor getAllAsCursor() {
        return DBHelper.getWritableDatabase().query(
                DATABASE_TABLE,
                null,null,null,null,null,null
        );
    }
    public Cursor getItemID(String name) {
        SQLiteDatabasedb= DBHelper.getWritableDatabase();
        Stringquery="SELECT " + KEY_ROWID + " FROM " + DATABASE_TABLE +
                " WHERE " + KEY_NAME + " = '" + name + "'";
        Cursordata= db.rawQuery(query, null);
        return data;
    }

    // Retrieve a row (single) according to idpublic Cursor getRecordById(long id) {
        return DBHelper.getWritableDatabase().query(
                DATABASE_TABLE,
                null,
                KEY_ROWID + "=?",
                newString[]{String.valueOf(id)},
                null,null,null
        );
    }

    //---updates a record---publicbooleanupdateRecord(long rowId, String name, String amount, String duedate) {
        ContentValuesargs=newContentValues();
        args.put(KEY_NAME, name);
        args.put(KEY_AMOUNT, amount);
        args.put(KEY_DUEDATE, duedate);
        Stringwhereclause= KEY_ROWID + "=?";
        String[] whereargs = newString[]{String.valueOf(rowId)};
        return DBHelper.getWritableDatabase().update(DATABASE_TABLE,
            args,
            whereclause,
            whereargs
        ) > 0;
    }
}
  • Basically as was except that upDateRecord has been un-commented, again as per the original answer.

Results

1st Run - MainActivity (Bills) :-

enter image description here

Long Click Bill2 (note changed from Click as Long Click is less prone to accidental use)

enter image description here

Change data (Update button not clicked)

enter image description here

Update Button Clicked (Toast was Updated.)

enter image description here

  • Note use of finish() to return to the invoking activity and then the use of onResume to refresh the list according to the updated data (possibly your next question).
    • using startActivity will simply result in issues.
  • Note Values are date and course rather then amount and duedate because I didn't change the values in the addSomeData method (easily done).
    • the actual data itself is irrelevant to the process.

Post a Comment for "How To Retrieve Multiple Data When Clicked On Listview?"