Adapter doesn't fill recycler - android

I have a problem with recycler, the problem is: I have AsyncTask which query data from my db, and then updating recycler by CursorLoader, but adapter doesn't fill recycler, Logs says that the data from db is successfully reading and then Adapter constructor successfully takes ArrayList with data, but that's all, logs says that adapter's methods doesn't call.
MainActivity :
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private SQLiteDatabase db;
private SimpleCursorLoader loader;
private MySimpleAdapter adapter;
private RecyclerView recycler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = (RecyclerView) findViewById(R.id.recycler);
new SimpleTask(SimpleTask.OPEN, null).execute();
}
private class SimpleTask extends AsyncTask<Void, Void, Void> {
public static final int INSERT = 0;
public static final int DELETE = 1;
public static final int OPEN = 2;
private int task;
private String name;
public SimpleTask(int task, String name) {
this.task = task;
this.name = name;
}
#Override
protected Void doInBackground(Void... params) {
switch (task) {
case INSERT :
ContentValues values = new ContentValues();
values.put(SimpleHelper.KEY_NAME, name);
db.insert(SimpleHelper.TABLE_NAME, null, values);
break;
case DELETE :
db.delete(SimpleHelper.TABLE_NAME, SimpleHelper.KEY_NAME + " = ? ", new String[]{name});
break;
case OPEN :
if (db == null) {
try {
db = new SimpleHelper(MainActivity.this).getWritableDatabase();
} catch (SQLiteException e) {
e.printStackTrace();
}
}
break;
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (loader == null) {
loader = new SimpleCursorLoader(MainActivity.this, db);
loader.setQueryParams(SimpleHelper.TABLE_NAME, new String[]{SimpleHelper.KEY_NAME},
null, null);
getSupportLoaderManager().initLoader(0, null, MainActivity.this);
}
getSupportLoaderManager().getLoader(0).forceLoad();
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return loader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.i("MyLog", "onLoadFinished cursor size is " + data.getCount());
List<String> items = new ArrayList<>();
data.moveToFirst();
do {
items.add(data.getString(0));
Log.i("MyLog", data.getString(0));
} while (data.moveToNext());
Log.i("MyLog", "onLoadFinished items size is " + items.size());
if (adapter == null) {
adapter = new MySimpleAdapter(items);
recycler.setAdapter(adapter);
} else {
adapter.updateAdapter(items);
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
private class MySimpleAdapter extends RecyclerView.Adapter<MySimpleAdapter.MyHolder> {
private List<String> items;
public MySimpleAdapter(List<String> items) {
Log.i("MyLog", "Constructor called with items size " + items.size());
this.items = items;
}
public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tvText;
public MyHolder(View itemView) {
super(itemView);
tvText = (TextView) itemView.findViewById(android.R.id.text1);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
new SimpleTask(SimpleTask.DELETE, tvText.getText().toString());
}
}
public void updateAdapter(List<String> items) {
this.items = items;
notifyDataSetChanged();
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i("MyLog", "onCreateViewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, null, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.tvText.setText(items.get(position));
Log.i("MyLog", "onBindViewHolder setText : " + items.get(position));
}
#Override
public int getItemCount() {
Log.d("MyLog", "getItemCount called with size : " + items.size());
return items.size();
}
}
SimpleCursorLoader :
public class SimpleCursorLoader extends CursorLoader {
private SQLiteDatabase db;
private String tableName;
private String[] columns;
public SimpleCursorLoader(Context context, SQLiteDatabase db) {
super(context);
this.db = db;
}
public void setQueryParams(String tableName, String[] columns, String selection, String[] selectionArgs) {
this.tableName = tableName;
this.columns = columns;
setSelection(selection);
setSelectionArgs(selectionArgs);
}
#Override
public Cursor loadInBackground() {
Cursor cursor = db.query(tableName, columns, getSelection(), getSelectionArgs(),
null, null, null);
return cursor;
}
DBHelper :
public class SimpleHelper extends SQLiteOpenHelper{
public static final String TABLE_NAME = "users";
public static final String KEY_NAME = "name";
public static final String KEY_ID = "_id";
private static final int DB_VERSION = 1;
private static final String DB_NAME = "SimpleDB";
public SimpleHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME + "("
+ KEY_ID + " integer primary key autoincrement, "
+ KEY_NAME + " text)");
for (int i = 0; i < 5; i ++) {
ContentValues values = new ContentValues();
values.put(KEY_NAME, "name" + i+1);
db.insert(TABLE_NAME, null, values);
Log.i("MyLog", "inserted");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Use this.
recycler.setLayoutManager(new LinearLayoutManager(this));
recycler.setHasFixedSize(true);
recycler.setNestedScrollingEnabled(false);

Related

SearchView doesn't work with RecyclerView & SQLite

I have a Fragment with a RecyclerView. users input data and they will store in a SQLite DataBase. i am trying to Search in the items of this RecyclerView but it does not work,
here is my Fragment :
public class FragmentOne extends Fragment {
private RecyclerView mDetailRecyclerView;
private DetailAdapter mAdapter;
private boolean mNumberVisible;
private SearchView sv;
private ArrayList<Detail> mDetails=new ArrayList<>();
private View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_one_layout,
container, false);
mDetailRecyclerView = (RecyclerView) view.findViewById(R.id.detail_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setReverseLayout(true); //This will reverse the data order but not scroll the RecyclerView to the last item
layoutManager.setStackFromEnd(true); //For keeping data order same and simply scrolling the RecyclerView to the last item
mDetailRecyclerView.setLayoutManager(layoutManager);
if (savedInstanceState != null) {
mNumberVisible =
savedInstanceState.getBoolean(SAVED_NUMBER_VISIBLE);
}
sv = (SearchView) view.findViewById(R.id.sv);
mAdapter = new DetailAdapter(mDetails);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit (String query) {
return false;
}
#Override
public boolean onQueryTextChange(String query) {
getDetailsSearch(query);
return false;
}
});
initViews();
updateUI();
return view;
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_NUMBER_VISIBLE, mNumberVisible);
}
..
..
private class DetailHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, View.OnLongClickListener {
private TextView mTitleTextView;
// private TextView mDateTextView;
private Detail mDetail;
private RatingBar mRatingBar;
public DetailHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_detail,
parent, false));
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
mTitleTextView = (TextView) itemView.findViewById(R.id.detail_title);
mRatingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
}
public void bind(Detail detail) {
mDetail = detail;
mTitleTextView.setText(mDetail.getTitle());
mRatingBar.setRating(mDetail.getRate());
}
#Override
public void onClick(View view) {
Intent intent = DetailPagerActivity.newIntent(getActivity(),
mDetail.getId());
startActivity(intent);
}
}
private class DetailAdapter extends RecyclerView.Adapter<DetailHolder> {
private List<Detail> mDetails;
private Detail mDetail;
public DetailAdapter(List<Detail> details) {
mDetails = details;
}
#Override
public DetailHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new DetailHolder(layoutInflater, parent);
}
#Override
public void onBindViewHolder(DetailHolder holder, int position) {
Detail detail = mDetails.get(position);
holder.bind(detail);
}
#Override
public int getItemCount() {
return mDetails.size();
}
public void setDetails(final List<Detail> details) {
mDetails = details;
}
..
..
}
public void initViews(){
mDetailRecyclerView.setAdapter(mAdapter);
initSwipe();
}
..
..
private void getDetailsSearch (String searchTerm) {
mDetails.clear();
DBAdapter db = new DBAdapter(getActivity());
db.openDB();
Detail p = null;
Cursor c = db.retrieve(searchTerm);
while (c.moveToNext()) {
String title = c.getString(2);
p = new Detail();
p.setTitle(title);
mDetails.add(p);
}
db.closeDB();
mDetailRecyclerView.setAdapter(mAdapter);
}
}
and this is my Database Adapter:
public class DBAdapter {
Context c;
SQLiteDatabase db;
DetailBaseHelper helper;
public DBAdapter (Context c) {
this.c = c;
helper = new DetailBaseHelper(c);
}
public void openDB() {
try {
db = helper.getWritableDatabase();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void closeDB() {
try {
helper.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public Cursor retrieve (String searchTerm) {
String[] columns = {
"_id",
"uuid",
"title",
"des",
"date",
"rate"
Cursor c = null;
if (searchTerm != null && searchTerm.length()>0) {
String sql ="SELECT * FROM " +DetailDbSchema.DetailTable.NAME+
" WHERE "+DetailDbSchema.DetailTable.Cols.TITLE+
" LIKE '%"+searchTerm+"%'";
c = db.rawQuery(sql, null);
return c;
}
c = db.query(DetailDbSchema.DetailTable.NAME, columns,
null, null, null, null, null);
return c;
}
}
and here is DataBase Helper:
public class DetailBaseHelper extends SQLiteOpenHelper{
private static final int VERSION = 1;
private static final String DATABASE_NAME = "detailBase.db";
public DetailBaseHelper (Context context) {
super(context, DATABASE_NAME, null, VERSION);
}
#Override
public void onCreate (SQLiteDatabase db) {
db.execSQL("create table " + DetailTable.NAME +
"(" +
" _id integer primary key autoincrement," +
DetailTable.Cols.UUID + ", " +
DetailTable.Cols.TITLE + ", " +
DetailTable.Cols.DES + ", " +
DetailTable.Cols.DATE + ", " +
DetailTable.Cols.RATE +
")"
);
}
#Override
public void onUpgrade (SQLiteDatabase db,
int oldVersion, int newVersion) {
}
}
here is the tutorial that i used for this,
I'll be appreciate if u have any idea for helping me.
I think that the main problem is here you're changing the adapter, but the new adapter was never modified by the data of the results, and also you have to notify your recycler that the data set changed. so
private void getDetailsSearch (String searchTerm) {
mDetails.clear();
/// the loop wiith the cursor
/// change the dataset
mAdapter = new DetailAdapter(mDetails);
mDetailRecyclerView.setAdapter(mAdapter);
/// tell the recycler there is a different data to display
mDetailRecyclerView.notifyDataSetChanged();
}

Drag and Drop RecyclerView Which is Populated from SQLiteDatabase

Info:
I have a RecyclerView, and I populate it with the ArrayList dataList inside the ListAdapter class. I get the data for dataList from the SQLiteDatabase table: TABLE_USERdETAIL in the DbHelper class. I'm trying to implement drag and drop re-organisation into the RecyclerView by using the SimpleItemTouchHelperCallback class; however, although I am now able to move the RecyclerView elements, the list doesn't re-sort or move; I'm only able to temporarily drag the list elements over each other, as shown in the image below, but it's meant to be permanently slotting the list elements into whichever position it's held:
I expect the problem to be within the ListAdapter class, inside the method onItemMove, but I don't know how to solve my issue.
Question: How do I make this drag and drop feature actually re-organise the RecyclerView data list?
Update 5: I have updated my current code for further assistance.
ListAdapter Class
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ListViewHolder> {
Context context;
List<UserData> dataList = new ArrayList<>();
LayoutInflater inflater;
Listener listener;
DbHelper dbHelper;
public interface Listener {
void nameToChnge(String name);
}
public ListAdapter(Context context, List<UserData> dataList1) {
this.context = context;
this.dataList = dataList1;
//this.listener= (Listener) context;
inflater = LayoutInflater.from(context);
}
#Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View convertView = inflater.inflate(R.layout.recylerview_one, parent, false);
ListViewHolder viewHolder = new ListViewHolder(convertView);
return viewHolder;
}
#Override
public void onBindViewHolder(ListViewHolder holder, final int position) {
holder.tv_name.setText(dataList.get(position).name);
holder.tv_quantity.setText(dataList.get(position).quantity);
holder.tv_description.setText(dataList.get(position).description + " ");
if(dataList.get(position).description.isEmpty()) {
holder.tv_description.setVisibility(View.GONE);
}
holder.relLayout.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
String s = dataList.get(position).id;
Integer stringo = Integer.parseInt(s);
Intent intent = new Intent(context, ItemEditActivity.class);
intent.putExtra("ItemNumber", stringo);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return dataList.size();
}
class ListViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
TextView tv_name, tv_quantity, tv_description;
RelativeLayout relLayout;
public ListViewHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.nameDisplay);
tv_quantity = (TextView) itemView.findViewById(R.id.quantityDisplay);
tv_description = (TextView) itemView.findViewById(R.id.descriptionDisplay);
relLayout = (RelativeLayout) itemView.findViewById(R.id.relLayout);
}
#Override
public void onItemSelected() {
Log.d("ListViewHolder", "item selected");
}
#Override
public void onItemClear() {
Log.d("ListViewHolder", "item clear");
for (int count = 0; count < dataList.size(); count++) {
UserData u = dataList.get(count);
u.setSort(count);
dbHelper.updateUserData(u);
}
notifyDataSetChanged();
}
}
public void onItemDismiss(int position) {
dataList.remove(position);
//dbHelper = DbHelper.getInstance(context);
//dbHelper.deleteRowItem(position + 1);
notifyItemRemoved(position);
}
//Collections.swap(dataList, fromPosition, toPosition);
//notifyItemMoved(fromPosition, toPosition);
public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(dataList, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(dataList, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
}
SimpleItemTouchHelperCallback Class
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ListAdapter mAdapter;
public SimpleItemTouchHelperCallback(ListAdapter adapter) {
mAdapter = adapter;
}
#Override
public boolean isLongPressDragEnabled() {return true; }
#Override
public boolean isItemViewSwipeEnabled() { return false; }
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
#Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// We only want the active item to change
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Let the view holder know that this item is being moved or dragged
Log.i("ADAPTER", "----DRAGGING----");
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemSelected();
}
}
super.onSelectedChanged(viewHolder, actionState);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
}
}
DbHelper Class
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "UserDatabase";
private static final int DATABASE_VERSION = 2;
private static DbHelper mDbHelper;
public static String TABLE_USERdETAIL = "userdetail";
private static final String _ID = "_id";
private static final String SORT_ID = "sort_id";
private static final String NAME = "name";
private static final String QUANTITY = "quantity";
private static final String WEIGHT = "weight";
private static final String WEIGHTTOTAL = "weighttotal";
private static final String VALUE = "value";
private static final String VALUETOTAL = "valuetotal";
private static final String DESCRIPTION = "description";
public static synchronized DbHelper getInstance(Context context) {
if (mDbHelper == null) {
mDbHelper = new DbHelper(context.getApplicationContext());
}
return mDbHelper;
}
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_USERDETAIL_TABLE = "CREATE TABLE " + TABLE_USERdETAIL +
"(" +
_ID + " INTEGER PRIMARY KEY , " +
SORT_ID + " INTEGER," +
NAME + " TEXT," +
QUANTITY + " INTEGER," +
WEIGHT + " INTEGER," +
WEIGHTTOTAL + " INTEGER," +
VALUE + " INTEGER," +
VALUETOTAL + " INTEGER," +
DESCRIPTION + " TEXT" +
")";
db.execSQL(CREATE_USERDETAIL_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion != newVersion) {
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + WEIGHT + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + WEIGHTTOTAL + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + VALUE + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + VALUETOTAL + " INTEGER DEFAULT 0");
}
}
/**
Insert a user detail into database
*/
public void insertUserDetail(UserData userData) {
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try {
ContentValues values = new ContentValues();
values.put(SORT_ID, userData.sort_id);
values.put(NAME, userData.name);
values.put(QUANTITY, userData.quantity);
values.put(WEIGHT, userData.weight);
values.put(WEIGHTTOTAL, userData.weighttotal);
values.put(VALUE, userData.value);
values.put(VALUETOTAL, userData.valuetotal);
values.put(DESCRIPTION, userData.description);
db.insertOrThrow(TABLE_USERdETAIL, null, values);
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}
public void updateUserDetail(int id, String v1, String v2, String v3, String v4, String v5, String v6, String v7){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(NAME, v1);
values.put(QUANTITY, v2);
values.put(DESCRIPTION, v3);
values.put(WEIGHT, v4);
values.put(WEIGHTTOTAL, v5);
values.put(VALUE, v6);
values.put(VALUETOTAL, v7);
db.update(TABLE_USERdETAIL, values, "_id="+id, null);
}
/**
fetch all data from UserTable
*/
public List<UserData> getAllUser() {
List<UserData> usersdetail = new ArrayList<>();
String USER_DETAIL_SELECT_QUERY = "SELECT * FROM " + TABLE_USERdETAIL + " ORDER BY " + SORT_ID + " COLLATE NOCASE;";
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(USER_DETAIL_SELECT_QUERY, null);
try {
if (cursor.moveToFirst()) {
do {
UserData userData = new UserData();
userData.id = cursor.getString(cursor.getColumnIndex(_ID));
userData.sort_id = cursor.getInt(cursor.getColumnIndex(SORT_ID));
userData.name = cursor.getString(cursor.getColumnIndex(NAME));
userData.quantity = "Quantity: " + cursor.getString(cursor.getColumnIndex(QUANTITY));
userData.weight = cursor.getString(cursor.getColumnIndex(WEIGHT));
userData.weighttotal = cursor.getString(cursor.getColumnIndex(WEIGHTTOTAL));
userData.value = cursor.getString(cursor.getColumnIndex(VALUE));
userData.valuetotal = cursor.getString(cursor.getColumnIndex(VALUETOTAL));
userData.description = cursor.getString(cursor.getColumnIndex(DESCRIPTION));
usersdetail.add(userData);
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return usersdetail;
}
/**
Delete single row from UserTable
*/
void deleteRow(String name) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
db.execSQL("delete from " + TABLE_USERdETAIL + " where name ='" + name + "'");
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}
void deleteRowItem(int id) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
db.execSQL("delete from " + TABLE_USERdETAIL + " where _id ='" + id + "'");
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}
public UserData getSingleUserDetail(String userId) {
SQLiteDatabase db = this.getWritableDatabase();
UserData userData = null;
//Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_USERdETAIL, null);
// this is the code to order the RecyclerView by _ID:
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_USERdETAIL + " WHERE " + _ID + "= ?", new String[]{userId});
try {
while (cursor.moveToNext()) {
userData = new UserData();
userData.name = cursor.getString(cursor.getColumnIndex(NAME));
userData.quantity = cursor.getString(cursor.getColumnIndex(QUANTITY));
userData.weight = cursor.getString(cursor.getColumnIndex(WEIGHT));
userData.weighttotal = cursor.getString(cursor.getColumnIndex(WEIGHTTOTAL));
userData.value = cursor.getString(cursor.getColumnIndex(VALUE));
userData.valuetotal = cursor.getString(cursor.getColumnIndex(VALUETOTAL));
userData.description = cursor.getString(cursor.getColumnIndex(DESCRIPTION));
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return userData;
}
public int getTotalWeight() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(WEIGHTTOTAL) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalWeight();
}
public int getTotalQuantity() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(QUANTITY) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalQuantity();
}
public int getTotalValue() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(VALUETOTAL) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalValue();
}
public int getMaxColumnData() {
SQLiteDatabase db = this.getWritableDatabase();
final SQLiteStatement stmt = db
.compileStatement("SELECT MAX(SORT_ID) FROM " + TABLE_USERdETAIL);
return (int) stmt.simpleQueryForLong();
}
public void updateUserData(UserData userData) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(NAME, userData.getName());
values.put(QUANTITY, userData.getQuantity());
values.put(DESCRIPTION, userData.getDescription());
values.put(WEIGHT, userData.getWeight());
values.put(WEIGHTTOTAL, userData.getWeighttotal());
values.put(VALUE, userData.getValue());
values.put(VALUETOTAL, userData.getValuetotal());
values.put(SORT_ID, userData.getSort());
Log.i("DBhelper", "USER UPDATED = " + userData.getName());
db.update(TABLE_USERdETAIL, values, _ID + "=?", new String[]{String.valueOf(userData.getId())});
}
}
UserData
import java.io.Serializable;
public class UserData implements Serializable {
String id, name, quantity, weight, weighttotal, value, valuetotal, description;
int sort_id;
public UserData() {
super();
}
public void setId(String id){
this.id= id;
}
public String getId(){
return id;
}
public void setSort(int sort){
this.sort_id= sort;
}
public int getSort(){
return sort_id;
}
public void setName(String name){
this.name= name;
}
public String getName(){
return name;
}
public void setDescription(String description){
this.description= description;
}
public String getDescription(){
return description;
}
public void setQuantity(String quantity){
this.quantity= quantity;
}
public String getQuantity(){
return quantity;
}
public void setWeight(String weight){
this.weight= weight;
}
public String getWeight(){
return weight;
}
public void setWeighttotal(String weighttotal){
this.weighttotal= weighttotal;
}
public String getWeighttotal(){
return weighttotal;
}
public void setValue(String value){
this.value= value;
}
public String getValue(){
return value;
}
public void setValuetotal(String valuetotal){
this.quantity= valuetotal;
}
public String getValuetotal(){
return quantity;
}
}
ItemTouchHelperViewHolder Class
public interface ItemTouchHelperViewHolder {
void onItemSelected();
void onItemClear();
}
MainActivity
public class MainActivity extends AppCompatActivity implements ListAdapter.Listener {
RecyclerView recyclerView;
DbHelper dbHelper;
ListAdapter adapter;
private ItemTouchHelper mItemTouchHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = DbHelper.getInstance(getApplicationContext());
recyclerView = (RecyclerView) findViewById(R.id.rv_contactlist);
adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ItemTouchHelper.Callback callback =
new SimpleItemTouchHelperCallback(adapter);
mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(recyclerView);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about_task:
Intent intentChangeActivity2 = new Intent(MainActivity.this, AboutActivity.class);
startActivity(intentChangeActivity2);
return true;
case R.id.encumbrance_task:
Intent intentChangeActivity = new Intent(MainActivity.this, EncumbranceActivity.class);
startActivity(intentChangeActivity);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onResume() {
super.onResume();
dbHelper = DbHelper.getInstance(getApplicationContext());
recyclerView = (RecyclerView) findViewById(R.id.rv_contactlist);
adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
public void nameToChnge(String name) {
dbHelper.deleteRow(name);
adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
Error log:
8-26 11:20:49.443 23533-23533/name.appE/AndroidRuntime: FATAL EXCEPTION: main
Process: name.app, PID: 23533
java.lang.NullPointerException: Attempt to invoke virtual method 'void name.app.DbHelper.updateUserData(name.app.UserData)' on a null object reference
at name.app.ListAdapter$ListViewHolder.onItemClear(ListAdapter.java:95)
at name.app.SimpleItemTouchHelperCallback.clearView(SimpleItemTouchHelperCallback.java:63)
at android.support.v7.widget.helper.ItemTouchHelper$3.onAnimationEnd(ItemTouchHelper.java:619)
at android.support.v4.animation.HoneycombMr1AnimatorCompatProvider$AnimatorListenerCompatWrapper.onAnimationEnd(HoneycombMr1AnimatorCompatProvider.java:115)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1149)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1309)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
at android.animation.AnimationHandler.-wrap2(AnimationHandler.java)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:869)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:616)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
I'm not sure that catching your problem but what i noticed (hope this helps):
in your onItemMove you are refactoring dataList by swapping items but adapter notifies only about general change.
guess the simplest way to move the item (and save animation) is to remove it and add again:
UserData item = dataList.remove(fromPosition);
dataList.add(i, toPossition);
notifyItemMoved(fromPosition, toPosition);
EDITED: Look at the complete example here
I tested your code and your OnItemMove method is working as expected.
Probably, you have problems to store the order in your database?
Here you have an example:
1- Create ItemTouchHelperViewHolder interface:
public interface ItemTouchHelperViewHolder {
void onItemSelected();
void onItemClear();
}
Now implement it in your ViewHolder class.
2- Go to SimpleItemTouchHelperCallback class and add this two methods:
#Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder instanceof ItemTouchHelperViewHolder) {
ItemTouchHelperViewHolder itemViewHolder =
(ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemSelected();
}
}
super.onSelectedChanged(viewHolder, actionState);
}
#Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
}
3- In OnItemClear (ViewHolder class) store the new order:
#Override
public void onItemClear() {
for (int count = 0; count < dataList.size(); count++) {
UserData u = dataList.get(count);
u.setOrder(count);
mDbHelper.updateOrder(u);
}
adapter.notifyDataSetChanged();
}
I am not sure about getting your problem. But I have implemented the same using the given code. This code doesn't use SQLite but it does perform drag and drop in recycler view with some textviews. You can have a look at my code:
MovieTouchHelper.java
public class MovieTouchHelper extends ItemTouchHelper.SimpleCallback {
private MovieAdapter mMovieAdapter;
public MovieTouchHelper(MovieAdapter movieAdapter){
super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
this.mMovieAdapter = movieAdapter;
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
mMovieAdapter.swap(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mMovieAdapter.remove(viewHolder.getAdapterPosition());
}
}
MovieAdapter.java
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
private Context mContext;
private List<Movie> mMovies;
public MovieAdapter(Context context, List<Movie> movies){
this.mContext = context;
this.mMovies = movies;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(mContext).inflate(R.layout.list_item_movie, parent, false));
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bindMovie(mMovies.get(position));
}
#Override
public int getItemCount() {
return mMovies.size();
}
public void remove(int position) {
mMovies.remove(position);
notifyItemRemoved(position);
}
public void swap(int firstPosition, int secondPosition){
Collections.swap(mMovies, firstPosition, secondPosition);
notifyItemMoved(firstPosition, secondPosition);
}
public class ViewHolder extends RecyclerView.ViewHolder{
public final TextView movieNameTextView;
public ViewHolder(View view){
super(view);
movieNameTextView = (TextView) view.findViewById(R.id.movie_name);
}
public void bindMovie(Movie movie){
this.movieNameTextView.setText(movie.getName());
}
}
}
You can edit the code according to your need.
Hope this helps!
In onItemMove you don't need to make all the swap because the method will be called every time the selected item change its position with the item next to it. So every iteration in the for will be taking care on each call to the method.
you should move the item from the old position (dragged.getAdapterPosition()) to new position (target.getAdapterPosition()) in your adapter and also call RecyclerView.Adapter.notifyItemMoved(int, int).
Your onItemMove should look something like this:
#Override
public void onItemMove(int fromPosition, int toPosition) {
Collections.swap(mItems, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}

recyclerView doesn't show the 'real' data for my list items

I have implemented a recyclerView and a SQLite database to save/retrieve data for the recylerview, but the data I get on the recyclerView is not the data that should show. The recyclerView worked as it should without the SQLite db.
When the plus sign is clicked, a dialog will popup with editext fields, where the user can type the information:
Here is the DialogFragment class where the user shall write their information:
public class DialogAdd extends DialogFragment {
private Button okButton;
private EditText name, quantity, location, normalPrice, offerPrice;
private List<ShopListItem> shopListItem;
private Context context;
DatabaseHelper dbHelper;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DatabaseHelper(getContext());
shopListItem = new ArrayList<>();
context = getActivity();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.add_productdialog,container, false);
getDialog().setCanceledOnTouchOutside(false);
getDialog().setTitle("Add to shoplist");
name = (EditText) rootView.findViewById(R.id.dialog_productname);
quantity = (EditText) rootView.findViewById(R.id.dialog_qantity);
location = (EditText) rootView.findViewById(R.id.dialog_location);
normalPrice = (EditText) rootView.findViewById(R.id.dialog_normalPrice);
offerPrice = (EditText) rootView.findViewById(R.id.dialog_offerPrice);
okButton = (Button) rootView.findViewById(R.id.dialog_okButton);
okButton.getBackground().setColorFilter(Color.parseColor("#2fbd4b"), PorterDuff.Mode.MULTIPLY);
okButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (name.getText().toString().isEmpty()) {
Toast.makeText(context, "You must add a name", Toast.LENGTH_LONG).show();
} else {
dbHelper.insertData(name.toString() ,quantity.toString(),location.toString(),normalPrice.toString(),offerPrice.toString());
getDialog().dismiss();
}
}
});
return rootView;
}
This is the mainActivity class where I create the recylerview, adapters and Database:
public class MainActivity extends AppCompatActivity{
private ImageButton addbutton;
private DialogAdd dialogAdd;
public static RecyclerView recyclerView;
private List<ShopListItem> shopListItems;
private SQLiteDatabase db;
private Cursor cursor;
private DatabaseHelper databaseHelper;
private ShoplistAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shoppinglist_mainactivity);
databaseHelper = new DatabaseHelper(this);
addbutton = (ImageButton) findViewById(R.id.addbtn);
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialogAdd = new DialogAdd();
dialogAdd.show(getSupportFragmentManager(), "addDialog");
}
});
//RecyclerView
recyclerView = (RecyclerView)findViewById(R.id.rv_shoppinglist);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(App.getAppContex());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
initializeData();
adapter = new ShoplistAdapter(shopListItems);
recyclerView.setAdapter(adapter);
}
private void initializeData(){
shopListItems = new ArrayList<>();
Cursor resultset = databaseHelper.getAllData();
if (resultset.moveToFirst()){
while(!resultset.isAfterLast()){
shopListItems.add(new ShopListItem(resultset.getString(1), resultset.getString(2), resultset.getString(3), resultset.getString(4), resultset.getString(5)));
resultset.moveToNext();
}
}
resultset.close();
shopListItems.add(new ShopListItem("Potato", "2 KG", "MALL", "7 kr", ""));
}
This class is where the database is defined:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME ="dbshoplist.db";
public static final String TABLE_NAME ="product_table";
public static final String COL_ID = "ID";
public static final String COL_NAME ="NAME";
public static final String COL_QTY ="QUANTITY";
public static final String COL_LOCATION ="LOCATION";
public static final String COL_PRICE1 ="PRICE1";
public static final String COL_PRICE2 ="PRICE2";
/*
This constructor creates the database
*/
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT,QUANTITY TEXT,LOCATION TEXT,PRICE1 TEXT,PRICE2 TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean insertData(String name, String qty, String location, String price1, String price2){
SQLiteDatabase db = this.getWritableDatabase();
// content value is a row, and we fill it with the put();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_NAME, name);
contentValues.put(COL_QTY, qty);
contentValues.put(COL_LOCATION, location);
contentValues.put(COL_PRICE1, price1);
contentValues.put(COL_PRICE2, price2);
long result = db.insert(TABLE_NAME, null,contentValues);
if(result == -1) {
return false;
}else{
return true;
}
}
public Cursor getAllData(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursorResults = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return cursorResults;
}
My recyclerView adapter class:
public class ShoplistAdapter extends RecyclerView.Adapter<ShoplistAdapter.ViewHolder>{
List<ShopListItem> shopListItems;
public ShoplistAdapter(List<ShopListItem> shopListItems) {
this.shopListItems = shopListItems;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View shoplist_itemView = inflater.inflate(R.layout.shop_list_item, parent, false);
ViewHolder viewHolder = new ViewHolder(shoplist_itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.location.setText(shopListItems.get(position).location.toString());
holder.normalPrice.setText(shopListItems.get(position).normalprice.toString());
holder.offerPrice.setText(shopListItems.get(position).offerprice.toString());
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(shopListItems.get(position).quantity + " " + shopListItems.get(position).name);
holder.productname.setText(stringBuilder);
if(!shopListItems.get(position).offerprice.toString().isEmpty()){
holder.normalPrice.setPaintFlags(holder.normalPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
if(shopListItems.get(position).normalprice.isEmpty()){
holder.normalPrice.setVisibility(View.GONE);
}
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked == true){
holder.productname.setPaintFlags(holder.productname.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
holder.productname.setTextColor(Color.parseColor("#40000000"));
}else{
holder.productname.setPaintFlags(0 | Paint.ANTI_ALIAS_FLAG);
holder.productname.setTextColor(Color.BLACK);
}
}
});
}
#Override
public int getItemCount() {
return shopListItems.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
private CheckBox checkBox;
private TextView productname, quantity, location, normalPrice, offerPrice;
private ImageButton edit_icon, delete_icon;
public ViewHolder(View itemView) {
super(itemView);
productname = (TextView)itemView.findViewById(R.id.product_name);
location = (TextView)itemView.findViewById(R.id.product_location);
normalPrice = (TextView)itemView.findViewById(R.id.product_price);
offerPrice = (TextView)itemView.findViewById(R.id.product_offer_price);
edit_icon = (ImageButton)itemView.findViewById(R.id.editShopItem_Icon);
delete_icon = (ImageButton)itemView.findViewById(R.id.shopitem_delete_icon);
checkBox = (CheckBox) itemView.findViewById(R.id.bought_checkbox);
}
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
This is happening because you're calling the toString() method of fields of the ShopListItem object: shopListItems.get(position).location.toString().
Instead, create getter methods for the fields of your ShopListItem class, e.g.
public getLocation() {
return location;
}
and just call these to get the data.

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);
}

Categories

Resources