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();
}
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
This question already has answers here:
Deleting Row in SQLite in Android
(18 answers)
Closed 6 years ago.
I know there are lots of threads with more or less same topic but none of them covers my situation:
I have delete button that delete one item in a listView but when you close the app and reopen it the items reappears. I don't know how to fix this .
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "todo.db";
public static final int DATABASE_VERSION = 1;
public static final String ITEMS_TABLE = "items";
private static DatabaseHelper instance = null;
public static DatabaseHelper getInstance(Context context) {
if(instance == null) {
instance = new DatabaseHelper(context);
}
return instance;
}
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createQuery = "CREATE TABLE " + ITEMS_TABLE + " (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"description TEXT NOT NULL, " +
"completed INTEGER NOT NULL DEFAULT 0)";
db.execSQL(createQuery);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
The button works fine but it does not delete permently I don't know if it is the code or if it is where I am placing it in my MainActivity if someone would please tell that would much appreciated.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "ToDoApp";
private ToDoListManager listManager;
private ToDoItemAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView todoList = (ListView) findViewById(R.id.todo_list);
listManager = new ToDoListManager(getApplicationContext());
adapter = new ToDoItemAdapter(
this,
listManager.getList()
);
todoList.setAdapter(adapter);
ImageButton addButton = (ImageButton) findViewById(R.id.add_item);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onAddButtonClick();
}
});
}
#Override
protected void onPause() {
super.onPause();
}
private void onAddButtonClick() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.add_item);
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton(
R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ToDoItem item = new ToDoItem(
input.getText().toString(),
false
);
listManager.addItem(item);
adapter.swapItems(listManager.getList());
}
});
builder.setNegativeButton(
R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
private class ToDoItemAdapter extends ArrayAdapter<ToDoItem> {
private Context context;
private List<ToDoItem> items;
private LayoutInflater inflater;
public ToDoItemAdapter(
Context context,
List<ToDoItem> items
) {
super(context, -1, items);
this.context = context;
this.items = items;
this.inflater = LayoutInflater.from(context);
}
public void swapItems(List<ToDoItem> items) {
this.items = items;
notifyDataSetChanged();
}
#Override
public int getCount() {
return items.size();
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ItemViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.to_do_item_layout, parent, false);
holder = new ItemViewHolder();
holder.itemDescription = (TextView) convertView.findViewById(R.id.item);
holder.itemState = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(holder);
}else {
holder = (ItemViewHolder) convertView.getTag();
}
holder.itemDescription.setText(items.get(position).getDescription());
holder.itemState.setChecked(items.get(position).isComplete());
holder.itemState.setTag(items.get(position));
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ToDoItem item = (ToDoItem) holder.itemState.getTag();
item.toggleComplete();
listManager.updateItem(item);
notifyDataSetChanged();
}
});
ImageButton deleteButton = (ImageButton) convertView.findViewById(R.id.delete_Button);
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
items.remove(items.get(position));
notifyDataSetChanged();
}
});
holder.itemState.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ToDoItem item = (ToDoItem) holder.itemState.getTag();
item.toggleComplete();
listManager.updateItem(item);
notifyDataSetChanged();
}
});
return convertView;
}
}
public static class ItemViewHolder{
public TextView itemDescription;
public CheckBox itemState;
}
}
ToDoListManager.java
public class ToDoListManager {
private DatabaseHelper dbHelper;
public ToDoListManager(Context context) {
dbHelper = DatabaseHelper.getInstance(context);
}
public List<ToDoItem> getList() {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery(
"SELECT * FROM " + DatabaseHelper.ITEMS_TABLE,
null
);
List<ToDoItem> items = new ArrayList<>();
if(cursor.moveToFirst()) {
while(!cursor.isAfterLast()) {
ToDoItem item = new ToDoItem(
cursor.getString(cursor.getColumnIndex("description")),
cursor.getInt(cursor.getColumnIndex("completed")) != 0,
cursor.getLong(cursor.getColumnIndex("_id"))
);
items.add(item);
cursor.moveToNext();
}
}
cursor.close();
return items;
}
public void addItem(ToDoItem item) {
ContentValues newItem = new ContentValues();
newItem.put("description", item.getDescription());
newItem.put("completed", item.isComplete());
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.insert(DatabaseHelper.ITEMS_TABLE, null, newItem);
}
public void updateItem(ToDoItem item) {
ContentValues editItem = new ContentValues();
editItem.put("description", item.getDescription());
editItem.put("completed", item.isComplete());
SQLiteDatabase db = dbHelper.getWritableDatabase();
String[] args = new String[] { String.valueOf(item.getId()) };
db.update(DatabaseHelper.ITEMS_TABLE, editItem, "_id=?", args);
}
}
ToDoItem.java
public class ToDoItem {
private String description;
private boolean isComplete;
private long id;
public ToDoItem(String description, boolean isComplete) {
this(description, isComplete, -1);
}
public ToDoItem(String description,boolean isComplete,long id) {
this.description = description;
this.isComplete = isComplete;
this.id = id;
}
public String getDescription() {
return description;
}
public boolean isComplete() {
return isComplete;
}
public void toggleComplete() {
isComplete = !isComplete;
}
public long getId() {return id;}
#Override
public String toString() {
return getDescription();
}
}
you just remove items in your adapter class that causes the item delete from the current listView. but you have not any function in your ToDoListManager.java that remove items from your database. deleting from a listView does not affect to your database items.
you can add this function to your ToDoListManager.java class
public void deleteItem(long itemId) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(DatabaseHelper.ITEMS_TABLE, "_id = ?",
new String[] { String.valueOf(itemId) });
}
and call it from your delete button's onClick, like this
ImageButton deleteButton = (ImageButton) convertView.findViewById(R.id.delete_Button);
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
long itemId = items.get(position).getId();
items.remove(items.get(position));
listManager.deleteItem(itemId);
notifyDataSetChanged();
}
});
Since you are fetching the data from data base and displaying it in listview,you need to delete the row from database too. make a method in you database adapter that looks some thing like this:
public boolean deleteItem(Long id) {
return Db.delete(DATABASE_TABLE,"_id="+id,null) > 0;
}
then on list view item delete,simply call this method and pass the row id as argument.
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.
After a long time I figured out that changing argument from 0 to different number allows me to update row with corresponding id to this number:
private void saveItToDB() {
dba.open();
dba.updateDiaryEntry(((TextView) editText).getText().toString(), 2);
dba.close();
((TextView) editText).setText("");
}
In above code I changed 0 to 2 and I was able to update content of row no 2. Here is full class code:
class EditListItemDialog extends Dialog implements View.OnClickListener {
MyDB dba;
private View editText;
private DiaryAdapter adapter;
private SQLiteDatabase db;
public EditListItemDialog(Context context) {
super(context);
dba = new MyDB(context);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_text_dialog);//here is your xml with EditText and 'Ok' and 'Cancel' buttons
View btnOk = findViewById(R.id.button_ok);
editText = findViewById(R.id.edit_text);
btnOk.setOnClickListener(this);
dba.open();
}
private List<String> fragment_monday;
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Position is the number of the item clicked
//You can use your adapter to modify the item
adapter.getItem(position); //Will return the clicked item
}
public EditListItemDialog(Context context, DiaryAdapter adapter, int position) {
super(context);
this.fragment_monday = new ArrayList<String>();
this.adapter = adapter;
dba = new MyDB(context);
}
#Override
public void onClick(View v) {
fragment_monday.add(((TextView) v).getText().toString());//here is your updated(or not updated) text
dismiss();
try {
saveItToDB();
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveItToDB() {
dba.open();
dba.updateDiaryEntry(((TextView) editText).getText().toString(), 2);
dba.close();
((TextView) editText).setText("");
}
}
Now, what do I need to do in order to tell it that I want to update row that is clicked, not row number 2? Any help would be appreciated.
Here is MyDB code:
public class MyDB {
private static final String TABLE_NAME = null;
private static final String KEY_ID = null;
private SQLiteDatabase db;
private final Context context;
private final MyDBhelper dbhelper;
// Initializes MyDBHelper instance
public MyDB(Context c){
context = c;
dbhelper = new MyDBhelper(context, Constants.DATABASE_NAME, null,
Constants.DATABASE_VERSION);
}
// Closes the database connection
public void close()
{
db.close();
}
// Initializes a SQLiteDatabase instance using MyDBhelper
public void open() throws SQLiteException
{
try {
db = dbhelper.getWritableDatabase();
} catch(SQLiteException ex) {
Log.v("Open database exception caught", ex.getMessage());
db = dbhelper.getReadableDatabase();
}
}
// updates a diary entry (existing row)
public boolean updateDiaryEntry(String title, long rowId)
{
ContentValues newValue = new ContentValues();
newValue.put(Constants.TITLE_NAME, title);
return db.update(Constants.TABLE_NAME, newValue, Constants.KEY_ID + "=" + rowId, null)>0;
}
// Reads the diary entries from database, saves them in a Cursor class and returns it from the method
public Cursor getdiaries()
{
Cursor c = db.query(Constants.TABLE_NAME, null, null,
null, null, null, null);
return c;
}
}
Here is the Adapter:
public class Monday extends ListActivity {
private SQLiteDatabase db;
private static final int MyMenu = 0;
MyDB dba;
DiaryAdapter myAdapter;
private class MyDiary{
public MyDiary(String t, String c){
title=t;
content=c;
}
public String title;
public String content;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
dba = new MyDB(this);
dba.open();
setContentView(R.layout.fragment_monday);
super.onCreate(savedInstanceState);
myAdapter = new DiaryAdapter(this);
this.setListAdapter(myAdapter);
}
public class DiaryAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<MyDiary> fragment_monday;
public DiaryAdapter(Context context) {
mInflater = LayoutInflater.from(context);
fragment_monday = new ArrayList<MyDiary>();
getdata();
ListView list = getListView();
list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
new EditListItemDialog(Monday.this, null, position).show();
return true;
}
});
}
public void getdata(){
Cursor c = dba.getdiaries();
startManagingCursor(c);
if(c.moveToFirst()){
do{
String title =
c.getString(c.getColumnIndex(Constants.TITLE_NAME));
String content =
c.getString(c.getColumnIndex(Constants.CONTENT_NAME));
MyDiary temp = new MyDiary(title,content);
fragment_monday.add(temp);
} while(c.moveToNext());
}
}
#Override
public int getCount() {return fragment_monday.size();}
public MyDiary getItem(int i) {return fragment_monday.get(i);}
public long getItemId(int i) {return i;}
public View getView(int arg0, View arg1, ViewGroup arg2) {
final ViewHolder holder;
View v = arg1;
if ((v == null) || (v.getTag() == null)) {
v = mInflater.inflate(R.layout.diaryrow, null);
holder = new ViewHolder();
holder.mTitle = (TextView)v.findViewById(R.id.name);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.mdiary = getItem(arg0);
holder.mTitle.setText(holder.mdiary.title);
v.setTag(holder);
return v;
}
public class ViewHolder {
MyDiary mdiary;
TextView mTitle;
}
}
/** Called when the user clicks the Edit button */
public void visitDiary(View view) {
Intent intent = new Intent(this, Diary.class);
startActivity(intent);
}
/** Called when the user clicks the back button */
public void visitSchedule(View view) {
Intent intent = new Intent(this, DisplayScheduleScreen.class);
startActivity(intent);
}
}
Implement getItemId(int position) in your adapter. In your onListItemClick method, call this method with the given position.
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long itemId = adapter.getItemId(position);
saveItToDB(itemId);
}
private void saveItToDB(long itemId) {
String text = editText.getText().toString();
editText.setText("");
dba.open();
dba.updateDiaryEntry(text, itemId);
dba.close();
}
Top rows of three buttons shows the top three values of the database but from the next rows again top three values were shown in the three buttons ?
public class ButtonTest extends Activity {
/** Called when the activity is first created. */
NoteHelper helper = null;
Cursor ourCursor = null;
NoteAdapter adapter = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.main);
ListView list = (ListView) findViewById(R.id.list);
helper = new NoteHelper(this);
ourCursor = helper.getAll();
startManagingCursor(ourCursor);
adapter = new NoteAdapter(ourCursor);
list.setAdapter(adapter);
}
catch (Exception e) {
Log.e("ERROR", "ERROR IN CODE :" + e.toString());
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
helper.close();
}
class NoteAdapter extends CursorAdapter {
NoteAdapter(Cursor c) {
super(ButtonTest.this, c);
}
#Override
public void bindView(View row, Context ctxt, Cursor c) {
NoteHolder holder = (NoteHolder) row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context ctxt, Cursor c, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
NoteHolder holder = new NoteHolder(row);
row.setTag(holder);
return (row);
}
}
My NoteHolder Class Is
static class NoteHolder {
private Button b1 = null;
private Button b2 = null;
private Button b3 = null;
NoteHolder(View row) {
b1 = (Button) row.findViewById(R.id.one);
b2 = (Button) row.findViewById(R.id.two);
b3 = (Button) row.findViewById(R.id.three);
}
void populateFrom(Cursor c, NoteHelper helper) {
if (!c.moveToFirst()) return;
b1.setText(helper.getNote(c));
c.moveToNext();
b2.setText(helper.getNote(c));
c.moveToNext();
b3.setText(helper.getNote(c));
}
}
My SQLiteHelper Class is
class NoteHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "note.db";
private static final int SCHEMA_VERSION = 1;
public SQLiteDatabase dbSqlite;
public NoteHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE Notes (_id INTEGER PRIMARY KEY AUTOINCREMENT,note TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public Cursor getAll() {
return (getReadableDatabase().rawQuery("SELECT _id,note From Notes",
null));
}
public String getNote(Cursor c) {
return(c.getString(1));
}
public Cursor getById(String id) {
return (getReadableDatabase().rawQuery(
"SELECT _id,note From Notes", null));
}
}
}
My main.xml is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:padding="6dip"
android:background="#1F8B26">
<ListView android:layout_height="wrap_content" android:id="#+id/list"
android:layout_width="fill_parent"></ListView>
First I want to say is that Gridview will be more suitable in your case
second you are getting multiple rows because cursor adapter will create those many view that it has rows and for each row you are again reading rows in populateFrom() method so that your rows are being repeated.
Instead of Cursor adapter use Base adapter
Solution
1) first create arraylist from your cursor
2) after getting arraylist create a object of NoteAdapter which is below
3) set adapter in gridview
private class NoteAdapter extends BaseAdapter implements OnClickListener {
ArrayList<Note> arrNote;
LayoutInflater inflater;
public NoteAdapter(ArrayList<Note> arr) {
this.arrNote = arr;
inflater = ExploreDestination.this.getLayoutInflater();
}
#Override
public int getCount() {
return arrNote.size();
}
#Override
public Object getItem(int index) {
return arrNote.get(index);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(int position, View v, ViewGroup arg2) {
v = inflater.inflate(R.layout.Notebutton, null);
v.setTag(arrNote.get(position));
((Button)v).setText(arrNote.get(position).getTitle());
v.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
//do your work
}
}