I'm trying to get data from column ITEMS in my Database to appear in the Items listView when you click the add button. At the moment when you click the add button it just saves a item in a column of the database. I would appreciate an answer!
The main Java class (New_Recipe)
public class New_Recipe extends AppCompatActivity {
Button add,done,display;
EditText Recipe_Name,Recipe_Item,Recipe_Steps;
String search;
WebView webView;
DatabaseHelper databaseHelper;
ListView Items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new__recipe);
databaseHelper = new DatabaseHelper(this);
setTitle("New Recipe");
add = (Button) findViewById(R.id.button2);
done = (Button) findViewById(R.id.button);
Recipe_Name = (EditText) findViewById(R.id.editText);
Recipe_Item = (EditText) findViewById(R.id.editText2);
Recipe_Steps = (EditText) findViewById(R.id.editText3);
webView = (WebView) findViewById(R.id.webView);
display = (Button) findViewById(R.id.button3);
Items = (ListView) findViewById(R.id.listView);
AddData();
viewAll();
}
public void AddData() {
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean inserted = databaseHelper.insertData1(Recipe_Name.getText().toString(),
Recipe_Steps.getText().toString());
if (inserted == true)
Log.d("Database", "Data successfully inserted!");
else Log.d("Database","Data did not insert!");
}
});
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean inserted = databaseHelper.insertData2(Recipe_Item.getText().toString());
if (inserted == true)
Log.d("Database", "Data successfully inserted!");
else Log.d("Database","Data did not insert!");
}
});
}
public void viewAll() {
display.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor res = databaseHelper.getAllData();
if (res.getCount() == 0) {
showMessage("Error","No Data found!");
return;
}
StringBuffer stringBuffer = new StringBuffer();
while (res.moveToNext()) {
stringBuffer.append("Names :"+res.getString(0)+"\n");
stringBuffer.append("Items :"+res.getString(1)+"\n");
stringBuffer.append("Steps :"+res.getString(2)+"\n\n");
}
showMessage("Success!",stringBuffer.toString());
}
});
}
public void showMessage(String title,String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setTitle(title);
builder.setMessage(message);
builder.show();
}
public void onSearch(View v) {
search = "Recipes";
webView.loadUrl("https://www.google.com/search?q="+search);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new__recipe, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The Database Java class (DatabaseHelper)
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Recipes.db";
public static final String TABLE_NAME = " Recipe_Table";
public static final String COL1 = "NAME";
public static final String COL2 = "ITEMS";
public static final String COL3 = "STEPS";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
Log.d("Database", "Database should be made!");
}
#Override
public void onCreate (SQLiteDatabase db){
db.execSQL("create table " + TABLE_NAME + " (NAME TEXT PRIMARY KEY,ITEMS TEXT,STEPS TEXT)");
Log.d("Database", "Database should be made!, Again");
}
#Override
public void onUpgrade (SQLiteDatabase db,int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);
Log.d("Database", "Table exists");
onCreate(db);
}
public boolean insertData1(String name,String steps) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1, name);
contentValues.put(COL3, steps);
long result = db.insert(TABLE_NAME,null,contentValues);
if (result == -1)
return false;
else
return true;
}
public boolean insertData2(String items) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, items);
long result = db.insert(TABLE_NAME,null,contentValues);
if (result == -1)
return false;
else
return true;
}
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
return res;
}
public Cursor getItemData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select"+COL2+"from"+TABLE_NAME,null);
return res;
}
}
The real Android way to do this would be to use a combination of ContentProvider and CursorAdapter.
Android already has a way to take a Cursor from a query and put the data in a ListView: The CursorAdapter class. You just override getView() to create the item view for your list.
Here's what a custom ContentProvider will get you: When you create a content provider URI and query it to get a Cursor, a DataObserver is set up, so that when you insert/delete/update data through the ContentProvider using that URI, the Cursor will get a notification that the data has changed and will re-query the data. When that Cursor has been set on a CursorAdapter, the adapter will also see that the cursor data has changed and call notifyDataSetChanged().
So the net result is that when you add a record, your ListView is automatically refreshed with current data.
For an introduction to Content Providers, refer to this article: Content Providers | Android Developers.
You need to create an adapter that the list view can draw its data from. You will pass the data from your getAllData() call to the adapter, which the list view will then display.
If you haven't already, you can create a custom class which extends base adapter, implement the methods correctly, then all you have to worry about it the data.
First off, I always like to build a class that can store my data retrieved from the database. Something simple, like:
public class ItemObject {
// Instance variables.
private String mName, mItem, mStep;
// Constructor.
public ItemObject(String name, String item, String step) {
mName = name;
mItem = item;
mStep = step;
}
// Create getters for each item.
public String getName() { /*...*/ }
public String getItem() { /*...*/ }
public String getStep() { /*...*/ }
}
Now you have an object that can store the items retrieved from the database table. In your while loop after calling getAllData() you create your ItemObject there.
For example:
List<ItemObject> itemObjectList = new ArrayList<>();
while (res.moveToNext()) {
// Extract values from the cursor.
String name = res.getString(0);
String item = res.getString(1);
String step = res.getString(2);
// Create the ItemObject and add it to the list.
ItemObject item = new ItemObject(name, item, step);
// Add it to the list.
itemObjectList.add(item);
}
Now, you'll have a list of items you can pass directly to your adapter.
public class ItemsListAdapter extends BaseAdapter {
// Instance variables.
private Context mContext;
private List<ItemObject> mItemObjectList;
// Constructor.
public ItemsListAdapter(Context context, List<itemObjectList> itemObjectList) {
mContext = context;
mItemObjectList = itemObjectList;
}
#Override
public int getCount() {
return mItemObjectList.size();
}
#Override
public Object getItem(int position) {
return mItemObjectList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Inflate your layout for each row here. I wont include list view
// optimization here, as you should look it up, its documentation
// is readily available.
LayoutInflater inflater = LayoutInflater.from(mContext);
// Inflate the layout.
View layout = inflater.inflate(R.layout.<your_list_view_row_layout>, null);
// Reference the views inside the layout that will display each value. (Name, Item, Step);
TextView nameView = (TextView) layout.findViewById(R.id.<your_text_view_id>);
// Do this for each view.
// Now retrieve your data from the array list.
ItemObject item = (ItemObject) getItem(position);
// Now you have your item and the 3 values associated with it.
// Set the values in the UI.
nameView.setText(item.getName());
// Return the view.
return layout;
}
// Use this method to modify the data in the list view.
// It's an ArrayList so simply add or remove elements, clear it, etc.
public List<ItemObject> getAdapterList() {
return mItemObjectList;
}
}
To update the items in the list view, call getAdapterList() and modify the items in the ArrayList that is returned. After modification, you must invalidate the list by calling notifyDataSetChanged() on the adapter itself.
Hope this points you in the right direction.
Related
When I tap the button for inserting the data it says it is successful, but when I check my listview there is no data. But If I add again, then only the data is inserted.
Why is the data only inserted on the second time?
Thanks in advance! :D
This is my Database Helper class:
public static final String DB_NAME = "CartDB";
public static final String TABLE_NAME = "Orders";
public static final String COLUMN_ID = "id";
public static final String NAME ="name";
public static final String SIZE ="size";
public static final String QUANTITY ="quantity";
private static final int DB_VERSION = 1;
public cartDatabaseHelper(Context context)
{
super(context,DB_NAME,null,DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE " + TABLE_NAME
+ "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ NAME + " VARCHAR, "
+ SIZE + " VARCHAR, "
+ QUANTITY + " VARCHAR);";
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXIST Orders";
db.execSQL(sql);
onCreate(db);
}
public boolean addPerson(String name, String size, String quantity){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(NAME,name);
contentValues.put(SIZE,size);
contentValues.put(QUANTITY,quantity);
long result = db.insert(TABLE_NAME,null ,contentValues);
if(result == -1)
return false;
else
return true;
}
public Cursor getListContents(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return data;
}
And this is my MainActivity class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alcohol_list);
db = new cartDatabaseHelper(this);
GridAlcoholAdapter adapter = new GridAlcoholAdapter(alcoholType.this, images, names);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = names.get(position);
String size = textSize.getText().toString().trim();
String quantityNumber = textQuantityNumber.getText().toString().trim();
String bottleCase = textBottleCase.getText().toString().trim();
String bottleCaseQuantity = textQuantity.getText().toString().trim();
textQuantity.setText(quantityNumber + " " + bottleCase);
db.addPerson(name,size,bottleCaseQuantity);
dialog.dismiss();
}
});
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
case R.id.action_cart:
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.cartdialog);
dialog.setTitle("YOUR CART");
listView = (ListView) dialog.findViewById(R.id.listView);
final ListCartAdapter adapter = new ListCartAdapter(alcoholType.this, orderName, orderSize, orderQuantity);
listView.setAdapter(adapter);
Cursor data = db.getListContents();
data.moveToFirst();
while (data.moveToNext()) {
orderName.add(data.getString(1));
orderSize.add(data.getString(2));
orderQuantity.add(data.getString(3));
}
data.close();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
orderName.clear();
orderSize.clear();
orderQuantity.clear();
}
});
dialog.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
This is my Adapter Class:
public class ListCartAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> orderName;
private ArrayList<String> orderSize;
private ArrayList<String> orderQuantity;
public ListCartAdapter(Context context, ArrayList<String> orderName, ArrayList<String> orderSize, ArrayList<String> orderQuantity){
// public ListCartAdapter(Context context, ArrayList<String> orderName){
this.context = context;
this.orderName = orderName;
this.orderSize = orderSize;
this.orderQuantity = orderQuantity;
}
#Override
public int getCount() {
return orderName.size();
}
#Override
public Object getItem(int position) {
return orderName.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listView;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
listView = inflater.inflate(R.layout.cart_list_item, null);
TextView name = (TextView) listView.findViewById(R.id.textOrderName);
TextView size = (TextView) listView.findViewById(R.id.textOrderSize);
TextView quantity = (TextView) listView.findViewById(R.id.textOrderQuantity);
name.setText(orderName.get(position));
size.setText(orderSize.get(position));
quantity.setText(orderQuantity.get(position));
return listView;
}
Why is the data only inserted on the second time?
The problem is in your while loop. When there is only one order then your while loop body will not be executed because you have used data.moveToNext() as condition. If your order count more than one, only then it will enter into the while loop.
ERROR:
data.moveToFirst();
while (data.moveToNext()) {
orderName.add(data.getString(1));
orderSize.add(data.getString(2));
orderQuantity.add(data.getString(3));
}
SOLUTION:
if(data.moveToFirst())
{
do
{
orderName.add(data.getString(1));
orderSize.add(data.getString(2));
orderQuantity.add(data.getString(3));
} while(data.moveToNext());
}
Hope this will help~
this is happening because you are adding data to orderName,orderSize and orderQuantity after setting adapter to listView. and you are not even calling
adapter.notifyDataSetChanged();
to let the adapter know that dataSet has changed
The problem is that the adapter doesn't know that you have added an element to the database.
After:
db.addPerson(name,size,bottleCaseQuantity);
you should make
adapter.notifyDataSetChanged()
Well guys I fixed the problem
I made a do-while in retrieving the data and it works!
do{
orderName.add(data.getString(1));
orderSize.add(data.getString(2));
orderQuantity.add(data.getString(3));
} while (data.moveToNext());
thanks again to anyone who wanted and helped :D
first time posting here, long time lurker. I am developing an Android app using an SQLite Database to persist data. The first view I have is a ListView where the user can add, change or delete Animal names. They can also hit an Edit Button, which brings them to a second view. This view has more details about the same animal, such as DOB and Comments, with the name and id transferred over from the first view.
The problem I am running into is I cannot figure out how to get the current animal's DOB and Comments to display in their respective EditTexts from the database. I have a save button at the bottom of this view that should save whatever info they put into these fields already, but then going back into this view needs to display whatever they have entered. My code for the two views and my DBHelper class is below. Thanks!
Here are images of what the two views look like.
ListView Primary View
Detail View
The MainActivity that contains the first view and the ListView:
public class MainActivity extends AppCompatActivity
{
public final static String ID_EXTRA = "com.example.josh.boergoats._ID";
public final static String NAME_EXTRA = "com.example.josh.boergoats.name";
private DBHelper dbHelper = null;
private Cursor cursor = null;
private DBAdapter adapter = null;
EditText editAnimal = null;
String animalId = null;
long idAnimal = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try
{
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
editAnimal = (EditText) findViewById(R.id.animalEditText);
dbHelper = new DBHelper(this);
cursor = dbHelper.getAll();
startManagingCursor(cursor);
adapter = new DBAdapter(cursor);
listView.setAdapter(adapter);
Button addButton = (Button) findViewById(R.id.addButton);
addButton.setOnClickListener(onSave);
Button deleteButton = (Button) findViewById(R.id.deleteButton);
deleteButton.setOnClickListener(onDelete);
Button editButton = (Button) findViewById(R.id.editButton);
editButton.setOnClickListener(onEdit);
listView.setOnItemClickListener(onListClick);
}
catch (Exception e)
{
Log.e("ERROR", "ERROR IN CODE: " + e.toString());
e.printStackTrace();
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
dbHelper.close();
}
private View.OnClickListener onSave = new View.OnClickListener()
{
public void onClick(View v)
{
Button addButton = (Button) findViewById(R.id.addButton);
if (animalId == null)
{
dbHelper.insert(editAnimal.getText().toString());
}
else
{
dbHelper.update(animalId, editAnimal.getText().toString());
animalId = null;
}
cursor.requery();
editAnimal.setText("");
addButton.setText("Add Animal");
}
};
private View.OnClickListener onDelete = new View.OnClickListener()
{
public void onClick(View v)
{
if (animalId == null)
{
return;
}
else
{
dbHelper.delete(animalId);
animalId = null;
}
cursor.requery();
editAnimal.setText("");
Button addButton = (Button) findViewById(R.id.addButton);
addButton.setText("Add Animal");
}
};
private View.OnClickListener onEdit = new View.OnClickListener()
{
public void onClick(View v)
{
Button editButton = (Button) findViewById(R.id.editButton);
editButton.setVisibility(View.INVISIBLE);
Button addButton = (Button) findViewById(R.id.addButton);
addButton.setText("Add Animal");
Intent i = new Intent(MainActivity.this, DetailActivity.class);
//i.putExtra(ID_EXTRA, String.valueOf(id));
i.putExtra(NAME_EXTRA, String.valueOf(editAnimal.getText().toString()));
i.putExtra(ID_EXTRA, String.valueOf(idAnimal));
editAnimal.setText("");
startActivity(i);
}
};
private AdapterView.OnItemClickListener onListClick = new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
animalId = String.valueOf(id);
Cursor c = dbHelper.getById(animalId);
c.moveToFirst();
editAnimal.setText(dbHelper.getAnimal(c));
Button addButton = (Button) findViewById(R.id.addButton);
addButton.setText("Update");
Button editButton = (Button) findViewById(R.id.editButton);
editButton.setVisibility(View.VISIBLE);
idAnimal = id;
}
};
public class DBAdapter extends CursorAdapter
{
DBAdapter(Cursor c)
{
super(MainActivity.this, c);
}
#Override
public void bindView(View view, Context context, Cursor c)
{
DBHolder holder = (DBHolder) view.getTag();
holder.populateFrom(c, dbHelper);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
DBHolder holder = new DBHolder(row);
row.setTag(holder);
return(row);
}
}
static class DBHolder
{
private TextView name = null;
DBHolder(View row)
{
name = (TextView) row.findViewById(R.id.nameTextView);
}
void populateFrom(Cursor c, DBHelper helper)
{
//name.setText(r.getName(c));
name.setText(helper.getAnimal(c));
}
}
}
The second activity, DetailActivity, where I am having the problem.
public class DetailActivity extends AppCompatActivity
{
private DBHelper dbHelper = null;
//private Cursor cursor = null;
String passedName = null;
String passedID = null;
private EditText passedIdView = null;
private EditText passedNameView = null;
private EditText dobView = null;
private EditText commentsView = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
//dbHelper = new DBHelper(this);
//cursor = dbHelper.getAllInfo();
passedName = getIntent().getStringExtra(MainActivity.NAME_EXTRA);
passedNameView = (EditText) findViewById(R.id.nameDetailEditText);
passedNameView.setText(passedName);
passedID = getIntent().getStringExtra(MainActivity.ID_EXTRA);
passedIdView = (EditText) findViewById(R.id.idDetailEditText);
passedIdView.setText(passedID);
dobView = (EditText) findViewById(R.id.dobDetailEditText);
commentsView = (EditText) findViewById(R.id.commentsDetailEditText);
Button saveButton = (Button) findViewById(R.id.saveButton);
saveButton.setOnClickListener(onSave);
}
private View.OnClickListener onSave = new View.OnClickListener()
{
public void onClick(View v)
{
String id = passedID;
passedID = getIntent().getStringExtra(MainActivity.ID_EXTRA);
if (passedNameView.getText().toString() != null)
{
if (passedID != null)
{
dbHelper.update(id, passedNameView.getText().toString());
}
}
if (dobView.getText().toString() != null)
{
dbHelper.updateDob(id, dobView.getText().toString());
}
if (commentsView.getText().toString() != null)
{
dbHelper.updateComments(id, commentsView.getText().toString());
}
//reset all edittext fields to blank before leaving
passedIdView.setText("");
passedNameView.setText("");
dobView.setText("");
commentsView.setText("");
Intent i = new Intent(DetailActivity.this, MainActivity.class);
startActivity(i);
}
};
}
The Database Helper class, where the database is created and manipulated. Note that not all of the methods are being used, a few of them are from my experimenting.
public class DBHelper extends SQLiteOpenHelper
{
private static final String dbPath = "/data/data/com.example.josh.boergoats/";
private static final String dbName = "animals.db";
private static final int schemaVersion = 1;
public DBHelper(Context context)
{
super(context, dbName, null, schemaVersion);
//this.myContext = context;
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE Animals (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, dob TEXT, comments TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
}
public void insert(String animal)
{
ContentValues cv = new ContentValues();
cv.put("name", animal);
getWritableDatabase().insert("Animals", "name", cv);
}
public void update(String id, String animal)
{
ContentValues cv = new ContentValues();
String[] args = {id};
cv.put("name", animal);
getWritableDatabase().update("Animals", cv, "_id=?", args);
}
public void updateDob(String id, String dob)
{
ContentValues cv = new ContentValues();
String[] args = {id};
cv.put("dob", dob);
getWritableDatabase().update("Animals", cv, "_id=?", args);
}
public void updateComments(String id, String comment)
{
ContentValues cv = new ContentValues();
String[] args = {id};
cv.put("comments", comment);
getWritableDatabase().update("Animals", cv, "_id=?", args);
}
public void delete(String id)
{
getWritableDatabase().delete("Animals", "_id=?", new String[] {id});
}
public Cursor getAll()
{
return(getReadableDatabase().rawQuery("SELECT _id, name FROM Animals", null));
}
public Cursor getAllInfo()
{
return(getReadableDatabase().rawQuery("SELECT _id, name, dob, comments FROM Animals", null));
}
public String getAnimal(Cursor c)
{
return(c.getString(1));
}
public String getDob(Cursor c)
{
return(c.getString(2));
}
public String getComments(Cursor c)
{
return(c.getString(3));
}
public Cursor getById(String id)
{
String[] args = {id};
return(getReadableDatabase().rawQuery("SELECT _id, name FROM Animals WHERE _id=?", args));
}
}
Thank you again in advance.
What I do, to use the same activity to add or edit (which I believe is what you're trying to do), is to pass, via an Intent Extra, the respective option and then have the code set the respective values. here's an example :-
String caller = getIntent().getStringExtra("Caller");
if(getIntent().getStringExtra("Caller").equals("ShopListByCursorActivityUpdate")) {
((EditText) findViewById(R.id.ase_storename_input)).setText(getIntent().getStringExtra("ShopName"));
((EditText) findViewById(R.id.ase_storeorder_input)).setText(getIntent().getStringExtra("ShopOrder"));
((EditText) findViewById(R.id.ase_storestreet_input)).setText(getIntent().getStringExtra("ShopStreet"));
((EditText) findViewById(R.id.ase_storecity_input)).setText(getIntent().getStringExtra("ShopCity"));
((EditText) findViewById(R.id.ase_storestate_input)).setText(getIntent().getStringExtra("ShopState"));
((EditText) findViewById(R.id.ase_storephone_input)).setText(getIntent().getStringExtra("ShopPhone"));
((EditText) findViewById(R.id.ase_storenotes_input)).setText(getIntent().getStringExtra("ShopNotes"));
setTitle(getResources().getString(R.string.title_activity_shop_edit));
}
The 2nd Line checks for the Update mode (ie what is in the Intent Extra named Caller (extracted into caller)) and then sets the respective values which themselves are in Intent Extras. 1st line isn't needed I just had it there for debugging purposes.
Note the when called by Edit as opposed to Add then the Intent Extra Caller is set to ShopListByCursorActivityUpdate when adding is is set to ShopListByCursorActivity.
PS You may have issues in the first activity not displaying the changed/saved data as it doesn't appear that you refresh the data. In brief, if this is an issue. You need to rebuild the cursor (ie redo the query) and then get the adapter to use the new/amended cursor via changeCursor, SwapCursor or notifyDataSetChanged. eg :-
Cursor csr = shopperdb.getShopsAsCursor();
currentsca.swapCursor(csr);
In regards to comment
You are on the right track, but I was actually having trouble putting the information that I needed into the Intent Extra. Since I don't have the DOB or comments field on my first activity, I need to pull that information from my database and put it into the Intent Extra somehow. Those 2 fields are created in my DBHelper class. Also, depending on how they can be pulled from the database, they may not even need to be put in the Intent Extra if they can be put straight into my EditTexts.
Then Use SELECT * FROM Animals to get all columns in getAll then all columns will be available in the returned Cursor.
I am trying to delete objects in a listView and database at the same time after you have clicked the item in the listView. I'm tying to make it open an alert dialog before deleting the item. I have read many other stack overflow questions about this such as :
how can i delete an item from listview and also database
delete a specific item from listview stored in database in android application
Delete item from database - ListView - Android
And many others...none of them I find very helpful. Any suggestions?
Main_Activity:
public class New_Recipe extends AppCompatActivity {
Button add, done;
EditText Recipe_Name, Recipe_Item, Recipe_Steps;
String search;
WebView webView;
DatabaseHelper databaseHelper;
ListView ItemsList;
Context context = this;
SQLiteDatabase sqLiteDatabase;
Cursor cursor;
RecipeListAdapter listAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new__recipe);
setTitle("New Recipe");
add = (Button) findViewById(R.id.button2);
done = (Button) findViewById(R.id.button);
Recipe_Name = (EditText) findViewById(R.id.editText);
Recipe_Item = (EditText) findViewById(R.id.editText2);
Recipe_Steps = (EditText) findViewById(R.id.editText3);
webView = (WebView) findViewById(R.id.webView);
ItemsList = (ListView) findViewById(R.id.listView);
listAdapter = new RecipeListAdapter(getApplicationContext(), R.layout.recipe_textview);
context = this;
AddData();
}
//When the add button is pressed
public void AddData() {
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String item = Recipe_Item.getText().toString();
databaseHelper = new DatabaseHelper(context);
sqLiteDatabase = databaseHelper.getWritableDatabase();
databaseHelper.addItems(item, sqLiteDatabase);
Toast.makeText(getBaseContext(), "Item inserted", Toast.LENGTH_LONG).show();
databaseHelper.close();
ItemsList.setAdapter(listAdapter);
databaseHelper = new DatabaseHelper(getApplicationContext());
sqLiteDatabase = databaseHelper.getReadableDatabase();
cursor = databaseHelper.getItems(sqLiteDatabase);
if (cursor.moveToFirst()) {
do {
String items;
items = cursor.getString(0);
RecipeDataProvider dataProvider = new RecipeDataProvider(items);
listAdapter.add(dataProvider);
} while (cursor.moveToNext());
}
}
});
}
public void onSearch(View v) {
search = "Recipes";
webView.loadUrl("https://www.google.com/search?q=" + search);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new__recipe, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
DatabaseHelper class:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 5;
public static final String DATABASE_NAME = "Recipes.db";
public static final String CREATE_QUERRY = "create table " + RecipeContract.RecipeEntry.TABLE_NAME + "( _ID INTEGER PRIMARY KEY, NAME text, ITEMS text, STEPS text)";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.d("Recipe Database", "Database should be made!");
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_QUERRY);
Log.d("Recipe Database", "Table should be made!");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void addItems(String items, SQLiteDatabase db)
{
ContentValues values = new ContentValues();
values.put(RecipeContract.RecipeEntry.COL2,items);
db.insert(RecipeContract.RecipeEntry.TABLE_NAME,null,values);
Log.e("Recipe Database","Item should be added to the table!");
}
public Cursor getItems(SQLiteDatabase db)
{
Cursor cursor;
String[] projections = {RecipeContract.RecipeEntry.COL2};
cursor = db.query(RecipeContract.RecipeEntry.TABLE_NAME,projections,null,null,null,null,null);
return cursor;
}
ListViewAdapter:
public class RecipeListAdapter extends ArrayAdapter {
List list = new ArrayList();
public RecipeListAdapter(Context context, int resource) {
super(context, resource);
}
static class LayoutHandler
{
TextView ITEM;
}
#Override
public void add(Object object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return super.getCount();
}
#Override
public Object getItem(int position) {
return super.getItem(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
LayoutHandler layoutHandler;
if (row == null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.recipe_textview,parent,false);
layoutHandler = new LayoutHandler();
layoutHandler.ITEM = (TextView) row.findViewById(R.id.tx_items);
row.setTag(layoutHandler);
} else {
layoutHandler = (LayoutHandler) row.getTag();
}
RecipeDataProvider dataProvider = (RecipeDataProvider) this.getItem(position);
layoutHandler.ITEM.setText(dataProvider.getItems().toString());
return row;
}
EDIT: my updated Main_Activity class
public class New_Recipe extends AppCompatActivity {
Button add, done;
EditText Recipe_Name, Recipe_Item, Recipe_Steps;
String search;
WebView webView;
DatabaseHelper databaseHelper;
ListView ItemsList;
Context context = this;
SQLiteDatabase sqLiteDatabase;
Cursor cursor;
RecipeListAdapter listAdapter;
List<New_Recipe> list = new ArrayList<>();
private int id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new__recipe);
setTitle("New Recipe");
add = (Button) findViewById(R.id.button2);
done = (Button) findViewById(R.id.button);
Recipe_Name = (EditText) findViewById(R.id.editText);
Recipe_Item = (EditText) findViewById(R.id.editText2);
Recipe_Steps = (EditText) findViewById(R.id.editText3);
webView = (WebView) findViewById(R.id.webView);
ItemsList = (ListView) findViewById(R.id.listView);
listAdapter = new RecipeListAdapter(getApplicationContext(), R.layout.recipe_textview);
context = this;
AddData();
ItemsList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Object getSelectedItem = list.get(position);
databaseHelper.deleteItem(getSelectedItem);
listAdapter.deleteitem(getSelectedItem);
return true;
}
});
}
public New_Recipe(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
You can use this method for deleting a row from DatabaseHelper class :
public void deleteItem(Object item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, KEY_ID + " = ?",
new String[]{String.valueOf(item.getId())});
db.close();
}
And then you need also one method for deleting object from adapter :
public void deleteItem(Object item) {
listArray.remove(item);
notifyDataSetChanged();
}
Now you can call all this method in activity like this :
Let's say that you want to delete all this by clicking long on list item :
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int pos, long id) {
Object getSelectedItem = arrayList.get(pos);
dataBaseHelper.deleteItem(getSelectedItem);
adapter.deleteItem(getSelectedItem);
return true;
}
});
UPDATED:
You need before you try to call method getId() to create that method in your class. So you need to create get and setter methods in your class, something like this:
STEP BY STEP:
Change your class New_Recipe to MainActivity. If you are getting an error, just highlight that error and there you will see "rename file".
Create a new class outside your main class and call it NewRecipe:
public class NewRecipe {
private int id;
private String title;
public NewRecipe() {
// empty constructor
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
And now you can do everything i have explained earlier.
You need a function deletein DatabaseHelper class
public boolean delete(long rowId) {
return db.delete(TABLE_NAME, KEY_ROWID + "=" + rowId, null) > 0;
}
You need a function in the Activity deleteItem() similar to addItems()
public void deleteItem(){
//Based on some logic,find the rowID of the table which needs to be deleted and call delete function of DatabaseHelper class.
}
Similarily in your ListViewAdapter, you need to define a method delete
public void delete(Object object) {
list.remove(object);
//To update the ListView in Android
this.notifyDataSetChanged();
}
Background:
I'm attempting to create a custom ArrayAdapter for a custom ListView. The list template I'm using to form each row contains a few TextView columns and one Button.
I'm using a SQLite table as the source of the list.
Problem:
I want the Button to capture the current time and write it to my SQLite table [Results] in the column corresponding to the row in which the Button appears. I'm at a loss for how I would do that.
Here is the class that contains the ArrayList
public class ResultsMenu extends ActionBarActivity {
private static final String LOGTAG = "Logtag: " + Thread.currentThread()
.getStackTrace()[2].getClassName(); // log tag for records
// sql elements for selecting boats
private String where = DBAdapter.KEY_RACE_ID + " = " + GlobalContent.activeRace.getId()
+ " AND " + DBAdapter.KEY_RESULTS_VISIBLE + " = 1";
private String orderBy = DBAdapter.KEY_BOAT_CLASS + " DESC ";
//instance of data source
RaceDataSource raceDataSource;
ResultDataSource resultDataSource;
// make a listview instance
ListView myList;
// make button instance for capturing finish time
Button buttonCaptureFinishTime;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results_menu);
//wire data source and open
raceDataSource = new RaceDataSource(this);
resultDataSource = new ResultDataSource(this);
raceDataSource.open();
resultDataSource.open();
// wire list view
myList = (ListView) findViewById(R.id.lvResultList);
//wire button
buttonCaptureFinishTime = (Button) findViewById(R.id.btn_finish_time);
//set onclick listening for listview
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
GlobalContent.setResultsRowID(id);
Intent intent = new Intent(view.getContext(), ResultsEditForm.class);
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_results_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
super.onResume();
Log.i(LOGTAG, " onResume Now");
raceDataSource.open(); // reopen the db
resultDataSource.open(); // reopen the db
//populateListView(); // need to build this
}
#Override
protected void onPause() {
super.onPause();
Log.i(LOGTAG, " onPause NOW");
raceDataSource.close(); // close db to reduce data leak
resultDataSource.close(); // close db to reduce data leak
}
public void populateListView(){
}
}
ArrayAdapter so far
public class ResultsAdapter extends BaseAdapter {
Context mContext; // add context
LayoutInflater inflater; // instance of inflater
// lists of result
private ArrayList<Result> arraylist;
// instance constructor
public ResultsAdapter(Context context, ResultDataSource resultDataSource) {
mContext = context;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<Result>();
}
/**
* How many items are in the data set represented by this Adapter.
*
* #return Count of items.
*/
#Override
public int getCount() {
return arraylist.size();
}
#Override
public Object getItem(int position) {
return arraylist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView( int index, View view, final ViewGroup parent) {
if (view == null) {
// build inflater to create a new row for each row in the Results table
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.activity_list_template_results, parent, false);
}
final Result result = arraylist.get(index);
Button btn = (Button) view.findViewById(R.id.btn_finish_time); // instance of button
// wire text views and set the associated text to them.
TextView tv = (TextView) view.findViewById(R.id.txt_hd_results_ID);
tv.setText(result.getResultsId() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_race_id);
tv.setText(result.getResultsRaceId() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_boat_id);
tv.setText(result.getResultsBoatId() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_Visible);
tv.setText(result.getResultsVisible() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_Name);
tv.setText(result.getBoatName() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_Class);
tv.setText(result.getBoatClass() + "");
tv = (TextView) view.findViewById(R.id.txt_hd_results_SailNum);
tv.setText(result.getBoatSailNum() + "");
// set the function of each finish button
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LocalTime localTime = new LocalTime();// capture the current time
// TODO: Add SQLite statement to insert local time into Results table
}
});
return view;
}
}
Inside the onClick method you can create an instance of your database, open it and update the data accordingly.
DatabaseConnection database = new DatabaseConnection(context);
database.getWritableDatabase();
I'm creating an app that scans bar codes, saves them in a db and manages them through a list.
So, these are classes that interested in my problem
Main
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scanner_menu);
Button addButton = (Button) findViewById (R.id.addMenuButton);
addButton.setOnClickListener (new OnClickListener(){
public void onClick (View v){
startActivity(new Intent(CodiceBarreActivity.this, AggiungiCodiceActivity.class));
}
});
Button listButton = (Button) findViewById (R.id.ViewlistButton);
listButton.setOnClickListener (new OnClickListener(){
public void onClick (View v){
startActivity(new Intent(CodiceBarreActivity.this, ProdottiSelectionActivity.class));
}
});
}
static final class ProductData {
long _id;
String barcode;
String format;
String title;
String price;
}
}
helper
private SQLiteDatabase db;
public ProductDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("create table ")
.append(PRODUCT_TABLE)
.append("( ")
.append(" _id integer primary key,")
.append(" barcode text,")
.append(" format text,")
.append(" title text,")
.append(" price text")
.append(") ");
db.execSQL(sql.toString());
Log.d(TAG, PRODUCT_TABLE + "table created");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + PRODUCT_TABLE);
Log.d(TAG, PRODUCT_TABLE + "table dropped");
onCreate(db);
}
db
private static final String PRODUCT_TABLE = "products";
private static final BigDecimal ONE_HUNDRED = new BigDecimal("100");
private SQLiteDatabase db;
public CodiciDatabase(Context context) {
ProductDatabaseHelper helper = new ProductDatabaseHelper(context);
db = helper.getWritableDatabase();
}
public boolean insert(ProductData product) {
ContentValues vals = new ContentValues();
vals.put("_id", product._id);
vals.put("barcode", product.barcode);
vals.put("format", product.format);
vals.put("title", product.title);
vals.put("price", product.price);
return db.insert(PRODUCT_TABLE, null, vals) != -1;
}
interested class
private ProductDatabaseHelper dbHelper;
private static final String PRODUCT_TABLE = "products";
ProductData product = new ProductData();
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new ProductDatabaseHelper(this);
}
#Override
protected void onResume(){
super.onResume();
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + PRODUCT_TABLE, null);
setListAdapter(new CursorAdapter(this, cursor, true) {
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent){
TextView textView = new TextView(ProdottiSelectionActivity.this);
return textView;
}
#Override
public void bindView (View view, Context context, Cursor cursor){
TextView textView = (TextView) view;
textView.append(cursor.getString(1));
textView.append("\n");
textView.append(cursor.getString(2));
textView.append("\n");
textView.append(cursor.getString(3));
textView.append("\n");
textView.append(cursor.getString(4));
registerForContextMenu(textView);
}
});
}
#Override
protected void onDestroy(){
super.onDestroy();
dbHelper.close();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
}
}
I need to implement the method onListItemClick so that you delete the selected item.I'm going crazy looking for the right syntax I hope you can help me!
Seems to me like you may be getting errors in your "interested class". Your code is a bit confusing in some places, I'm not exactly sure if your using a list view or not. But it would be helpful to use a list view and bind it to a onItemClickListener. You will use extends ListActivity in the layout you want to display the items in, make sure to put a listview element in your list view layout. Then to populate your list view, you'll have:
String[] tableColumnNames = new String[] {
"TABLE COLUMN NAMES SEPARATED BY COMMAS" };
int[] textViewLabelNames = new int[] { "NAMES OF TEXT VIEW LABELS IN XML ROW LAYOUT" };
SimpleCursorAdapter stuff = new SimpleCursorAdapter(this,
R.layout.your_created_xml_row_layout, cursor, tableColumnNames,
textViewLabelNames);
this.setListAdapter(stuff);
Then bind your onClickListener:
listView.setOnItemClickListener(new OnItemClickListener() {
//ListView item is clicked
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
Referring back to your code:
When onListItemClick is triggered you need to delete from the database the row corresponding to the id passed into the onListItemClick method. You then need to update your cursor to reflect the changes on the view by using cursor.requery().
So in order to delete an item from a database with a certain id you can do this:
ProductDatabaseHelper helper = new ProductDatabaseHelper(context);
SQLiteDatabase database = helper.getWritableDatabase();
database.delete("TABLE NAME HERE", "NAME OF ID COLUMN HERE" + "=" + id, null);
database.close();
You can also view the SQLiteDatabase Docs for a helpful description of the method signature.
something like this should work:
db.delete("products", "barcode" + "="+ barcodeToDelete, null);
replace barcodeToDelte with the value of the barcode that you want to delete from the table. If you won't know the value of the barcode you could delete it based on any of the other fields in your database too by subbing them in for "barcode" in the method above.