App crash after getWritableDatabase() execution in my android app - android

Whenever I run the code application crashes after instantiating the helper class. I am new at this and can't figure out the error.
My contract class
public final class PetContract {
private PetContract(){}
public static class PetEntry implements BaseColumns{
public static final String TABLE_NAME = "pets";
public static final String _ID = BaseColumns._ID;
public static final String COLUMN_NAME = "name";
public static final String COLUMN_BREED = "breed";
public static final String COLUMN_GENDER = "gender";
public static final String COLUMN_WEIGHT = "weight";
// constants for gender
public static final int GENDER_UNKNOWN = 0;
public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2;
}
}
My SQLiteHelperClass
public class PetDbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "pets.db";
public static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + PetEntry.TABLE_NAME + " ( "
+ PetEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ PetEntry.COLUMN_NAME + " TEXT NOT NULL, "
+ PetEntry.COLUMN_BREED + " TEXT NOT NULL, "
+ PetEntry.COLUMN_GENDER + " INTEGER NOT NULL, "
+ PetEntry.COLUMN_WEIGHT + " FLOAT NOT NULL "
+ ")";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + PetEntry.TABLE_NAME;
public PetDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
onCreate(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Main activity
public class CatalogActivity extends AppCompatActivity {
PetDbHelper mDbHelper = new PetDbHelper(this);
public void insertDummyData(){
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
String name = "DOG";
String breed = "dkdsbk";
float weight = (float) 55.5;
values.put(PetEntry.COLUMN_NAME,name);
values.put(PetEntry.COLUMN_BREED, breed);
values.put(PetEntry.COLUMN_GENDER,PetEntry.GENDER_MALE);
values.put(PetEntry.COLUMN_WEIGHT,weight);
long newRowId = db.insert(PetEntry.TABLE_NAME,null,values);
}
public Cursor displayRowCount(){
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {PetEntry._ID};
String selection = PetEntry.TABLE_NAME;
return db.query(PetEntry.TABLE_NAME,projection,null,null,null,null,null);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(CatalogActivity.this,EditorialActivity.class );
startActivity(intent);
}
});
Cursor c = displayRowCount();
TextView view = (TextView) findViewById(R.id.text);
view.setText("The row count is" + c.getCount());
}
#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_catalog, 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
switch (id){
case R.id.delete_all_the_pets:
break;
case R.id.insert_dummy_data:
insertDummyData();
break;
}
return super.onOptionsItemSelected(item);
}
}

#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
onCreate(db);
}
this is A recursive function!!
don't call onCreate Inside onCreate

Related

Android studio sqlite and fragment

I wanted to develop a simple program with fragments and sqlite. In fact i could write sqlite program before. I followed this project
https://github.com/mitchtabian/SQLiteSaveUserData
i wrote db that can add, update, delete.
Now i want to write a program that has 3 fragments. one of them is add fragment. But when i run program, program give error. "Keeps stopping Close App"
DatabaseHelper
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "people.db";
public static final String TABLE_NAME = "people_table";
public static final String COL1 = "ID";
public static final String COL2 = "NAME";
public static final String COL3 = "EMAIL";
public static final String COL4 = "TVSHOW";
public DatabaseHelper(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, " +
" NAME TEXT, EMAIL TEXT, TVSHOW TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String name, String email, String tvShow){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2,name);
contentValues.put(COL3,email);
contentValues.put(COL4, tvShow);
long result = db.insert(TABLE_NAME, null, contentValues);
if(result == -1){
return false;
}else{
return true;
}
}
public Cursor showData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return data;
}
public boolean updateData(String id, String name, String email, String tvShow){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1,id);
contentValues.put(COL2,name);
contentValues.put(COL3,email);
contentValues.put(COL4,tvShow);
db.update(TABLE_NAME, contentValues, "ID = ?", new String[] {id});
return true;
}
public Integer deleteData(String id){
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, "ID = ?", new String[] {id});
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private TextView mTextMessage;
Fragment fragmentTemp = null;
FrameLayout fmalan;
Button btnAdd;
EditText etEng,etTr,etCom;
public DatabaseHelper dbhelper;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText("Ekle");
fragmentTemp = new Fragment_Add();
Fragment_Add_Func(fragmentTemp);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText("Test");
fragmentTemp = new Fragment_test();
Fragment_Add_Func(fragmentTemp);
return true;
case R.id.navigation_notifications:
mTextMessage.setText("Listele");
fragmentTemp = new Fragment_List();
Fragment_Add_Func(fragmentTemp);
return true;
}
return false;
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbhelper = new DatabaseHelper(this);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
fmalan = (FrameLayout) findViewById(R.id.alan);
mTextMessage = (TextView) findViewById(R.id.PageShow);
btnAdd = (Button) findViewById(R.id.btnAdd);
etEng=(EditText)findViewById(R.id.etdEng);
etTr=(EditText)findViewById(R.id.etdTr);
etCom=(EditText)findViewById(R.id.etdComment);
AddData();
}
public void AddData(){
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String Eng=etEng.getText().toString();
String Tr=etTr.getText().toString();
String Com=etCom.getText().toString();
boolean insertData = dbhelper.addData(Eng, Tr, Com);
if (insertData == true) {
Toast.makeText(MainActivity.this, "Data Successfully Inserted!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MainActivity.this, "Something went wrong :(.", Toast.LENGTH_LONG).show();
}
}
});
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actions, menu);
return true;
}
public void Fragment_Add_Func(Fragment fragment) {
if (fmalan != null) {
fmalan.removeAllViews();
}
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.alan, fragment);
fragmentTransaction.commit();
}
}
}
FragmentAdd
/**
* A simple {#link Fragment} subclass.
*/
public class Fragment_Add extends Fragment {
DatabaseHelper dbhelper;
public Fragment_Add() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment__add, container, false);
}
}
How can i solve this problem?

Cursor object returning null

ANSWER
#Override
public void categoryLoadComplete(Cursor cursor) {
data = cursor;
categoryAdapter.swapCursor(cursor);
categoryAdapter.notifyDataSetChanged();
}
#Override
public void transactionLoadComplete(Cursor cursor) {
data = cursor;
categoryAdapter.swapCursor(cursor);
categoryAdapter.notifyDataSetChanged();
}
ORIGINAL POST
I've been at this for hours now and I can't seem to figure it out, but I have narrowed the problem down to the fact that my Cursor object is returning null. I can't figure out why and was hoping to enlist the help of more experienced coders on this site.
I borrowed a Database package from this tutorial on SQLite: http://partisanapps.com/2015/08/really-useful-notes-saving-and-loading-with-a-local-database-i/
I added a second table as well as added Add, Load, Delete, and Save classes for the new table.
I can confirm that there is data in the database by exporting the file and viewing it in SQLite Broweser.
I'm attempting to populate a a spinner with data from the database as you can see in AddTransaction.class
Thank you for your time.
AddTransaction.class:
public class AddTransaction extends AppCompatActivity
implements CategoryLoad.categoryLoadComplete,
TransactionLoad.LoadComplete {
Spinner currencySpinner, recurringSpinner;
EditText itemName, itemPrice, itemNote;
Time today = new Time(Time.getCurrentTimezone());
Snackbar snackbar;
private Cursor data = null;
LinearLayout transactionLayout;
SimpleCursorAdapter categoryAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_transaction);
transactionLayout = (LinearLayout) findViewById(R.id.transactionLayout);
itemName = (EditText) findViewById(R.id.itemName);
itemPrice = (EditText) findViewById(R.id.itemPrice);
itemNote = (EditText) findViewById(R.id.note);
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Add a Transaction");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
CategoryLoad categoryLoad = new CategoryLoad(this);
categoryLoad.execute();
categoryAdapter = new SimpleCursorAdapter(getBaseContext(),
android.R.layout.simple_spinner_item,
data,
new String[] {DatabaseHelper.CATEGORY_NAME},
new int[] {android.R.id.text1},
0);
final Spinner categorySpinner = (Spinner) findViewById(R.id.categorySpinner);
categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
categoryAdapter.swapCursor(data);
categoryAdapter.notifyDataSetChanged();
categorySpinner.setAdapter(categoryAdapter);
currencySpinner = (Spinner) findViewById(R.id.currencySpinner);
ArrayAdapter<CharSequence> currencyAdapter = ArrayAdapter.createFromResource(this,
R.array.currency, android.R.layout.simple_spinner_item);
currencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
currencySpinner.setAdapter(currencyAdapter);
recurringSpinner = (Spinner) findViewById(R.id.recurringSpinner);
ArrayAdapter<CharSequence> recurringAdapter = ArrayAdapter.createFromResource(this,
R.array.recurring, android.R.layout.simple_spinner_item);
recurringAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
recurringSpinner.setAdapter(recurringAdapter);
if (data == null) {
snackbar.make(transactionLayout, "Category data failed to load", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
#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_add_category, 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.
itemPrice = (EditText) findViewById(R.id.itemPrice);
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
if (id == R.id.delete) {
Toast.makeText(getBaseContext(), "Transaction data lost!", Toast.LENGTH_LONG).show();
NavUtils.navigateUpFromSameTask(this);
return true;
}
if (id == R.id.save) {
if (TextUtils.isEmpty(itemPrice.getText().toString())) {
snackbar.make(transactionLayout, "Please input a price.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
} else {
today.setToNow();
TransactionAdd transactionAdd = new TransactionAdd(this);
transactionAdd.execute(
itemName.getText().toString(),
itemPrice.getText().toString(),
// categorySpinner.getSelectedItem().toString(),
null,
currencySpinner.getSelectedItem().toString(),
recurringSpinner.getSelectedItem().toString(),
itemNote.getText().toString(),
today.format("%Y-%m-%d %H:%M:%S")
);
Toast.makeText(getBaseContext(), "Transaction added!", Toast.LENGTH_LONG).show();
NavUtils.navigateUpFromSameTask(this);
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void categoryLoadComplete(Cursor cursor) {
data = cursor;
}
#Override
public void transactionLoadComplete(Cursor cursor) {
}
}
CategoryLoad:
public class CategoryLoad extends AsyncTask<Void, Void, Cursor> {
private static final String TAG = "LoadTask";
private categoryLoadComplete loadComplete;
private WeakReference<Context> categoryWeakReference;
private DatabaseHelper db;
public interface categoryLoadComplete {
void categoryLoadComplete(Cursor cursor);
}
public CategoryLoad(Context context) {
categoryWeakReference = new WeakReference<>(context);
db = DatabaseHelper.getInstance(categoryWeakReference.get());
try {
loadComplete = (categoryLoadComplete) categoryWeakReference.get();
} catch (ClassCastException e) {
Log.e(TAG, context.toString() + " must implement LoadComplete");
}
}
#Override
protected Cursor doInBackground(Void... params) {
Cursor result = db.getReadableDatabase().query(
DatabaseHelper.CATEGORIES_TABLE,
null, null, null, null, null, DatabaseHelper.CATEGORY_KEY_ID);
result.getCount();
return result;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(Cursor cursor) {
loadComplete.categoryLoadComplete(cursor);
}
}
TransactionLoad:
public class TransactionLoad extends AsyncTask<Void, Void, Cursor> {
private static final String TAG = "LoadTask";
private LoadComplete loadComplete;
private WeakReference<Context> transactionWeakReference;
private DatabaseHelper tt;
public interface LoadComplete {
void transactionLoadComplete(Cursor cursor);
}
public TransactionLoad(Context context) {
transactionWeakReference = new WeakReference<>(context);
tt = DatabaseHelper.getInstance(transactionWeakReference.get());
try {
loadComplete = (LoadComplete) transactionWeakReference.get();
} catch (ClassCastException e) {
Log.e(TAG, context.toString() + " must implement LoadComplete");
}
}
#Override
protected Cursor doInBackground(Void... params) {
Cursor result = tt.getReadableDatabase().query(
DatabaseHelper.TRANSACTIONS_TABLE,
null, null, null, null, null, DatabaseHelper.TRANSACTION_KEY_ID);
result.getCount();
return result;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(Cursor cursor) {
loadComplete.transactionLoadComplete(cursor);
}
}
DatabaseHelper:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "budgets.db";
private static final int SCHEMA = 1;
public static final String KEY_ID = "_id";
// ~~~~~~~~~~~~~~~~~~~Categories~~~~~~~~~~~~~~~~~~~~~~~~~~~
public static final String CATEGORIES_TABLE = "categories";
// ~~~~~~~~~~~~~~~~~~~~~Columns~~~~~~~~~~~~~~~~~~~~~~~~~~~
public static final String CATEGORY_KEY_ID = "_id_cat";
public static final String CATEGORY_NAME = "cat_name";
public static final String CATEGORY_AMOUNT = "cat_amount";
public static final String CATEGORY_CURRENCY = "cat_currency";
public static final String CATEGORY_FREQUENCY = "cat_frequency";
public static final String CATEGORY_DURATION_VALUE = "cat_duration_value";
public static final String CATEGORY_DURATION_MODIFIER = "cat_duration_modifier";
public static final String CATEGORY_OVERAGE = "cat_overage";
public static final String CATEGORY_SURPLUS = "cat_surplus";
public static final String CATEGORY_DATE = "cat_date";
// ~~~~~~~~~~~~~~~~~~~Transactions~~~~~~~~~~~~~~~~~~~~~~~~~~~
public static final String TRANSACTIONS_TABLE = "transactions";
// ~~~~~~~~~~~~~~~~~~~~~Columns~~~~~~~~~~~~~~~~~~~~~~~~~~~
public static final String TRANSACTION_KEY_ID = "_id_trans";
public static final String TRANSACTION_NAME = "trans_name";
public static final String TRANSACTION_PRICE = "trans_price";
public static final String TRANSACTION_CATEGORY = "trans_category";
public static final String TRANSACTION_CURRENCY = "trans_currency";
public static final String TRANSACTION_RECURRING = "trans_recurring";
public static final String TRANSACTION_NOTES = "trans_notes";
public static final String TRANSACTION_DATE = "trans_date";
private static DatabaseHelper mInstance = null;
public static synchronized DatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA);
}
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE categories (_id_cat INTEGER PRIMARY KEY AUTOINCREMENT, " +
"cat_name TEXT, cat_amount TEXT, cat_currency TEXT, cat_frequency TEXT," +
"cat_duration_value TEXT, cat_duration_modifier TEXT, cat_overage TEXT, " +
"cat_surplus TEXT, cat_date TEXT);");
db.execSQL("CREATE TABLE transactions (_id_trans INTEGER PRIMARY KEY AUTOINCREMENT, " +
"trans_name TEXT, trans_price TEXT, trans_category TEXT, trans_currency TEXT, " +
"trans_recurring TEXT, trans_notes TEXT, trans_date TEXT, " +
"FOREIGN KEY(trans_category) REFERENCES categories(cat_name));");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
int upgradeTo = oldVersion + 1;
while (upgradeTo <= newVersion) {
switch (upgradeTo) {
case 2:
break;
}
upgradeTo++;
}
}
}
You need to set the cursor on the adapter in your categoryLoadComplete() and transactionLoadComplete() methods, and then call adapter.notifyDataSetChanged().
Your cursor is null because it has not been assigned by the time you pass if off you your adapter. Try not creating your adapter until "categoryLoadComplete".
#Override
public void categoryLoadComplete(Cursor cursor) {
data = cursor;
categoryAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item,
data,
new String[] {DatabaseHelper.CATEGORY_NAME},
new int[] {android.R.id.text1},
0);
categorySpinner.setAdapter(categoryAdapter);
}

How to remove item from SQLite Android?

I have one RecyclerView and my method in RecyclerView adapter is working, but only for position i select and for example, when i click image with sign X i'm deleting first item which i positioned in remove method, but i want this to happens when user click image with sign X, to give him ability to select what item from the list he will delete.
Also i would like to delete that item from SQLite, but my method isn't good probably in helper class.
Here is MainActivity:
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
GridAdapter mGridAdapter;
DBHelper dbh;
String firstName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
initAddImage();
dbh = new DBHelper(this);
initRecyclerView();
initDeleteImage();
}
public List<Birthday> getData() {
List<Birthday> birthdays = new ArrayList<>();
Birthday birthday = null;
Cursor c = dbh.getBirthdayData();
if (c != null) {
while (c.moveToNext()) {
int nameIndex = c.getColumnIndex(dbh.BIRTHDAY_NAME);
String nameText = c.getString(nameIndex);
this.firstName = nameText;
int lastNameIndex = c.getColumnIndex(dbh.BIRTHDAY_LAST_NAME);
String lastNameText = c.getString(lastNameIndex);
birthday = new Birthday();
birthday.setNAME(nameText);
birthday.setLAST_NAME(lastNameText);
birthdays.add(birthday);
}
}
return birthdays;
}
private void initRecyclerView(){
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setItemAnimator(new ScaleInAnimator());
// The number of Columns
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(this, 3);
mRecyclerView.setLayoutManager(mLayoutManager);
mGridAdapter = new GridAdapter(getData());
mRecyclerView.setAdapter(mGridAdapter);
}
private void initAddImage(){
ImageView addImage = (ImageView) findViewById(R.id.add_image);
addImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddBirthday.class);
startActivity(intent);
}
});
}
private void initDeleteImage(){
ImageView deleteImage = (ImageView) findViewById(R.id.delete_image);
deleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mGridAdapter.removeItem(0);
}
});
}
#Override
protected void onResume() {
super.onResume();
initRecyclerView();
}
}
Here is my RecyclerView Adapter:
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> {
private List<Birthday> birthdays;
DBHelper dbh;
public GridAdapter(List<Birthday> birthdays){
this.birthdays = birthdays;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
CustomTextView firstName, lastName;
TextView dateOfBirthday;
public MyViewHolder(View itemView) {
super(itemView);
firstName = (CustomTextView) itemView.findViewById(R.id.first_name);
lastName = (CustomTextView) itemView.findViewById(R.id.last_name);
dateOfBirthday = (TextView) itemView.findViewById(R.id.date_of_birthday);
}
}
public void removeItem(int position) {
birthdays.remove(position);
notifyItemRemoved(position);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
MyViewHolder holder = new MyViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.firstName.setText(birthdays.get(position).getNAME());
holder.lastName.setText(birthdays.get(position).getLAST_NAME());
}
#Override
public int getItemCount() {
return birthdays.size();
}
}
And here is my Database: Method for deleting item is at the bottom of class
public class DBHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "_database";
private static final String BIRTHDAY_TABLE_NAME = "birthday_table";
public static final String BIRTHDAY_ID = "birthday_id";
public static final String BIRTHDAY_NAME = "birthday_name";
public static final String BIRTHDAY_LAST_NAME = "birthday_last_name";
private static final String CREATE_BIRTHDAY_TABLE = "CREATE TABLE " + BIRTHDAY_TABLE_NAME +
" ( " + BIRTHDAY_ID + " INTEGER PRIMARY KEY,"
+ BIRTHDAY_NAME + " TEXT," + BIRTHDAY_LAST_NAME + " TEXT );";
SQLiteDatabase database;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BIRTHDAY_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + BIRTHDAY_TABLE_NAME);
onCreate(db);
}
public void setBirthdayData(String birthdayName, String birthdayLastName) {
database = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(BIRTHDAY_NAME, birthdayName);
cv.put(BIRTHDAY_LAST_NAME, birthdayLastName);
database.insert(BIRTHDAY_TABLE_NAME, null, cv);
}
public Cursor getBirthdayData() {
database = getReadableDatabase();
String[] columns = {BIRTHDAY_ID, BIRTHDAY_NAME, BIRTHDAY_LAST_NAME};
Cursor c = database.query(BIRTHDAY_TABLE_NAME, columns, null, null, null, null, BIRTHDAY_ID + " DESC");
return c;
}
public Cursor getBirthdayName(String[] args) {
database = getReadableDatabase();
String query = "SELECT " + BIRTHDAY_NAME + " FROM " + BIRTHDAY_TABLE_NAME + " WHERE " + BIRTHDAY_NAME + " =?";
Cursor c = database.rawQuery(query, args);
return c;
}
public boolean deleteItem(long rowId) {
SQLiteDatabase db = getWritableDatabase();
return db.delete(BIRTHDAY_TABLE_NAME, BIRTHDAY_ID + "=" + rowId, null) > 0;
}
}
Assume your X sign is an ImageButton
Add the ImageButton in your grid_item.xml
In your MyViewHolder add ImageView as item named deleteItem
In OnBindViewHolder
`holder.deleteItem.setOnclickListener(new OnClickListener(){
#Override
public void onClick(View v){
dbHelper.deleteItem(birthdays.get(position).getItemId); /* you pass birthday id to a method deleteItem() in your DBHelper.java */
birthdays.remove(position);
GridAdapter.this.notifyDataSetChanged();
});`
deleteItem(long birthdayId) method
deleteItem(long birthdayId){
return database.delete(BIRTHDAY_TABLE_NAME, BIRTHDAY_ID + " = '" + birthdayId +"'", null, null, null, null);
}

recyclerview with sqlite the right way

hey guys currently Im studying recyclerview and sqlite on how to fetch data from sqlite then show it to recyclerview. I made it working but Im not confident that it is the right way. here is my code.
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Toolbar mToolBar;
private NavigationView mDrawer;
private ActionBarDrawerToggle mdrawerToggle;
private DrawerLayout mDrawerLayout;
private Button alarmButton;
private AlarmManager alarmManager;
private PendingIntent sender;
private RecyclerView listReminder;
private RemindersAdapter adapter;
List<ListInfo> data;
ListInfo infoData;
Button addReminderBtn;
MyDBHandler dbHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_PROGRESS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDrawer();
initView();
}
#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_main, 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
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mdrawerToggle.onConfigurationChanged(newConfig);
}
public void initDrawer(){
mToolBar = (Toolbar) findViewById(R.id.app_bar);
mDrawer = (NavigationView) findViewById(R.id.main_drawer);
setSupportActionBar(mToolBar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mdrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
mToolBar,
R.string.drawer_open,
R.string.drawer_close);
mDrawerLayout.setDrawerListener(mdrawerToggle);
// indicator based on whether the drawerlayout is in open or closed
mdrawerToggle.syncState();
}
public void initView(){
listReminder = (RecyclerView) findViewById(R.id.listData);
dbHandler = new MyDBHandler(this);
adapter = new RemindersAdapter(this, dbHandler.getAllData_a());
listReminder.setAdapter(adapter);
listReminder.setLayoutManager(new LinearLayoutManager(this));
addReminderBtn = (Button) findViewById(R.id.addBtn);
addReminderBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.addBtn:
Intent addReminder = new Intent(this, AddReminderActivity.class);
startActivity(addReminder);
break;
}
}
}
MyDBHandler.java
public class MyDBHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 6;
private static final String DATABASE_NAME = "paroah.db";
public static final String TABLE_REMINDER = "reminders";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_TITLE_REMINDER = "title";
public static final String COLUMN_DESC_REMINDER = "desc";
public static final String COLUMN_DATE_REMINDER = "date_created";
public MyDBHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = " CREATE TABLE "
+TABLE_REMINDER+ "(" +
COLUMN_ID +" INTEGER PRIMARY KEY AUTOINCREMENT,"+
COLUMN_TITLE_REMINDER + " TEXT ,"+
COLUMN_DESC_REMINDER + " TEXT ,"+
COLUMN_DATE_REMINDER + " TEXT "+
");";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// db.execSQL("DROP TABLE IF EXIST " + TABLE_REMINDER); // onCreate(db);
Log.d("aoi", "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
try {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_REMINDER);
onCreate(db);
} catch (SQLException e) {
Log.d("aoi", "getting exception "
+ e.getLocalizedMessage().toString());
}
}
public void addReminder(ListInfo reminder ){
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE_REMINDER, reminder.getTitle());
values.put(COLUMN_DESC_REMINDER, reminder.getDesc());
values.put(COLUMN_DATE_REMINDER, reminder.getDate());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_REMINDER, null, values);
db.close();
}
public void printDatabase(){
SQLiteDatabase db = getWritableDatabase();
}
public List<ListInfo> getAllData_a(){
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM "+TABLE_REMINDER;
Cursor cursor=db.rawQuery(query, null);
List<ListInfo> data=new ArrayList<>();
while (cursor.moveToNext()){
int _id=cursor.getInt(cursor.getColumnIndex(COLUMN_ID));
String title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE_REMINDER));
String desc = cursor.getString(cursor.getColumnIndex(COLUMN_DESC_REMINDER));
String date = cursor.getString(cursor.getColumnIndex(COLUMN_DATE_REMINDER));
ListInfo current = new ListInfo();
current.set_id(_id);
current.title = title;
current.desc = desc;
current.date = date;
data.add(current);
}
return data;
}
}
RemindersAdapter.java
public class RemindersAdapter extends RecyclerView.Adapter<RemindersAdapter.ItemViewHolder> {
private final LayoutInflater inflater;
List<ListInfo> data = Collections.emptyList();
public RemindersAdapter(Context context, List<ListInfo> data){
inflater = LayoutInflater.from(context);
this.data = data;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.reminder_item, parent, false);
ItemViewHolder holder = new ItemViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
ListInfo current = data.get(position);
holder.title.setText(current.title);
}
#Override
public int getItemCount() {
return data.size();
}
class ItemViewHolder extends RecyclerView.ViewHolder{
TextView title;
public ItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.reminderTitle);
}
}
}
is there any other way to make this code clean? What I need are the concepts and examples if you do have, or what I need to learn to make it clean. TIA!!

Populating Listview from Database Only Works Once

I'm trying to update a listview with user entries into two text inputs. Once the save button is clicked, the user's entry should appear. Based on my code, the listview updates the first time I fill out the two text inputs and I hit save, but the second time I hit save, the listview does not update. Here's my code:
Home.java
public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
EditText inputOne;
EditText inputTwo;
MyDBHandler dbHandler;
Button saveButton;
MyCursorAdapter cursorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
inputOne = (EditText) findViewById(R.id.inputOne);
inputTwo = (EditText) findViewById(R.id.inputTwo);
dbHandler = new MyDBHandler(this, null, null, 1);
saveButton = (Button) findViewById(R.id.saveButton);
MyDBHandler myDBHandler = new MyDBHandler(this);
Cursor c = myDBHandler.getCursor();
cursorAdapter = new MyCursorAdapter(this,c,1);
ListView notes = (ListView) findViewById(R.id.notes);
notes.setAdapter(cursorAdapter);
public void saveClicked(View view) {
Test test = new Test( inputOne.getText().toString(), inputTwo.getText().toString() );
dbHandler.addTest(test);
inputOne.setText("");
inputTwo.setText("");
cursorAdapter.notifyDataSetChanged();
}
MyDBHandler.java
public class MyDBHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "Database.db";
public static final String TABLE_TEST = "test";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_ONE = "one";
public static final String COLUMN_TWO = "two";
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_TEST + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_ONE + " TEXT," +
COLUMN_TWO + " TEXT" + ");";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TEST);
onCreate(db);
}
public void addTest(Test test){
ContentValues values = new ContentValues();
values.put(COLUMN_ONE, test.get_one());
values.put(COLUMN_TWO, test.get_two());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_TEST, null, values);
db.close();
}
public Cursor getCursor(){
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ACTIVITIES + " WHERE 1";
Cursor c = db.rawQuery(query, null);
return c;
}
}
MyCursorAdapter.java
public class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, 1);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.custom_row, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView one = (TextView) view.findViewById(R.id.one);
TextView two = (TextView) view.findViewById(R.id.two);
String one_string = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_ONE));
one.setText(one_string);
String two_string = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_TWO));
two.setText(two_string);
}
}
Test.java
public class Test {
private int _id;
private String _one;
private String _two;
public Test(){
}
public Test(int id){
this._id = id;
}
public Test(String one, String two){
this._one = one;
this._two = two;
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String get_one() {
return _one;
}
public void set_one(String _one) {
this._one = _one;
}
public String get_two() {
return _two;
}
public void set_two(String _two) {
this._two = _two;
}
The correct way to refresh a ListView backed by a Cursor is to call cursorAdapter.notifyDatasetChanged(), without needing to recreate and reset the adapter.
So in your saveClicked method you just update the db and let the Adapter know there has been a change.
To do this, you'll need to keep a reference to the adapter as an instance field instead of declaring it as a local variable.
Turns out my ListView was populating, but I made the mistake of putting a ListView inside of a ScrollView - so I wasn't able to see the addition of entries. It worked once I used the solution from this: Android - ListView's height just fits 1 ListView item

Categories

Resources