I have started to create a simple app where one of activities has RecyclerView for adding players. In the beginning I was storing all the data as variables and data list for RecyclerView was also store as List and everything worked fine. Then I've tried to replace variable usage with SQLite and found the problem. When I open this activity, all the players left in SQLite DB are displayed and after I'm pressing a button to delete them, they are successfully deleted from view and from DB. Cool! But when I'm trying to add a player, then record appears in DB but nothing changes in UI.
Part of activity code:
public class SetupActivity extends AppCompatActivity {
RecyclerView recyclerView;
PlayerAdapter adapter;
PlayersDbHelper db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup);
ImageButton button = findViewById(R.id.button);
nameInput = findViewById(R.id.nameInput);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
db = new PlayersDbHelper(this);
button.setOnClickListener(view -> {
String name = Objects.requireNonNull(nameInput.getText()).toString().trim();
db.insertPlayer(name);
});
adapter = new PlayerAdapter(this, db.getAllPlayers());
recyclerView.setAdapter(adapter);
}
}
Part of PlayerAdapter class:
public class PlayerAdapter extends RecyclerView.Adapter<PlayerAdapter.PlayerViewHolder> {
Context context;
List<Player> playerList;
PlayersDbHelper db;
public PlayerAdapter(Context context, List<Player> playerList) {
this.context = context;
this.playerList = playerList;
}
@NonNull
@Override
public PlayerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_layout, parent, false);
return new PlayerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull PlayerViewHolder holder, int position) {
Player player = playerList.get(position);
holder.playerName.setText(player.getName());
holder.trashButton.setImageDrawable(ContextCompat.getDrawable(context, player.getTrash()));
holder.position = position;
}
@Override
public int getItemCount() {
return playerList.size();
}
class PlayerViewHolder extends RecyclerView.ViewHolder {
TextView playerName;
ImageButton trashButton;
int position;
public PlayerViewHolder(@NonNull View itemView) {
super(itemView);
playerName = itemView.findViewById(R.id.playerName);
trashButton = itemView.findViewById(R.id.trashButton);
db = new PlayersDbHelper(context);
trashButton.setOnClickListener(view -> {
db.removePlayer(playerList.get(position));
playerList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, playerList.size());
});
}
}
}
And part of PlayerDbHelper:
public long insertPlayer(String name, String gender) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(PLAYERS_COLUMN_NAME, name);
return db.insert(PLAYERS_TABLE_NAME, null, contentValues);
}
public boolean removePlayer(Player player) {
SQLiteDatabase db = this.getWritableDatabase();
long result = db.delete(PLAYERS_TABLE_NAME, PLAYERS_COLUMN_ID + "=" + player.getId(), null);
return result > 0;
}
I have also tried to call adapter.notifyDataSetChanged()
(and other notify methods) after inserting data to DB but it didn't help.
Does anybody know how to solve this?
You have to query your db after insert
playerList = db.getAllPlayers();
adapter = new PlayerAdapter(this, playerList);
recyclerView.setAdapter(adapter);
button.setOnClickListener(view -> {
String name = Objects.requireNonNull(nameInput.getText()).toString().trim();
long result = db.insertPlayer(name);
if (result != -1) {
playerList = b.getAllPlayers();
adapter.notifyDataSetChanged();
}
});