0

I'm building a to do list app. I'm learning SQLite databases and I'm trying to save the user input into an SQLite database table and also display it in my recyclerview list. When I did this without the SQLite, it worked so the problem is obviously with my implementation of the database table. The app is supposed to add the data into the list per button click:

addingItems.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(itemsInput.getText() != null){
                    items.add(new todo(itemsInput.getText().toString()));
                    itemsInput.setText("");
                }else {
                    Toast.makeText(MainActivity.this, "Please enter something to do", Toast.LENGTH_SHORT).show();
                }
                itemAdapter.notifyDataSetChanged();
            }
        });

But now it does not do that. The app does not crash. The problem is just that my list shows absolutely no data. The following are my relevant Java files:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private SQLiteDatabase sqLiteDatabase;
    private List<todo> items = new ArrayList<>();
    private ItemAdapter itemAdapter;
    private RecyclerView listItemsRecyclerView;
    EditText itemsInput;
    Button addingItems;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        itemsInput = (EditText)findViewById(R.id.to_do_editText);
        addingItems = (Button)findViewById(R.id.to_do_btn);
        listItemsRecyclerView = (RecyclerView) findViewById(R.id.to_do_list);

        ToDoListDatabaseHelper databaseHelper = new ToDoListDatabaseHelper(this);
        sqLiteDatabase = databaseHelper.getWritableDatabase();

        items = new ArrayList<>();
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
        listItemsRecyclerView.setLayoutManager(layoutManager);
        listItemsRecyclerView.setItemAnimator(new DefaultItemAnimator());;
        itemAdapter = new ItemAdapter(items);
        listItemsRecyclerView.setAdapter(itemAdapter);

        new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
                ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

            }
        });

        addingItems.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(itemsInput.getText().length() > 0){
                    addNewToDo(itemsInput.getText().toString());
                    itemsInput.setText("");
                }else {
                    Toast.makeText(MainActivity.this, "Please enter something to do", Toast.LENGTH_SHORT).show();
                }
                itemAdapter.notifyDataSetChanged();
            }
        });
    }

    private List<todo> getAllToDos(){
        Cursor cursor = sqLiteDatabase.rawQuery("select * from " + ToDoContract.ToDoEntry.TABLE_NAME, new String[]{});
        List<todo> todos = new ArrayList<>();
        todo todo;
        if (cursor != null && cursor.getCount() > 0) {
            if (cursor.moveToFirst()) {
                do {

                    String name = cursor.getString(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_NAME));
                    int priority = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_PRIORITY));
                    int timestamp = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_TIMESTAMP));
                    todo = new todo(name);
                    todos.add(todo);
                } while (cursor.moveToNext());
            }
            cursor.close();
        }
        return todos;
    }

    private long addNewToDo(String name){
        ContentValues cv = new ContentValues();
        cv.put(ToDoContract.ToDoEntry.COLUMN_TODO_NAME, name);
        return sqLiteDatabase.insert(ToDoContract.ToDoEntry.TABLE_NAME, null, cv);
    }
}

My custom adapter:

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

    private List<todo> todoList;

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView toDoTextView;

        public ViewHolder(View itemView) {
            super(itemView);

            toDoTextView = (TextView) itemView.findViewById(R.id.to_do);
        }
    }

    public ItemAdapter(List<todo> todoList) {
        this.todoList = todoList;
    }

    @Override
    public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
        todo toDo = todoList.get(position);
        holder.toDoTextView.setText(toDo.getToDo());
    }


    @Override
    public int getItemCount() {
        return todoList.size();
    }
}

I ran unit tests on my SQLite classes so there is no issue with them.

Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78
  • You're adding an item into your list but your adapter does not know about that change. Try logging the `name` variable inside `onBindViewHolder` and add items inside the actual database tables not inside a list. – KudzieChase Jul 28 '17 at 01:32
  • your codition not correct. `editText.getText() != null` - not work correctly. Please, change condition to `editText.getText().length() > 0` or `!editText.getText().toString().equals("")` –  Jul 28 '17 at 05:34
  • By the way. https://stackoverflow.com/questions/26517855/using-the-recyclerview-with-a-database/27732748#27732748 – OneCricketeer Jul 28 '17 at 05:49

2 Answers2

1

You should not use Cursor as the data source for Adapter.Why don't you just fetch data(todos) from cursor then put the data into Adapter? As we known, cursor should be CLOSED at the end of data reading. You should code like that:

private List<todo> getAllToDos() {
    Cursor cursor = sqLiteDatabase.rawQuery("select * from " + ToDoContract.ToDoEntry.TABLE_NAME, new String[]{});
    List<todo> todos = new ArrayList<>();
    todo todo;
    if (cursor != null && cursor.getCount() > 0) {
        if (cursor.moveToFirst()) {
            do {

                String name = cursor.getString(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_NAME));
                int priority = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_PRIORITY));
                int timestamp = cursor.getInt(cursor.getColumnIndex(ToDoContract.ToDoEntry.COLUMN_TODO_TIMESTAMP));
                todo = new todo(name);
                todo.setPriority(priority);
                todo.setTimestamp(timestamp);
                todos.add(todo);
            } while (cursor.moveToNext());
        }
        cursor.close();
    }
    return todos;
}

And your ItemAdapter will be simpler.

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

    private List<todo> todoList;

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView toDoTextView;

        public ViewHolder(View itemView) {
            super(itemView);

            toDoTextView = (TextView) itemView.findViewById(R.id.to_do);
        }
    }

    public ItemAdapter(List<todo> todoList) {
        this.todoList = todoList;
    }

    @Override
    public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
        todo toDo = todoList.get(position);
        holder.toDoTextView.setText(toDo.getToDo());
    }


    @Override
    public int getItemCount() {
        return todoList.size();
    }
}

There are some other changes.But I think you can fix them as I told you above.If you have any other question about that, please tell me.I will help you.

Relish Wang
  • 385
  • 1
  • 8
0

Try this

public void update()
{
    cursor.requery();
    notifyDataSetChanged();
}