I am currently trying to add a deleting ability to a ListView onItemLongClick. Unfortunately, for some reason I cannot seem to do this. Whenever I long click, the dialog box appears correctly and when I press yes to delete, nothing at all happens. The item still remains in the Listview and in the database because I call the method to display all the items from the updated database right after I call my delete method. I have been trying to fix this problem for two days now and I have gotten nowhere. It seems as though it is unable to retrieve an Id from the database for each item, but I am not sure why it would be doing this.
Here is my habit object class:
public class Habit extends Object implements Serializable{
private int day_count;
private int _id;
private String habit_name, date_started, end_date, day_count_string, id_string;
public Habit(){
}
public Habit(int id, String name, String startDate, String endDate, int dayCount){
this._id = id;
this.habit_name = name;
this.date_started = startDate;
this.end_date = endDate;
this.day_count = dayCount;
}
public Habit(String name, String startDate, String endDate, int dayCount){
this.habit_name = name;
this.date_started = startDate;
this.end_date = endDate;
this.day_count = dayCount;
}
public int getID()
{
return _id;
}
public int setID(int id)
{
return this._id;
}
public String getIDString()
{
id_string = "" + this._id;
return id_string;
}
public int getDayCount()
{
return this.day_count;
}
public String getDayCountString()
{
day_count_string = "" + this.day_count;
return day_count_string;
}
public int setDayCount(int dayCount)
{
return this.day_count;
}
public String getName()
{
return this.habit_name;
}
public void setName(String name)
{
this.habit_name = name;
}
public String getStartDate()
{
return this.date_started;
}
public void setStartDate(String startDate)
{
this.date_started = startDate;
}
public String getEndDate()
{
return this.end_date;
}
public void setEndDate(String endDate)
{
this.end_date = endDate;
}
}
Here is my databaseHelper code where I call add habit to create one habit item in the database and I call deleteHabit to delete the habit at the location of the id that is in the habit object class:
public class HabitDbHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME="habits";
public static final String TABLE_HABITS = "habit_names";
public static final String KEY_NAME = "hname";
public static final String KEY_ID = "id";
public static final String KEY_STARTDATE = "start_date";
public static final String KEY_ENDDATE = "end_date";
public static final String KEY_DAYCOUNT = "day_count";
public HabitDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+TABLE_HABITS+" ("
+KEY_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "
+KEY_NAME+" TEXT, "
+KEY_STARTDATE+" TEXT, "
+KEY_ENDDATE+" TEXT, "
+KEY_DAYCOUNT+" INTEGER);");
}
// Upgrading Database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_HABITS);
onCreate(db);
}
//Adding new habit
public void addHabit(Habit habit) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, habit.getName()); // Habit Name
values.put(KEY_STARTDATE, habit.getStartDate()); // Start Date
values.put(KEY_ENDDATE, habit.getEndDate()); // End Date
values.put(KEY_DAYCOUNT, habit.getDayCount());
// Inserting Row
db.insert(TABLE_HABITS, null, values);
db.close(); // Closing database connection
}
// Fetching 1 Habit
public Habit getHabit(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_HABITS, new String[] { KEY_ID,
KEY_NAME, KEY_STARTDATE ,KEY_ENDDATE, KEY_DAYCOUNT }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Habit habit = new Habit(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3), Integer.parseInt(cursor.getString(4)));
// return contact
return habit;
}
// Fetching all Habits
public ArrayList<Habit> getAllHabits() {
ArrayList<Habit> habitList = new ArrayList<Habit>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_HABITS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Habit habit = new Habit();
habit.setID(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_ID))));
habit.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
habit.setStartDate(cursor.getString(cursor.getColumnIndex(KEY_STARTDATE)));
habit.setEndDate(cursor.getString(cursor.getColumnIndex(KEY_ENDDATE)));
habit.setDayCount(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_DAYCOUNT))));
// Adding contact to list
habitList.add(habit);
} while (cursor.moveToNext());
}
return habitList;
}
// Deleting Single Habit
public void deleteHabit(Habit habit) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_HABITS, KEY_ID + " = ?",
new String[] { String.valueOf(habit.getID()) });
db.close();
}
}
Here is my Listview adapter where each item is put into a custom item layout:
public class HabitAdapter extends BaseAdapter {
private ArrayList<Habit> habits;
private Context context;
private int layoutId;
private long id1;
public HabitAdapter(Context c, int LayoutId,ArrayList<Habit> habits) {
this.context = c;
this.layoutId = LayoutId;
this.habits = habits;
}
#Override
public int getCount() {
return habits.size();
}
#Override
public Habit getItem(int position) {
return habits.get(position);
}
#Override
public long getItemId(int position) {
Habit habit = (Habit)habits.get(position);
id1 = Long.parseLong(habit.getIDString());
return id1;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
Habit habit = habits.get(pos);
if (child == null) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.fragment_start_habit_item, null);
mHolder = new Holder();
mHolder.title = (TextView)child.findViewById(R.id.fragment_title);
mHolder.dayCount = (TextView)child.findViewById(R.id.fragment_days_left);
mHolder.startDate = (TextView)child.findViewById(R.id.fragment_start_date);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.title.setText(habit.getName());
mHolder.dayCount.setText("Days Completed: " + habit.getDayCountString());
mHolder.startDate.setText("Date Started: " + habit.getStartDate());
return child;
}
public class Holder {
TextView title;
TextView dayCount;
TextView startDate;
}
}
And finally, my main activity where I delete the item that is selected onItemLongClick:
public class fourtyMain extends Activity
{
private HabitDbHelper mDB;
private ListView mList;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fourty_main);
mList = (ListView)findViewById(R.id.habit_list);
mDB = new HabitDbHelper(this);
getActionBar().setDisplayShowTitleEnabled(false);
//Start new activity with click
mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
{
Intent singleI = new Intent(fourtyMain.this, SingleHabitView.class);
final Habit habit = (Habit) parent.getAdapter().getItem(position);
singleI.putExtra("habit", habit);
startActivity(singleI);
}
});
//long click to delete data
mList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, final View view, int position, long id) {
final Habit habit = (Habit) parent.getAdapter().getItem(position);
deleteHabitInListView(habit);
return true;
}
private void deleteHabitInListView(final Habit habit){
Builder deleteDialog = new AlertDialog.Builder(fourtyMain.this);
deleteDialog.setTitle("Delete " + habit.getName() + "?");
deleteDialog.setMessage("Are you sure you want to delete this habit? All your progress will be lost!");
deleteDialog.setPositiveButton("Yes", new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mDB.deleteHabit(habit);
displayData();
}
});
deleteDialog.setNegativeButton("No", new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
deleteDialog.show();
}
});
}
//Populate Listview
#Override
protected void onResume() {
displayData();
super.onResume();
}
private void displayData()
{
ArrayList<Habit> habitList = mDB.getAllHabits();
HabitAdapter disadpt = new HabitAdapter(fourtyMain.this, R.layout.fragment_start_habit_item, habitList);
mList.setAdapter(disadpt);
disadpt.notifyDataSetChanged();
}
}
I am absolutely lost on this one. I have been working for two days now to try and fix this problem and I have gotten nowhere. If I had to guess, I think I am going wrong on either retrieving the ID from the database or storing it incorrectly.
EDIT:
To add to this, I just found a way to write the id to a toast whenever the item is clicked. No matter what item in the list, it is returning 0 for the id. This makes me think that I am either fetching the id incorrectly or storing it incorrectly and my delete function is correct.
Insted of handling listview's setOnItemLongClickListener method, handl the perticuler cell's setOnItemLongClickListener
just like bleow :
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
Habit habit = habits.get(pos);
if (child == null) {
layoutInflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.fragment_start_habit_item, null);
mHolder = new Holder();
mHolder.llCellLayout = (LinearLayout)child.findViewById(R.id.llCellLayout);
mHolder.title = (TextView)child.findViewById(R.id.fragment_title);
mHolder.dayCount = (TextView)child.findViewById(R.id.fragment_days_left);
mHolder.startDate = (TextView)child.findViewById(R.id.fragment_start_date);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.title.setText(habit.getName());
mHolder.dayCount.setText("Days Completed: " + habit.getDayCountString());
mHolder.startDate.setText("Date Started: " + habit.getStartDate());
mHolder.llCellLayout.setOnItemLongClickListener(new OnItemLongClickListener(){
//** you can get id here and write code here for delete**
});
return child;
}
public class Holder {
TextView title;
TextView dayCount;
TextView startDate;
LinearLayout llCellLayout; //** this is the layout of cell**
}
try this code for delete operation
public float delete(String table,String colmName,String data) {
// TODO Auto-generated method stub
SQLiteDatabase db=dbhlpr.getWritableDatabase();
String[] arr={data};
colmName=colmName+"=?";
float res=db.delete(table, colmName,arr );
db.close();
return res;
}
Try to delete like below,
// Deleting Single Habit
public void deleteHabit(Habit habit) {
SQLiteDatabase database = this.getWritableDatabase();
{
database.execSQL("delete from " + "TABLE_HABITS"
+ " where KEY_ID='" + String.valueOf(habit.getID())+ "'");
}
database .close();
}
you could try the following:
1.Either change the query to a raw query like this:
public void deleteHabit(Habit habit) {
SQLiteDatabase db = this.getWritableDatabase();
String sql = "delete from " + TABLE_HABITS + " where "
+ KEY_ID + "=" + habit.getID();
db.rawQuery(sql,null);
db.close();
}
2.Or you could also try this:
public void deleteHabit(Habit habit) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_HABITS, KEY_ID+ "=" + habit.getID(), null);
db.close();
}
Hope that helps!
I managed to figure it out and of course it was the simplest error possible. In my habit object class I had it written:
public int setID(int id)
{
return this._id;
}
When all I needed to do was change it to this:
public void setID(int id)
{
this._id = id;
}
Stupid rookie mistake on my part but luckily thanks to trial and error by everybody I finally figured out my screw up. Thanks to anybody that helped out!
Related
I have an input page which submits 4 strings into the helper. The helper is supposed to get the data and put it into the listView.
When I insert my data, the app doesnt crash but it leads me to the listview page with no rows inflated. The 4 data inputs are all strings and is submitted through a button. I'm not too sure what is wrong with my code. Would appreciate some advice :)
listview code
public class MyActivitiesPage extends AppCompatActivity {
private Cursor model = null;
private ListView list;
private dbHandler helper = null;
private activityAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activities_page);
helper = new dbHandler(this);
list = findViewById(R.id.listView);
model = helper.getall();
adapter = new activityAdapter(this, model, 0);
list.setAdapter(adapter);
}
public static class activityHolder {
private TextView activitytext;
private TextView datetext;
private TextView timetext;
private TextView addresstext;
activityHolder(View row) {
activitytext = row.findViewById(R.id.activitytext);
datetext = row.findViewById(R.id.datetext);
timetext = row.findViewById(R.id.timetext);
addresstext = row.findViewById(R.id.addresstext);
}
void populateFrom(Cursor c, dbHandler helper){
activitytext.setText(helper.getActi(c));
datetext.setText(helper.getDate(c));
timetext.setText(helper.getTime(c));
addresstext.setText(helper.getAddr(c));
}
}
class activityAdapter extends CursorAdapter {
activityAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
}
public void bindView(View view, Context context, Cursor cursor) {
activityHolder holder = (activityHolder) view.getTag();
holder.populateFrom(cursor, helper);
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.row, parent, false);
activityHolder holder = new activityHolder(row);
row.setTag(holder);
return (row);
}
}
helper code
public class dbHandler extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "handler.db";
private static final int SCHEMA_VERSION = 1;
public dbHandler(#Nullable Context context){
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
this.context = context;
}
public void onCreate(SQLiteDatabase db) {
//Will be called ones when the database is not created
db.execSQL("CREATE TABLE dbTable ( _id INTEGER PRIMARY KEY AUTOINCREMENT, acti TEXT, date TEXT, time TEXT, addr TEXT );");
}
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {
//Will not be called upon until SCHEMA_VERSION increases
//For future upgrades
}
public Cursor getall() {
return (getReadableDatabase().rawQuery("SELECT * FROM dbTable", null));
}
public Cursor getById(String id) {
String[] args = {id};
return (getReadableDatabase().rawQuery("SELECT _id, acti, date, time, addr FROM dbTable WHERE _ID = ?", args));
}
public void insert(String acti, String date, String time, String addr) {
ContentValues cv = new ContentValues();
cv.put("acti", acti);
cv.put("date", date);
cv.put("time", time);
cv.put("addr", addr);
long result = getWritableDatabase().insert("dbTable", "firstvalue", cv);
if(result == -1){
Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Added Successfully!", Toast.LENGTH_SHORT).show();
}
}
public void updateDetails(String id, String acti, String date, String time, String addr) {
ContentValues cv = new ContentValues();
String[] args = {id};
cv.put("acti", acti);
cv.put("date", date);
cv.put("time", time);
cv.put("addr", addr);
getWritableDatabase().update("dbTable", cv, " _ID = ?", args);
}
public String getID(Cursor c) { return (c.getString(0));}
public String getActi(Cursor c) { return (c.getString(1));}
public String getDate(Cursor c) { return (c.getString(2));}
public String getTime(Cursor c) { return (c.getString(3));}
public String getAddr(Cursor c) { return (c.getString(4));}
}```
I spend much time on SQLite and I have a problem in deleting an item if it exist!
I'm working in Bookmark App that save links from webview into listview using SQLite, my problem is can't check if the item is exist > don't create a link.
this is my BookmarksDatabase used for sqlite:
public class BookmarksDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "bookmarks.db";
private static final String TABLE_NAME = "bookmarks_data";
private static final String COL1 = "ID";
private static final String COL2 = "ITEM1";
private static final String COL3 = "ITEM2";
public BookmarksDatabase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " + " ITEM1 TEXT, " + " ITEM2 TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item1, String item2) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, item1);
contentValues.put(COL3, item2);
long result = db.insert(TABLE_NAME, null, contentValues);
// if date as inserted incorrectly it will return -1
return result != -1;
}
public Cursor getListContents() {
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
}
public ArrayList<Bookmarks> getAllData() {
ArrayList<Bookmarks> arrayList = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
while (data.moveToNext()) {
int id = data.getInt(0);
String title = data.getString(1);
String link = data.getString(2);
Bookmarks bookmarks = new Bookmarks(id, title, link);
arrayList.add(bookmarks);
}
return arrayList;
}
public int deleteSpecificContents(int id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, COL1 + "=?", new String[]{Integer.toString(id)});
}
}
this is my code used in MainActivity to fetch items on listview
/*---------------- Bookmark Tab, sqlite databases integrated ---------------*/
private void showBookmarksScreen() {
// initialize a dialog in the main activity
final Dialog bookmarksScreen = new Dialog(this);
bookmarksScreen.requestWindowFeature(Window.FEATURE_NO_TITLE);
bookmarksScreen.setContentView(R.layout.activity_bookmark);
bookmarksScreen.setCancelable(true);
final ListView listView = bookmarksScreen.findViewById(R.id.bookmark_list);
RelativeLayout bookmarkEmpty = bookmarksScreen.findViewById(R.id.bookmark_empty);
// create an array and call bookmark
// database to retrive data then
// fetch it into list view
arrayList = new ArrayList<>();
arrayList = bookmarkDB.getAllData();
// get all data from sqlite database
Cursor data = bookmarkDB.getListContents();
// check if no bookmarks
// then show view that inform
// user that there is no bookmarks
if(data.getCount() == 0 ) {
bookmarkEmpty.setVisibility(View.VISIBLE);
}
bookmarkListAdpater = new BookmarkListAdpater(this, arrayList);
listView.setAdapter(bookmarkListAdpater);
bookmarkListAdpater.notifyDataSetChanged();
// load link on item click
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView link = view.findViewById(R.id.list_link);
String convertedLink = link.getText().toString();
webView.loadUrl(convertedLink);
bookmarksScreen.dismiss();
}
});
// ask user to delete bookmark on item long click
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
// initialize a dialog in the main activity
final Dialog deleteDialog = new Dialog(MainActivity.this);
deleteDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
deleteDialog.setContentView(R.layout.activity_confirm);
// confirm message or dialog can't be
// canceled so we set it to false
deleteDialog.setCancelable(false);
TextView deleteMessage = deleteDialog.findViewById(R.id.confirm_text);
TextView deleteConfirm = deleteDialog.findViewById(R.id.confirm_allow);
TextView deleteCancel = deleteDialog.findViewById(R.id.confirm_deny);
deleteMessage.setText(getString(R.string.delete_bookmark));
// confirm button
deleteConfirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor data = bookmarkDB.getListContents();
int i = 0;
while(data.moveToNext()){
if(i == position){
break;
}
i++;
}
bookmarkDB.deleteSpecificContents(data.getInt(0));
deleteDialog.dismiss();
bookmarksScreen.dismiss();
customToast(getString(R.string.bookmark_deleted), 0);
}
});
// confirm cancel
deleteCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteDialog.dismiss();
}
});
deleteDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
deleteDialog.show();
return true;
}
});
bookmarksScreen.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
bookmarksScreen.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
bookmarksScreen.show();
}
My Model
public class Bookmarks {
int id;
String title, link;
public Bookmarks(int id, String title, String link) {
this.id = id;
this.title = title;
this.link = link;
}
public Bookmarks() {}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
}
any ideas? thanks.
Try using below to delete item from DB
bookmarkDB.deleteSpecificContents(arrayList.get(position).getId(0));
If you want to check item exists or not before adding then add below code in your BookmarksDatabase
public boolean isExists(String link) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COL3 + "='" + link + "'", null);
return cursor.getCount() > 0;
}
And then check
if(bookmarkDB.isExists(link))
//Already Exist
else
//Not Exist, add now
With the same logic you're using:
SQLiteDatabase db = new DatabaseManager(context).getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME + " WHERE " + ID_KEY + " = ?";
Cursor cursor = db.rawQuery(query, new String[]{Integer.toString(id)});
if(cursor.moveToFirst()){
db.delete(TABLE_NAME, ID_KEY + " = ?", new String[]{Integer.toString(id)});
}
cursor.close();
db.close();
Another possibility is changing the method return type to boolean and verifying the return count from the delete command:
public boolean deleteSpecificContents(int id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, COL1 + "=?", new String[]{Integer.toString(id)}) > 0;
}
I'm working on an android project, where I want to get all the columns for a row (specific condition) and split them into TextViews.
I have a ListView with items:
StartPage Layout
When I click on one of the items from the listview it will navigate to another layout and pass the listview item as string:
public void Select()
{
final ListView listView = (ListView) findViewById(R.id.ListViewMovie);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
final String details = listView.getAdapter().getItem(position).toString();
Intent i = new Intent(getApplicationContext(), MovieDetailsActivity.class);
i.putExtra("key", details);
startActivity(i);
}
});
}
This is the other layout that it navigates to:
MovieDetails Layout
Other than that I have a MovieRepository:
public class MoviesRepository
{
private SQLiteDatabase db;
private MyDBHelper myDBHelper;
Movie movie;
private String [] MovieAllColumns ={Movie.COlUMN_ID,
Movie.COlUMN_NAME};
private String [] MovieColumns ={Movie.COlUMN_ID,
Movie.COlUMN_NAME,
Movie.COlUMN_GENRE,
Movie.COlUMN_YEAR};
public MoviesRepository(Context context)
{
myDBHelper = new MyDBHelper(context);
}
public void open() throws SQLException
{
//Open connection to write data
db = myDBHelper.getWritableDatabase();
}
public void close()
{
//Close connection to database
db.close();
}
private Movie cursorToMovie (Cursor cursor)
{
Movie movie = new Movie();
movie.setId(cursor.getInt(0));
movie.setName(cursor.getString(1));
return movie;
}
public List<Movie> getAllMovies()
{
open();
List<Movie> movieList = new ArrayList<>();
Cursor cursor = db.query(Movie.TABLE_NAME, MovieAllColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast())
{
Movie movie = cursorToMovie(cursor);
movieList.add(movie);
cursor.moveToNext();
}
cursor.close();
close();
return movieList;
}
public void Create(Movie movie)
{
open();
//helps you insert values to the table
ContentValues values = new ContentValues();
//Put method - first column; what column do you want to be storing this ind. Second; what is the value you want to put ind
values.put(Movie.COlUMN_NAME, movie.getName());
values.put(Movie.COlUMN_GENRE, movie.getGenre());
values.put(Movie.COlUMN_YEAR, movie.getYear());
db.insert(Movie.TABLE_NAME, null, values);
close();
}
public void Delete(Movie movie)
{
open();
//Deletes Movie by id
db.delete(Movie.TABLE_NAME, Movie.COlUMN_ID + " = " + movie.getId(), null);
db.close();
}
}
A DBHelper
And a Movie Model:
public class Movie
{
// property to help us handle the data
private int id;
private String name;
private String genre;
private int year;
//Getters and Setters of the properties
public long getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getGenre()
{
return genre;
}
public void setGenre(String genre)
{
this.genre = genre;
}
public int getYear()
{
return year;
}
public void setYear(int year)
{
this.year = year;
}
public String toString()
{
return name;
}
//----------Start--------- Here we have defined the table contents (basically a blueprint of the table Movie) -------------------------------------
public static final String TABLE_NAME = "movie";
public static final String COlUMN_ID = "id";
public static final String COlUMN_NAME = "make";
public static final String COlUMN_GENRE = "model";
public static final String COlUMN_YEAR = "year";
//----------------------END----------------------------------------------------------------------------------------------------------------//
}
Hope you guys can help me figure it out
You can pass entire object to an Activity and retrieve it there.
Calling Activity:
final Movie details = listView.getAdapter().getItem(position);
Intent i = new Intent(getApplicationContext(), MovieDetailsActivity.class);
i.putExtra("key", details);
Called Activity (here it is MovieDetailsActivity):
Intent intent = getIntent();
Movie details = (Movie)(intent.getExtras().getSerializable("key"));
Note that you'll have to make your class Movie Serializable.
public class Movie implements Serializable
You should keep list of data(Movies in your case) in your adapter. And then pass not title, but id of object to another activity to be able to query this object from database by id.
Thanks in advance for helping me out. This is my first time working on SQLite Database as well as creating an app.
Problem: When I click save"ImageButton" on the AddEntry.xml for some reason its not displaying on my listview which is located in my Fragment Home.xml. I found fragments to be a tad difficult since you have to change the code around in order for it to work. so please excuse if my code is all over the place.
AddEntry.java
public class AddEntry extends Fragment implements View.OnClickListener
{
EditText DescriptionET,CalorieET;
ImageButton Savebtn, Cancelbtn;
String description , calorieAmt;
CalorieDatabase calorieDB;
public AddEntry() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View myView = inflater.inflate(R.layout.fragment_add_entry,
container, false);
Savebtn = (ImageButton) myView.findViewById(R.id.SaveBtn);
Savebtn.setOnClickListener(this);
Cancelbtn = (ImageButton) myView.findViewById(R.id.CancelBtn);
Cancelbtn.setOnClickListener(this);
return myView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
DescriptionET= (EditText)view.findViewById(R.id.foodEditText);
CalorieET=(EditText)view.findViewById(R.id.caloriesEditText);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.SaveBtn:
description = DescriptionET.getText().toString();
calorieAmt=CalorieET.getText().toString();
((appMain) getActivity()).loadSelection(0);
break;
case R.id.CancelBtn:
EditText descriptionET=
(EditText)getView().findViewById(R.id.foodEditText);
descriptionET.setText("");
EditText calorieET=
(EditText)getView().findViewById(R.id.caloriesEditText);
calorieET.setText("");
break;
}
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
}
FragmentHome.java
public class FragmentHome extends Fragment implements
View.OnClickListener {
public static final String ARG_SECTION_NUMBER =
"section_number";
public static final String ARG_ID = "_id";
private TextView label;
private int sectionNumber = 0;
private Calendar fragmentDate;
ListView listview;
ImageButton AddEntrybtn;
CalorieDatabase calorieDB;
private View v;
private android.support.v4.app.FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
public FragmentHome() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_home,
container, false);
label= (TextView) myView.findViewById(R.id.section_label);
AddEntrybtn = (ImageButton) myView.findViewById(R.id.AddItems);
AddEntrybtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
((appMain)getActivity()).loadSelection(1);
}
});
return myView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle username = getActivity().getIntent().getExtras();
String username1 = username.getString("Username");
TextView userMain= (TextView)
getView().findViewById(R.id.User);
userMain.setText(username1);
openDataBase();
}
private void openDataBase (){
calorieDB= new CalorieDatabase(getActivity());
calorieDB.open();
}
private void closeDataBase(){
calorieDB.close();
};
private void populateLVFromDB(){
Cursor cursor = calorieDB.getAllRows();
String[] fromFieldNames = new String[]
{CalorieDatabase.KEY_NAME, CalorieDatabase.KEY_CalorieValue};
int[] toViewIDs = new int[]
{R.id.foodEditText, R.id.caloriesEditText, };
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
getActivity(),
R.layout.row_item,
cursor,
fromFieldNames,
toViewIDs
);
// Set the adapter for the list view
listview = (ListView) getActivity().findViewById(R.id.listViewDB);
listview.setAdapter(myCursorAdapter);
}
#Override
public void onResume() {
super.onResume();
// set label to selected date. Get date from Bundle.
int dayOffset = sectionNumber -
FragmentHomeDayViewPager.pagerPageToday;
fragmentDate = Calendar.getInstance();
fragmentDate.add(Calendar.DATE, dayOffset);
SimpleDateFormat sdf = new
SimpleDateFormat(appMain.dateFormat);
String labelText = sdf.format(fragmentDate.getTime());
switch (dayOffset) {
case 0:
labelText += " (Today)";
break;
case 1:
labelText += " (Tomorrow)";
break;
case -1:
labelText += " (Yesterday)";
break;
}
label.setText(labelText);
}
#Override
public void onDestroy() {
super.onDestroy();
closeDataBase();
}
#Override
public void onDetach() {
super.onDetach();
startActivity( new Intent(getContext(),MainActivity.class));
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.AddItems:
AddEntry addEntry = new AddEntry();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.FragmentHolder,addEntry)
.commit();
break;
}
}
}
CalorieDatabase.java
public class CalorieDatabase {
// Constants & Data
private static final String TAG = "DBAdapter";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
public static final String KEY_NAME = "Description";
public static final String KEY_CalorieValue = "Calories";
public static final int COL_NAME = 1;
public static final int COL_CalorieValue= 2;
public static final String[] ALL_KEYS = new String[]
{KEY_ROWID, KEY_NAME, KEY_CalorieValue};
public static final String DATABASE_NAME = "CalorieDb";
public static final String DATABASE_TABLE = "Calorie_Info";
public static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_NAME + " text not null, "
+ KEY_CalorieValue + " integer not null "
+ ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public CalorieDatabase(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public CalorieDatabase open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to the database.
public long insertRow(String description, int CalorieVal) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, description);
initialValues.put(KEY_CalorieValue, CalorieVal);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String description, int
CalorieValue) {
String where = KEY_ROWID + "=" + rowId;
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, description);
newValues.put(KEY_CalorieValue, CalorieValue);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int
newVersion) {
Log.w(TAG, "Upgrading application's database from version " +
oldVersion
+ " to " + newVersion + ", which will destroy all old
data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
Thanks again for helping me out. I've been stressing for the last couple of days trying to figure it out.
I'm very new at android programming and this is my first question on stack overflow ever. I am having trouble understanding where i have gone wrong in my code implementation. I'm trying to store data in a database and then extract it into an arraylist.
This is the class where i add data into the database in the button onclicklistener:
public class KarmaDescription extends AppCompatActivity {
Button button;
TasksDBHandler dbHandler;
int tId = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_karma_desc2min);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Overview");
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyTasksGS myTask = new MyTasksGS(tId, "New Task Title", 2);
dbHandler.addTask(myTask);
Toast.makeText(KarmaDescription.this, "Task Added", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
}
This is the class which manages the database:
public class TasksDBHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "tasks.db";
public static final String TABLE_TASKS = "tasks";
public static final String COLUMN_ID = "id";
public static final String COLUMN_TASKNAME = "taskname";
public static final String COLUMN_DAYSLEFT = "daysleft";
public TasksDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_TASKS + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY," +
COLUMN_TASKNAME + " TEXT," +
COLUMN_DAYSLEFT + " INTEGER" +
")";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASKS);
onCreate(db);
}
//Add a new row to the database
public void addTask(MyTasksGS myTask) {
ContentValues values = new ContentValues();
values.put(COLUMN_ID, myTask.getId());
values.put(COLUMN_TASKNAME, myTask.getTitle());
values.put(COLUMN_DAYSLEFT, myTask.getDaysRemaining());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_TASKS, null, values);
db.close();
}
//Delete row from the database
public void deleteTask(String taskID) {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_TASKS + " WHERE " + COLUMN_ID + "=\"" + taskID + "\";");
}
//To put data into an arraylist
public List<MyTasksGS> getDataFromDB()
{
int id, daysRemaining;
String title;
List<MyTasksGS> tasksList = new ArrayList<MyTasksGS>();
String query = "SELECT * FROM " + TABLE_TASKS;
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
while (cursor.moveToNext())
{
id = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_ID));
title = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_TASKNAME));
daysRemaining = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_DAYSLEFT));
MyTasksGS myTask = new MyTasksGS(id, title, daysRemaining);
tasksList.add(myTask);
}
return tasksList;
}
}
I'm trying to copy the arraylist data which is returned from the above class(using getDataFromDB function) into myTaskList here and im getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.example.prateek.karma.TasksDBHandler.getDataFromDB()' on a null object reference
public class MyTasksFragment extends Fragment {
Button taskComplete;
RecyclerView RVMyTasks;
static MyTasksAdapter mtAdapter;
List<MyTasksGS> myTaskList = new ArrayList<>();
TasksDBHandler dbHandler;
public MyTasksFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_my_tasks, container, false);
taskComplete = (Button) view.findViewById(R.id.taskComplete);
RVMyTasks = (RecyclerView) view.findViewById(R.id.RVMyTasks);
mtAdapter = new MyTasksAdapter(myTaskList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
RVMyTasks.setLayoutManager(mLayoutManager);
RVMyTasks.setItemAnimator(new DefaultItemAnimator());
RVMyTasks.setAdapter(mtAdapter);
myTaskList = dbHandler.getDataFromDB();
mtAdapter.notifyDataSetChanged();
return view;
}
}
And this is the MyTasksGS class:
public class MyTasksGS {
String title;
int daysRemaining;
int id;
public MyTasksGS() {
}
public MyTasksGS(int id, String title, int daysRemaining) {
this.title = title;
this.daysRemaining = daysRemaining;
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getDaysRemaining() {
return daysRemaining;
}
public void setDaysRemaining(int daysRemaining) {
this.daysRemaining = daysRemaining;
}
}
I may have made a very silly mistake somewhere but im not able to find it. Any help is appreciated
You need to instantiate the dbHandler, you are trying to use it without a valid instance. It causes the NullPointerException.
In your on onCreateView
before myTaskList = dbHandler.getDataFromDB();
add : dbHandler = new TasksDBHandler(getActivity());
use your class property DATABASE_NAME and DATABASE_VERSION instead of pass in constructor.
Change your TaskDBHandler constructor like this
public TasksDBHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}