【问题标题】:Android RecyclerView is not handling SQLite changesAndroid RecyclerView 不处理 SQLite 更改
【发布时间】:2021-03-30 21:29:08
【问题描述】:

我已经开始创建一个简单的应用程序,其中一个活动具有 RecyclerView 用于添加玩家。一开始我将所有数据存储为变量,RecyclerView 的数据列表也存储为列表,一切正常。然后我尝试用 SQLite 替换变量用法并发现了问题。当我打开此活动时,会显示所有留在 SQLite DB 中的玩家,并且在我按下按钮删除它们后,它们会成功地从视图和 DB 中删除。凉爽的!但是当我尝试添加播放器时,记录会出现在 DB 中,但 UI 中没有任何变化。

部分活动代码:

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

PlayerAdapter 类的一部分:

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

    }
}

以及 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;
}

在将数据插入数据库后,我也尝试调用adapter.notifyDataSetChanged()(和其他通知方法),但没有帮助。 有人知道怎么解决吗?

【问题讨论】:

    标签: android android-recyclerview android-sqlite android-adapter


    【解决方案1】:

    插入后必须查询数据库

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

    【讨论】:

    • 这是否意味着我需要始终存储玩家列表的可变副本并且仅调用 db.getAllPlayers() 是不够的?
    • 我已经尝试过使用它 - 问题仍然是一样的,所以这没有帮助
    • 有趣的事情,但现在我已经开始工作了...可能您的解决方案有效,但 Android Studio 有它自己的滞后...无论如何,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-29
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多