SQLite Cursor initializing as -1 and causing error - java

hoping someone can help me figure this issue out. I'm trying to build an app in Android Studio for school and am running into an issue when trying to get it to load results from a database using a cursor. I keep getting the error message that the cursor is initialized at -1 and it can't access column 0. Any ideas what might be causing it? Code is below along with error message:
Main Activity:
package com.example.lab2;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.the_button);
EditText input = findViewById(R.id.edittext);
Switch urgent = findViewById(R.id.the_switch);
dbOpener dbOpener = new dbOpener(MainActivity.this);
Cursor cursor;
ListView thisList = (ListView) findViewById(R.id.listview);
AlertDialog.Builder alertDIalogBuilder = new AlertDialog.Builder(this);
ArrayList<toDoItem> arrayList = new ArrayList<toDoItem>();
class MyAdapter extends BaseAdapter {
private Context context;
private ArrayList<toDoItem> items;
public MyAdapter(Context context, ArrayList<toDoItem> items) {
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View mainView = LayoutInflater.from(context).inflate(R.layout.activity_main_todolayout, parent, false);
LayoutInflater inflater = getLayoutInflater();
if(mainView == null) {
mainView = inflater.inflate(R.layout.activity_main_todolayout, parent, false);
}
TextView itemView = mainView.findViewById(R.id.to_do_items);
itemView.setText((arrayList.get(position).getToDoName().toString()));
if(arrayList.get(position).geturgent() == true) {
mainView.setBackgroundColor(Color.RED);
itemView.setTextColor(Color.WHITE);
}
return mainView;}
};
MyAdapter adapter = new MyAdapter(this, arrayList);
thisList.setAdapter(adapter);
urgent.setChecked(false);
urgent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View V) {
urgent.setChecked(true);
}
});
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String holder = input.getText().toString();
arrayList.add (new toDoItem(holder, urgent.isChecked()));
input.getText().clear();
adapter.notifyDataSetChanged();
int urgentStatus = 0;
if(urgent.isChecked() == true) {
urgentStatus = 1;
} else {
urgentStatus = 0;
}
dbOpener.addItem(holder, urgentStatus);
urgent.setChecked(false);
}
});
thisList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
String title = getString(R.string.alert_dialogue_title);
String message = getString(R.string.alert_dialogue_message);
String pos_button = getString(R.string.pos_button);
String neg_button = getString(R.string.neg_button);
alertDIalogBuilder.setTitle(title);
alertDIalogBuilder.setMessage(message + " " + position);
alertDIalogBuilder.setPositiveButton(pos_button, (click, arg) -> {
arrayList.remove(position);
adapter.notifyDataSetChanged();
});
alertDIalogBuilder.setNegativeButton(neg_button, (click, arg) -> {
});
alertDIalogBuilder.create();
alertDIalogBuilder.show();
return false;
}
});
cursor = dbOpener.readData();
int nameColIndex = cursor.getColumnIndex("COL_ITEM_NAME");
int urgentColIndex = cursor.getColumnIndex("COL_URGENT");
int idColIndex = cursor.getColumnIndex("COL_ID");
for(int i = 0; i < cursor.getCount(); i++) {
String name = cursor.getString(nameColIndex);
int urgentHolder = cursor.getInt(urgentColIndex);
long id = cursor.getLong(idColIndex);
boolean converter = false;
if(urgentHolder == 1) {
converter = true;
} else {
converter = false;
}
arrayList.add(new toDoItem(name, converter));
}
}
}
Database Opener:
package com.example.lab2;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
public class dbOpener extends SQLiteOpenHelper {
protected final static String DATABASE_NAME = "toDoListDB";
protected final static int VERSION_NUM = 1;
public final static String TABLE_NAME = "TO_DO_ITEMS";
public final static String COL_ITEM_NAME = "ITEM";
public final static String COL_URGENT = "URGENT";
public final static String COL_ID = "_id";
private Context ctx;
String [] columns = {dbOpener.COL_ITEM_NAME, dbOpener.COL_ITEM_NAME, dbOpener.COL_URGENT};
public dbOpener(Context ctx) {super(ctx, DATABASE_NAME, null, VERSION_NUM);
this.ctx = ctx;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_ITEM_NAME
+ " TEXT," + COL_URGENT + " INTEGER)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addItem(String itemName, int urgent) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cnt = new ContentValues();
cnt.put(COL_ITEM_NAME, itemName);
cnt.put(COL_URGENT, urgent);
long result = db.insert(TABLE_NAME, null, cnt);
if(result == -1) {
Toast.makeText(ctx, "Failure", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx, "Success", Toast.LENGTH_SHORT).show();
}
}
Cursor readData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor results = db.rawQuery("SELECT * from " + TABLE_NAME, null);
return results;
}
}
Error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.lab2, PID: 15645
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lab2/com.example.lab2.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.lab2.MainActivity.onCreate(MainActivity.java:152)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 15645 SIG: 9
Disconnected from the target VM, address: 'localhost:49568', transport: 'socket'

You've defined your schema with these constants:
public final static String TABLE_NAME = "TO_DO_ITEMS";
public final static String COL_ITEM_NAME = "ITEM";
public final static String COL_URGENT = "URGENT";
public final static String COL_ID = "_id";
But you're using the names of the constants here rather than their values:
int nameColIndex = cursor.getColumnIndex("COL_ITEM_NAME");
int urgentColIndex = cursor.getColumnIndex("COL_URGENT");
int idColIndex = cursor.getColumnIndex("COL_ID");
In other words, in MainActivity, do this:
int nameColIndex = cursor.getColumnIndex(dbOpener.COL_ITEM_NAME);
int urgentColIndex = cursor.getColumnIndex(dbOpener.COL_URGENT);
int idColIndex = cursor.getColumnIndex(dbOpener.COL_ID);
Also, classes start with capital letters. You should rename dbOpener to DbOpener.

In your cursor-reading for loop, you need to move the cursor in order to iterate over the result set. An easy fix there would be to change
for(int i = 0; i < cursor.getCount(); i++) {
to
while(cursor.moveToNext()) {
There are other issues in your code such as the one pointed out by Gavin Wright in his answer. Missing moveTo...() is the reason for the crash you've reported.

Related

How to cast the value of SQLiteDatabase.execSQL to a String?

I'm developing a small android notes app using java. Everything seems to be working fine except that I'm getting an error while trying to cast the instance SQLiteDatabase.execSql obj to a String. The purpose of doing this is that, it will allow user to update their data. In the custom adapter class (obBind method) I've set a tag, which means I've the id of each itemView even in my MainActivity. What I want it to do is when a user left swipes a particular item then his/her data should be set (editText.setText) in the edittext and if he/she clicks on the add button, the data should be updated.
Please refer to the codes for better understand-ability
CustomAdapter Class:
package com.example.myapplication20;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
Context mContext;
Cursor mCursor;
CustomAdapter (Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
}
#NonNull
#Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.single_item_layout, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
if (!mCursor.moveToPosition(position)) {
return;
}
String value = mCursor.getString(mCursor.getColumnIndex(TableDetailsClass.Collection.TABLE_COLUMN));
Long id = mCursor.getLong(mCursor.getColumnIndex(TableDetailsClass.Collection._ID));
holder.mTextView.setText(value);
holder.itemView.setTag(id);
}
#Override
public int getItemCount() {
return mCursor.getCount();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
TextView uTextView;
public ViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textView);
uTextView = itemView.findViewById(R.id.updateTextView);
}
}
public void swapCursor (Cursor newCursor) {
if (mCursor != null) {
mCursor.close();
}
mCursor = newCursor;
if (newCursor != null) {
notifyDataSetChanged();
}
}
}
MainActivity Class:
package com.example.myapplication20;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.CollapsibleActionView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText mEditText;
private Button addButton;
private RecyclerView mRecyclerView;
private SQLiteDatabase mDataBase;
MyOpenHelperClass myOpenHelperClass;
CustomAdapter mCustomAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myOpenHelperClass = new MyOpenHelperClass(this);
mDataBase = myOpenHelperClass.getWritableDatabase();
mEditText = findViewById(R.id.editText);
addButton = findViewById(R.id.button);
mCustomAdapter = new CustomAdapter(this, getAllItems());
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mCustomAdapter);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItems();
}
});
// Swipe delete
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
removeItem( (Long) viewHolder.itemView.getTag());
}
}).attachToRecyclerView(mRecyclerView);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
updateItem( (Long) viewHolder.itemView.getTag());
}
}).attachToRecyclerView(mRecyclerView);
}
private void addItems () {
if (mEditText.getText().toString().trim().length() == 0) {
return;
}
String textToBeAdded = mEditText.getText().toString();
ContentValues cv = new ContentValues();
cv.put(TableDetailsClass.Collection.TABLE_COLUMN, textToBeAdded);
mDataBase.insert(TableDetailsClass.Collection.TABLE_NAME, null, cv);
mCustomAdapter.swapCursor(getAllItems());
mEditText.getText().clear();
}
public Cursor getAllItems () {
return mDataBase.query(TableDetailsClass.Collection.TABLE_NAME,
null,
null,
null,
null,
null,
TableDetailsClass.Collection.TIMESTAMP + " DESC"
);
}
public void removeItem (Long id) {
mDataBase.delete(TableDetailsClass.Collection.TABLE_NAME,
TableDetailsClass.Collection._ID + "=" + id, null);
mCustomAdapter.swapCursor(getAllItems());
Toast.makeText(this, "Item deleted!", Toast.LENGTH_SHORT).show();
}
public void updateItem (long id) {
String val = mDataBase.execSQL("SELECT * FROM " + TableDetailsClass.Collection.TABLE_NAME + " WHERE " +
TableDetailsClass.Collection._ID + "=" + id);
mEditText.setText(val); // The line I'm getting the error in. Says cannot cast void to string.
ContentValues cv = new ContentValues();
cv.put(TableDetailsClass.Collection.TABLE_COLUMN, mEditText.getText().toString());
mDataBase.update(TableDetailsClass.Collection.TABLE_NAME, cv,
TableDetailsClass.Collection._ID + "=" + id, null);
mCustomAdapter.swapCursor(getAllItems());
}
}
SQLiteOpenHelper Class:
package com.example.myapplication20;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class MyOpenHelperClass extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "myapp.db";
public static final int DATABASE_VERSION = 1;
public MyOpenHelperClass(#Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String SQL_CREATE_QUERY = "CREATE TABLE " +
TableDetailsClass.Collection.TABLE_NAME + "(" +
TableDetailsClass.Collection._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TableDetailsClass.Collection.TABLE_COLUMN + " TEXT NOT NULL, " +
TableDetailsClass.Collection.TIMESTAMP + " TIMESTAMP DEFAULT CURRENT_TIMESTAMP" + ");";
db.execSQL(SQL_CREATE_QUERY);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TableDetailsClass.Collection.TABLE_NAME);
onCreate(db);
}
}
Any kind of help will be really appreciated.
public void updateItem (long id) {
Cursor cursor = mDataBase.rawQuery("SELECT * FROM " + TableDetailsClass.Collection.TABLE_NAME + " WHERE " +
TableDetailsClass.Collection._ID + "= ?", new String[]{String.valueOf(id)});
if (cursor != null && cursor.moveToFirst()) {
String val = cursor.getString(cursor.getColumnIndex(TableDetailsClass.Collection.TABLE_COLUMN));
mEditText.setText(val);
cursor.close();
}
...
}

Java: How to update the Recycler View every time I delete an item?

I seem to be stuck with this problem where I want to update the Recycler View in real-time. Meaning I want the recycler view to update its list when a user swipes to delete a row.
As you can see in the code below I have tried to use NotifyDataSetChange() in the DatabaseAdapter java class but I only get the error "RecyclerViewAdapter.notifyDataSetChanged() on a null object reference".
I have both googled the error above and how to update Recycle view in real-time but none of the solutions I found worked. Please help me because I am losing it with this problem.
NamesAdapter.Java
package com.example.myapplication.ui;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.DatabaseAdapter;
import com.example.myapplication.R;
import org.w3c.dom.NameList;
import java.util.ArrayList;
import java.util.List;
public class NamesAdapter extends RecyclerView.Adapter<NamesAdapter.ViewHolder> {
Context context;
List<Names> namesList;
RecyclerView rvPrograms;
final View.OnClickListener onClickListener = new MyOnClickListner();
public static class ViewHolder extends RecyclerView.ViewHolder{
TextView rowID;
TextView rowName;
TextView rowAmount;
TextView rowDate;
public ViewHolder(#NonNull View itemView) {
super(itemView);
//Store the item sub-views in member variables
rowID = itemView.findViewById(R.id.idTextView);
rowName = itemView.findViewById(R.id.nameTextView);
rowAmount = itemView.findViewById(R.id.amountEditText);
rowDate = itemView.findViewById(R.id.dateTextView);
}
}
public NamesAdapter(Context context, List<Names> namesList, RecyclerView rvPrograms){
this.context = context;
this.namesList= namesList;
this.rvPrograms = rvPrograms;
}
#NonNull
#Override
public NamesAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_list, viewGroup, false);
view.setOnClickListener(onClickListener);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull NamesAdapter.ViewHolder holder, int i) {
Names name = namesList.get(i);
holder.rowID.setText(""+name.getId());
holder.rowName.setText(name.getName());
holder.rowAmount.setText(name.getAmount());
holder.rowDate.setText(name.getDate());
holder.itemView.setTag(name.getId());
}
#Override
public int getItemCount() {
return namesList.size();
}
private class MyOnClickListner implements View.OnClickListener {
#Override
public void onClick(View v) {
int itemPosition = rvPrograms.getChildLayoutPosition(v);
String item = namesList.get(itemPosition).getName();
Toast.makeText(context, item, Toast.LENGTH_SHORT).show();
}
}
}
DatabaseAdapter.Java
package com.example.myapplication;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.example.myapplication.ui.Names;
import com.example.myapplication.ui.NamesAdapter;
import java.util.ArrayList;
import java.util.List;
public class DatabaseAdapter {
DatabaseHelper helper;
SQLiteDatabase db;
List<Names> namesList = new ArrayList<>();
NamesAdapter na;
public DatabaseAdapter(Context context) {
helper = new DatabaseHelper(context);
db = helper.getWritableDatabase();
}
public int deleteData(String name){
String whereArgs[] = {name};
int count = db.delete(DatabaseHelper.Table_Name, DatabaseHelper.Key_Name+ "=?", whereArgs);
return count;
}
public int removeItem (long id){
int count = db.delete(DatabaseHelper.Table_Name, DatabaseHelper.Key_ID+ "="+ id, null);
//na.notifyDataSetChanged();
return count;
}
public int updateAmount(String name, String amount){
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.Key_Amount, amount);
String whereArgs[] = {name};
int count = db.update(DatabaseHelper.Table_Name, contentValues, DatabaseHelper.Key_Name + "=?", whereArgs);
return count;
}
public String searchData(String sname){
String columns[] = {DatabaseHelper.Key_Name, DatabaseHelper.Key_Amount};
String selectionArgs[] = {sname};
Cursor cursor = db.query(DatabaseHelper.Table_Name, columns, DatabaseHelper.Key_Name + "=?", selectionArgs, null, null, null);
StringBuffer buffer = new StringBuffer();
while (cursor.moveToNext()){
int index1 = cursor.getColumnIndex(DatabaseHelper.Key_Name);
int index2 = cursor.getColumnIndex(DatabaseHelper.Key_Amount);
String name = cursor.getString(index1);
String amount = cursor.getString(index2);
buffer.append(name + " " + amount + "\n");
}
return buffer.toString();
}
// This is for the Toast dispaly
public String getAllData(){
String columns[] = {DatabaseHelper.Key_ID, DatabaseHelper.Key_Name, DatabaseHelper.Key_Amount};
Cursor cursor = db.query(DatabaseHelper.Table_Name, columns, null, null, null, null, null, null );
StringBuffer buffer = new StringBuffer();
while (cursor.moveToNext()){
int index1 = cursor.getColumnIndex(DatabaseHelper.Key_ID);
int rowid = cursor.getInt(index1);
int index2 = cursor.getColumnIndex(DatabaseHelper.Key_Name);
String name = cursor.getString(index2);
int index3 = cursor.getColumnIndex(DatabaseHelper.Key_Amount);
int amount = cursor.getInt(index3);
buffer.append(rowid + " " + name + " " + amount + "\n");
}
return buffer.toString();
}
public List<Names> getAllNames(){
String columns[] = {DatabaseHelper.Key_ID, DatabaseHelper.Key_Name, DatabaseHelper.Key_Amount, DatabaseHelper.Key_Date};
Cursor cursor = db.query(DatabaseHelper.Table_Name, columns, null, null, null, null, DatabaseHelper.Key_ID+" DESC",null );
while (cursor.moveToNext()){
int index1 = cursor.getColumnIndex(DatabaseHelper.Key_ID);
int rowid = cursor.getInt(index1);
int index2 = cursor.getColumnIndex(DatabaseHelper.Key_Name);
String name = cursor.getString(index2);
int index3 = cursor.getColumnIndex(DatabaseHelper.Key_Amount);
Double amount = cursor.getDouble(index3);
int index4 = cursor.getColumnIndex(DatabaseHelper.Key_Date);
String date = cursor.getString(index4);
Names names = new Names(rowid, name, amount, date);
namesList.add(names);
}
return namesList;
}
public long insertData (String name, Double amount, String date){
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.Key_Name, name);
contentValues.put(DatabaseHelper.Key_Amount, amount);
contentValues.put(DatabaseHelper.Key_Date, date);
long id = db.insert(DatabaseHelper.Table_Name, null ,contentValues);
return id;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
private static final String Database_Name = "Demoze.db";
private static final String Table_Name = "salary";
private static final int Database_Version= 10;
private static final String Key_ID = "_id";
private static final String Key_Name = "name";
private static final String Key_Amount = "amount";
private static final String Key_Date = "date";
private static final String Create_table = "create table "+Table_Name+
" ("+Key_ID+" integer primary key autoincrement, "+Key_Name+
" text, "+Key_Amount+ " real, "+Key_Date+" text)";
private static final String Table_Drop = "drop table if exists "+Table_Name;
private Context context;
public DatabaseHelper(#Nullable Context context) {
super(context, Database_Name, null, Database_Version);
this.context = context;
Toast.makeText(context, "Constructor Called", Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(Create_table);
Toast.makeText(context, "OnCreate Called", Toast.LENGTH_SHORT).show();
} catch (SQLException e){
Toast.makeText(context, ""+e, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Toast.makeText(context, "OnUpgrade Called", Toast.LENGTH_SHORT).show();
db.execSQL(Table_Drop);
onCreate(db);
} catch (SQLException e) {
Toast.makeText(context, "" + e, Toast.LENGTH_SHORT).show();
}
}
}
}
SpendingActivity.Java
package com.example.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.ui.Names;
import com.example.myapplication.ui.NamesAdapter;
import java.util.ArrayList;
import java.util.List;
public class SpendingActivity extends AppCompatActivity {
DatabaseAdapter databaseAdapter;
EditText crud;
RecyclerView rvPrograms;
NamesAdapter namesAdapter;
RecyclerView.LayoutManager layoutManager;
List<Names> namesList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spending_list);
databaseAdapter = new DatabaseAdapter(this);
namesList = databaseAdapter.getAllNames();
rvPrograms = findViewById(R.id.rvDBdata);
rvPrograms.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
rvPrograms.setLayoutManager(layoutManager);
namesAdapter = new NamesAdapter(this, namesList, rvPrograms);
rvPrograms.setAdapter(namesAdapter);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
databaseAdapter.removeItem((long) viewHolder.itemView.getTag());
}
}).attachToRecyclerView(rvPrograms);
crud = findViewById(R.id.crudEditText);
String data = databaseAdapter.getAllData();
Toast.makeText(this, data, Toast.LENGTH_LONG).show();
}
public void Home (View view) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
public void Search (View view){
String name = crud.getText().toString().trim();
String result = databaseAdapter.searchData(name);
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
public void Update (View view) {
String amount = crud.getText().toString().trim();
databaseAdapter.updateAmount("taxi", amount);
}
public void Delete (View view) {
String name = crud.getText().toString().trim();
databaseAdapter.deleteData(name);
}
}
In your NamesAdapter you could expose a method called deleteItem:
public class NamesAdapter extends RecyclerView.Adapter<NamesAdapter.ViewHolder> {
...
public void deleteItem(int position){
namesList.remove(position);
notifyItemRemoved(position);
}
}
Inside of onSwiped() method, you need to call NameAdapter' deleteItem method:
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
namesAdapter.deleteItem(position);
databaseAdapter.removeItem((long) viewHolder.itemView.getTag());
}
Recycleview adapterclass
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
MyRecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {
MyRecyclerViewAdapter adapter;
ArrayList<String> animalNames
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// data to populate the RecyclerView with
animalNames = new ArrayList<>();
animalNames.add("Horse");
animalNames.add("Cow");
animalNames.add("Camel");
animalNames.add("Sheep");
animalNames.add("Goat");
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.rvAnimals);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this, animalNames);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}
#Override
public void onItemClick(View view, int position) {
Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
animalNames.remove(position);
adapter.notifyItemRemoved(position);
}
}

Access a function from another class

i have 4 classes in my app cardclick.java , DatabaseHelper.java , homeframgment.java and recyclerAdapterhomesubjectList.java
I have a function populateArrayList(); in homefragment in which i want to call every time onclick(){present in recyclerAdapterHomesubjectList} is called. can someone help me in achieving that
homefragment::
package com.example.app100.RecylerAdapter;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.app100.R;
import com.example.app100.Subject;
import com.example.app100.card_click;
import com.example.app100.ui.home.HomeFragment;
import java.util.ArrayList;
public class RecyclerAdapterHomeSubjectList extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Subject> subject;
private Context context;
public RecyclerAdapterHomeSubjectList(ArrayList<Subject> a, Context context){
this.subject = a;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from((parent.getContext()));
View view = inflater.inflate(R.layout.card_home_subject, parent, false);
return new ViewHolder(view) {
};
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
ImageView imageView = holder.itemView.findViewById(R.id.home_card_subject_imageview);
switch (position % 3) {
case 2:
imageView.setBackgroundResource(R.drawable.back1);
break;
case 1:
imageView.setBackgroundResource(R.drawable.back2);
break;
case 0:
imageView.setBackgroundResource(R.drawable.back3);
break;
}
Subject data = subject.get(position);
String name = data.subject_name;
TextView subject_name = holder.itemView.findViewById(R.id.home_card_subject_name);
subject_name.setText(name);
}
#Override
public int getItemCount() {
return subject.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ViewHolder(#NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context , card_click.class);
intent.putExtra("name" , subject.get(getAdapterPosition()).subject_name);
intent.putExtra("class_good" , subject.get(getAdapterPosition()).class_attended);
intent.putExtra("class_missed" , subject.get(getAdapterPosition()).class_missed);
intent.putExtra("credits",subject.get(getAdapterPosition()).credits);
context.startActivity(intent);
}
}
}
DatabaseHelper::
package com.example.app100;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.Nullable;
import static androidx.constraintlayout.widget.Constraints.TAG;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String table_name = "SUBJECT_LIST";
private static final String COL0 = "ID";
private static final String COL1 = "NAME";
private static final String COL2 = "CREDITS";
private static final String COL3 = "CLASS_ATTENDED";
private static final String COL4 = "CLASS_MISSED";
public DatabaseHelper(#Nullable Context context) {
super(context, table_name, null, 6);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE = "CREATE TABLE " + table_name + "("+
COL0+ " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL1 + " TEXT, " +
COL2 + " INTEGER, "+
COL3 + " INTEGER, "+
COL4 + " INTEGER);";
db.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + table_name);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
boolean addData(String name, int credit , int good , int bad){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1 , name);
contentValues.put(COL2 , credit);
contentValues.put(COL3 , good);
contentValues.put(COL4 , bad);
long result = db.insert(table_name , null , contentValues);
return result != -1;
}
public Cursor getdata(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM SUBJECT_LIST;";
return db.rawQuery(query , null);
}
void append_data(String str, String name , int goodbad) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(str, goodbad);
int count = db.update(table_name, contentValues, "NAME = ?", new String[]{name});
Log.d(TAG, "blue button is pressed");
System.out.println(count);
}
}
cardclick:
package com.example.app100;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
public class card_click extends AppCompatActivity {
TextView attendace_info;
ProgressBar progressBar;
TextView credits;
TextView progress_percent;
int bad;
int good;
Button add;
Button minus;
ImageButton performance;
String name;
DatabaseHelper databaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_click);
databaseHelper = new DatabaseHelper(this);
ActionBar actionBar = getSupportActionBar();
assert actionBar != null;
actionBar.hide();
performance = findViewById(R.id.card_click_performance_add);
progress_percent = findViewById(R.id.card_click_progress_bar_percent);
attendace_info = findViewById(R.id.card_click_attendance_text);
progressBar = findViewById(R.id.card_click_progress_bar);
credits = findViewById(R.id.card_click_credits_show);
add = findViewById(R.id.card_click_add_button);
minus = findViewById(R.id.card_click_minus_button);
Intent intent = getIntent();
good = intent.getIntExtra("class_good", 0);
bad = intent.getIntExtra("class_missed", 0);
name = intent.getStringExtra("name");
credits.setText(String.valueOf(intent.getIntExtra("credits", 0)));
display();
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
good++;
databaseHelper.append_data("CLASS_ATTENDED", name , good);
display();
Cursor data = databaseHelper.getdata();
while(data.moveToNext()){
int a = data.getInt(3);
if( a > 0)
System.out.println("database has been updated");
}
}
});
minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bad++;
databaseHelper.append_data("CLASS_MISSED", name, bad);
display();
Cursor data = databaseHelper.getdata();
while(data.moveToNext()){
int b = data.getInt(4);
if( b > 1)
System.out.println("database has been updated");
}
}
});
performance.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(card_click.this, add_performace.class);
startActivity(intent1);
}
});
}
void display(){
int per = 100;
if(good+bad != 0)
per = (int)(good*100.0)/(good+bad);
String str = "You have atttended "+ (good) +
" out of " + (good + bad) +
" classes";
attendace_info.setText(str);
progressBar.setProgress(per);
progress_percent.setText(String.valueOf(per));
}
}
RecyclerAdapterHomeSubjectList:
package com.example.app100.RecylerAdapter;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.app100.R;
import com.example.app100.Subject;
import com.example.app100.card_click;
import com.example.app100.ui.home.HomeFragment;
import java.util.ArrayList;
public class RecyclerAdapterHomeSubjectList extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<Subject> subject;
private Context context;
public RecyclerAdapterHomeSubjectList(ArrayList<Subject> a, Context context){
this.subject = a;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from((parent.getContext()));
View view = inflater.inflate(R.layout.card_home_subject, parent, false);
return new ViewHolder(view) {
};
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
ImageView imageView = holder.itemView.findViewById(R.id.home_card_subject_imageview);
switch (position % 3) {
case 2:
imageView.setBackgroundResource(R.drawable.back1);
break;
case 1:
imageView.setBackgroundResource(R.drawable.back2);
break;
case 0:
imageView.setBackgroundResource(R.drawable.back3);
break;
}
Subject data = subject.get(position);
String name = data.subject_name;
TextView subject_name = holder.itemView.findViewById(R.id.home_card_subject_name);
subject_name.setText(name);
}
#Override
public int getItemCount() {
return subject.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ViewHolder(#NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(context , card_click.class);
intent.putExtra("name" , subject.get(getAdapterPosition()).subject_name);
intent.putExtra("class_good" , subject.get(getAdapterPosition()).class_attended);
intent.putExtra("class_missed" , subject.get(getAdapterPosition()).class_missed);
intent.putExtra("credits",subject.get(getAdapterPosition()).credits);
context.startActivity(intent);
}
}
}
just import the class name and you can use the function from it. (function and the class should be public to use)

Deleting an item from RecyclerView + SQLite

So I'm trying to delete an item on a cross button. Now it is being deleted from RecyclerView, but goes crazy with SQLite. If I delete one item, it's all good. But when I delete several items, it, as I said, goes crazy and gets deleted items back outta nowhere without deleting anything then.
Here's my DataAdapted.java
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private LayoutInflater inflater;
private List<Booking> bookings;
private String time;
DBHelper dbHelper;
SQLiteDatabase dataBase;
DataAdapter(Context context, List<Booking> bookings) {
this.bookings = bookings;
this.inflater = LayoutInflater.from(context);
}
#NonNull
#Override
public DataAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull DataAdapter.ViewHolder holder, int position) {
Booking booking = bookings.get(position);
holder.nameView.setText(booking.getName());
time = booking.getHours() + ":" + booking.getMinutes();
holder.timeView.setText(time);
}
#Override
public int getItemCount() {
return bookings.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView nameView;
TextView timeView;
ImageView crossImage;
ViewHolder(View view){
super(view);
timeView = view.findViewById(R.id.time_view);
nameView = view.findViewById(R.id.name_view);
crossImage = view.findViewById(R.id.crossImage);
crossImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeAt(getAdapterPosition());
}
});
}
}
public void removeAt(int position) {
bookings.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, bookings.size());
DBHelper.delete(position);
}
}
DBHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "bookingsDb";
public static final String TABLE_BOOKINGS = "bookings";
public static final String KEY_ID = "_id";
public static final String KEY_NUMBER = "_numbers";
public static final String KEY_NAME = "_names";
public static final String KEY_HOURS = "_hours";
public static final String KEY_MINUTES = "_minutes";
public static final String KEY_PHONE= "_phones";
Context myContext;
static DBHelper dbHelper;
static SQLiteDatabase database;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
myContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_BOOKINGS + "("
+ KEY_ID + " integer primary key,"
+ KEY_NUMBER + " integer,"
+ KEY_NAME + " text,"
+ KEY_HOURS + " text,"
+ KEY_MINUTES + " text,"
+ KEY_PHONE + " text" + ")");
dbHelper = new DBHelper(myContext);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + TABLE_BOOKINGS);
onCreate(db);
}
public static void delete(int id){
database = dbHelper.getWritableDatabase();
database.delete(TABLE_BOOKINGS, KEY_ID + "=" + id, null);
}
}
And my TableActivity.java if needed
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class TableActivity extends AppCompatActivity {
int currentTable;
Button createNewBooking;
List<Booking> bookings;
TextView name;
TextView time;
DataAdapter adapter;
RecyclerView recyclerView;
DBHelper dbHelper;
View.OnClickListener createNewBookingListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(TableActivity.this, BookingActivity.class);
startActivity(intent);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table);
currentTable = MainActivity.getCurrentTable();
createNewBooking = findViewById(R.id.createNewBooking);
createNewBooking.setOnClickListener(createNewBookingListener);
bookings = new ArrayList<>();
dbHelper = new DBHelper(this);
setInitialData();
recyclerView = findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
adapter = new DataAdapter(this, bookings);
recyclerView.setAdapter(adapter);
}
private void setInitialData() {
SQLiteDatabase database = dbHelper.getWritableDatabase();
Cursor cursor = database.query(DBHelper.TABLE_BOOKINGS, null, null, null, null, null, null);
if (cursor.moveToFirst()) {
int nameIndex = cursor.getColumnIndex(DBHelper.KEY_NAME);
int hoursIndex = cursor.getColumnIndex(DBHelper.KEY_HOURS);
int minutesIndex = cursor.getColumnIndex(DBHelper.KEY_MINUTES);
int phoneIndex = cursor.getColumnIndex(DBHelper.KEY_PHONE);
do {
bookings.add(new Booking(
currentTable,
cursor.getString(nameIndex),
cursor.getString(hoursIndex),
cursor.getString(minutesIndex),
cursor.getString(phoneIndex)
));
} while (cursor.moveToNext());
} else {
Toast.makeText(this, "Броней нет", Toast.LENGTH_SHORT).show();
}
cursor.close();
dbHelper.close();
}
}
Any ideas, please?
you are giving position for delete, it's not necessary to id will be same as per adapter position.
try this :
crossImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Booking booking = bookings.get(getAdapterPosition());
datatype id = booking.getId();
removeAt(getAdapterPosition(),id);
}
});
public void removeAt(int position, dataType id) {
bookings.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, bookings.size());
DBHelper.delete(id);
}

NPE with custom adapter

I am making a custom adapter for list view and got NPE. I have already read other questions but none of them.
Here is the logcat
07-04 06:54:58.036: E/AndroidRuntime(1340): FATAL EXCEPTION: main
07-04 06:54:58.036: E/AndroidRuntime(1340): java.lang.NullPointerException
07-04 06:54:58.036: E/AndroidRuntime(1340): at com.example.amirkh.MainActivity$FastFoodAdapter.getView(MainActivity.java:166)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.widget.AbsListView.obtainView(AbsListView.java:2159)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.widget.ListView.measureHeightOfChildren(ListView.java:1246)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.widget.ListView.onMeasure(ListView.java:1158)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.view.View.measure(View.java:15518)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4825)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
07-04 06:54:58.036: E/AndroidRuntime(1340): at android.widget.TableRow.measureChildBeforeLayout(TableRow.java:247)
the code works this way. there is a databasehandler that organize database, a fastfood class and main class. in main class the user enteres a fastfood name and it goes to data base. when user clicks on the"show data" tab whole data should be shown.
here is the main class:
package com.example.amirkh;
import java.util.ArrayList;
import java.util.List;
import android.R.integer;
import android.R.menu;
import android.os.Bundle;
import android.app.Activity;
import android.app.TabActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.ActionProvider;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem.OnActionExpandListener;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends TabActivity {
private TabHost myTabHost;
private FastFoodAdapter<String> adpter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTabHost = getTabHost();
TabHost.TabSpec spec;
// Adding First Tab
spec = myTabHost.newTabSpec("first");
spec.setContent(R.id.inputtab);
spec.setIndicator("Input data");
myTabHost.addTab(spec);
// Adding Second Tab
spec = myTabHost.newTabSpec("second");
spec.setContent(R.id.listView1);
spec.setIndicator("Show data");
myTabHost.addTab(spec);
myTabHost.setCurrentTab(0);
// final List<FastFood> fflist = new ArrayList<FastFood>();
final EditText etname = (EditText) findViewById(R.id.etname);
final EditText etaddress = (EditText) findViewById(R.id.etaddress);
final ListView lv = (ListView) findViewById(R.id.listView1);
final DataBaseHandeler dbh = new DataBaseHandeler(MainActivity.this);
final RadioGroup radiogroup = (RadioGroup) findViewById(R.id.radioGroup1);
final FastFood fastfood = new FastFood();
final RadioButton rbsit = (RadioButton) findViewById(R.id.rbsit);
final RadioButton rbdeli = (RadioButton) findViewById(R.id.rbdeliv);
final RadioButton rbtake = (RadioButton) findViewById(R.id.rbtake);
refreshComponents();
Button save = (Button) findViewById(R.id.btnsave);
Button remove = (Button) findViewById(R.id.btnremove);
// Create context menu
registerForContextMenu(lv);
// end of context menu
// start of save button
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
FastFood ffastfood = new FastFood("", "", "");
ffastfood.setName(etname.getText().toString());
ffastfood.setAddress(etaddress.getText().toString());
etname.setText("");
etaddress.setText("");
if (rbsit.isChecked()) {
ffastfood.setFlag("1");
} else if (rbtake.isChecked()) {
ffastfood.setFlag("2");
} else if (rbdeli.isChecked()) {
ffastfood.setFlag("3");
}
Toast toast = Toast.makeText(MainActivity.this,
"Fastfood is saved.", 2000);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
dbh.addFastFood(ffastfood);
refreshComponents();
}
}); // end of save
// remove
remove.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
EditText etrmvid = (EditText) findViewById(R.id.etrmvid);
dbh.removeFastFood(Integer.parseInt(etrmvid.getText()
.toString()));
etrmvid.setText("");
Toast toast = Toast.makeText(MainActivity.this,
"Fastfood is removed.", 2000);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
refreshComponents();
}
});// end of remove
Context context = getApplicationContext();
// Adapter
}
class FastFoodAdapter<String> extends ArrayAdapter<String> {
public FastFood fastfood = new FastFood();
public FastFoodAdapter(Context context, int textViewResourceId,
List objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.listview_item_row, parent,
false);
}
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.listview_item_row, parent,
false);
TextView tv = (TextView) row.findViewById(R.id.txtTitle23);
TextView tv2 = (TextView) row.findViewById(R.id.txtTitle2);
ImageView iv = (ImageView) row.findViewById(R.id.imgIcon);
tv.setText(fastfood.getName());
tv2.setText(fastfood.getAddress());
if (fastfood.getFlag().equals("1"))
iv.setImageResource(R.drawable.sit);
else if (fastfood.getFlag().equals("2"))
iv.setImageResource(R.drawable.ta);
else if (fastfood.getFlag().equals("3"))
iv.setImageResource(R.drawable.deli);
return row;
}
}// /end of adapter
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
getMenuInflater().inflate(R.menu.contexmenu, menu);
super.onCreateContextMenu(menu, v, menuInfo);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
}
private void refreshComponents() {
ListView lv = (ListView) findViewById(R.id.listView1);
TextView lblCount = (TextView) findViewById(R.id.lblcount);
DataBaseHandeler dbh = new DataBaseHandeler(MainActivity.this);
List<FastFood> fflist = dbh.getAllFastFoods();
// lv.setAdapter(new FastFoodAdapter<String>(context,
// textViewResourceId, objects))
lv.setAdapter(new FastFoodAdapter<FastFood>(MainActivity.this,
android.R.layout.simple_list_item_1, fflist));
lblCount.setText("Count of all FastFoods are " + dbh.getFastFoodCount());
}
}
here is fastfood class
package com.example.amirkh;
public class FastFood {
private String name;
private String address;
private String flag;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public FastFood(String name, String address, String phone) {
super();
this.name = name;
this.address = address;
}
public FastFood() {
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
return (String.format("%s %s ", getName(), getAddress()));
}
}
and the databasehandeler
package com.example.amirkh;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseHandeler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "FastFoodManager";
private static final String TABALE_FASTFOODS = "fastfoods";
private static final String KEY_ID = "_id";
private static final String KEY_NAME = "name";
private static final String KEY_ADDRESS = "address";
private static final String KEY_FLAG = "flag";
public DataBaseHandeler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABALE_FASTFOODS + " ("
+ KEY_ID + " INTEGER PRIMARY KEY, " + KEY_NAME + " TEXT, "
+ KEY_ADDRESS + " TEXT, " + KEY_FLAG + " TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + TABALE_FASTFOODS);
onCreate(db);
}
// insert a record
public void addFastFood(FastFood fastfood) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, fastfood.getName());
values.put(KEY_ADDRESS, fastfood.getAddress());
values.put(KEY_FLAG, fastfood.getFlag());
db.insert(TABALE_FASTFOODS, null, values);
db.close();
}
// remove a record by ID
public void removeFastFood(int id) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABALE_FASTFOODS, KEY_ID + " =?",
new String[] { String.valueOf(id) });
db.close();
}
// count
public int getFastFoodCount() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABALE_FASTFOODS, null);
// db.close();
return cursor.getCount();
}
// get all contacts
public List<FastFood> getAllFastFoods() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABALE_FASTFOODS, null);
List<FastFood> fflist = new ArrayList<FastFood>();
if (cursor.moveToFirst()) {
do {
FastFood ff = new FastFood();
ff.setId(Integer.parseInt(cursor.getString(0)));
ff.setName(cursor.getString(1));
ff.setAddress(cursor.getString(2));
ff.setFlag(cursor.getString(3));
fflist.add(ff);
} while (cursor.moveToNext());
}
// db.close();
return fflist;
}
}
Thanks for helping
You are getting this NullPointerException because you are trying to compare a null String in this line
fastfood.getFlag().equals("1")
In your adapter you create an object of Food using
public FastFood fastfood = new FastFood();
In the empty constructor of Food class nothing is assigned to any of the member String so when you try to do
fastfood.getFlag().equals("1")
you are trying to call equals method on a null object.
So you get a NullPointerException.
You should use the Food objects from the List that you pass in the FastFoodAdapter constructor.
Your NPE come from:
if (fastfood.getFlag().equals("1"))
So fastfood.getFlag() seems null. You should use setFlag() before or try this comparison:
if ("1".equals(fastfood.getFlag()))

Categories

Resources