0

我这几天一直在努力解决这个问题,希望您能帮助我...

我有一个活动,通过设置这样的列表适配器来显示玩家列表:

PlayerCursorAdapter playerAdapter = new PlayerCursorAdapter(this,
                                         R.layout.players_row, c, columns, to);
setListAdapter(playerAdapter);

单击列表中的项目时,将执行此代码,显示一个对话框,其中包含用于编辑和删除玩家的“编辑”和“删除”选项:

private class OnPlayerItemClickListener implements OnItemClickListener {
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long rowId) {
            Toast.makeText(view.getContext(),
                    "Clicked Item [" + position + "], rowId [" + rowId + "]",
                    Toast.LENGTH_SHORT).show();

            // Prepare Dialog with "Edit" and "Delete" option
            final CharSequence[] choices = {
                    view.getContext().getString(R.string.buttonEdit),
                    view.getContext().getString(R.string.buttonDelete) };

            AlertDialog.Builder builder = new AlertDialog.Builder(
                    view.getContext());
            builder.setTitle(R.string.title_edit_delete_player);
            builder.setItems(choices, new EditOrDeleteDialogOnClickListener(
                    view, rowId));

            AlertDialog alert = builder.create();

            // Show Dialog
            alert.show();
        }

根据您的选择(编辑或删除播放器),将执行以下侦听器:

private class EditOrDeleteDialogOnClickListener implements
        DialogInterface.OnClickListener {

    private View view;
    private long rowId;

    public EditOrDeleteDialogOnClickListener(View view, long rowId) {
        this.view = view;
        this.rowId = rowId;
    }

    public void onClick(DialogInterface dialog, int item) {
        if (item == 0) {
            // Edit
            showDialog(PlayGameActivity.DIALOG_EDIT_PLAYER_ID);
        } else if (item == 1) {
            // Delete from database
            DatabaseHelper databaseHelper = new DatabaseHelper(
                    view.getContext());
            databaseHelper.deletePlayer(rowId);

            // Requery to update view.
            ((PlayerCursorAdapter) getListAdapter()).getCursor().requery();

            Toast.makeText(
                    view.getContext(),
                    view.getContext().getString(
                            R.string.message_player_removed)
                            + " " + rowId, Toast.LENGTH_SHORT).show();

        }
    }
}

适配器的代码在这里:

public class PlayerCursorAdapter extends SimpleCursorAdapter {

    private LayoutInflater layoutInflater;
    private int layout;

    public PlayerCursorAdapter(Context context,
            int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);
        this.layout = layout;
        layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        Cursor c = getCursor();
        View view = layoutInflater.inflate(layout, parent, false);

        // Get Data
        int nameCol = c.getColumnIndex(Player.COLUMN_PLAYER_NAME);
        String name = c.getString(nameCol);
        int gamesPlayedCol = c.getColumnIndex(Player.COLUMN_GAMES_PLAYED);
        String gamesPlayed = c.getString(gamesPlayedCol);
        int gamesWonCol = c.getColumnIndex(Player.COLUMN_GAMES_WON);
        String gamesWon = c.getString(gamesWonCol);

        // Set data on fields
        TextView topText = (TextView) view.findViewById(R.id.topText);
        if (name != null)
            topText.setText(name);

        TextView bottomText = (TextView) view.findViewById(R.id.bottomText);
        if (gamesPlayed != null && gamesWon != null)
            bottomText.setText(view.getContext().getString(
                    R.string.info_played_won)
                    + gamesPlayed + "/" + gamesWon);

        CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkBox);

        // Set up PlayerViewHolder
        PlayerViewHolder playerViewHolder = new PlayerViewHolder();
        playerViewHolder.playerName = name;
        playerViewHolder.gamesPlayed = gamesPlayed;
        playerViewHolder.gamesWon = gamesWon;
        playerViewHolder.isChecked = checkBox.isChecked();
        view.setTag(playerViewHolder);
        return view;
    }

    private class PlayerViewHolder {
        String playerName;
        String gamesPlayed;
        String gamesWon;
        boolean isChecked;
    }

    @Override
    public void bindView(View view, Context context, Cursor c) {
        PlayerViewHolder playerViewHolder = (PlayerViewHolder) view.getTag();

        TextView topText = (TextView) view.findViewById(R.id.topText);
        topText.setText(playerViewHolder.playerName);

        TextView bottomText = (TextView) view.findViewById(R.id.bottomText);
        bottomText.setText(view.getContext()
                .getString(R.string.info_played_won)
                + playerViewHolder.gamesPlayed
                + "/"
                + playerViewHolder.gamesWon);

        CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkBox);
        checkBox.setChecked(playerViewHolder.isChecked);
    }
}

现在的问题是,在删除列表中的一些玩家之后,列表就搞砸了,例如。它显示了与实际可用的不同的东西。

我已经做了一些实验,如果我停止在 bindView 中使用 PlayerViewHolder 而是从光标读取文本并将其直接分配给文本字段,那么它就可以工作......所以问题是,为什么我的 ViewHolder 搞砸了???

任何帮助将不胜感激!

谢谢!

  • Zyb3r
4

1 回答 1

0

找到了解决方案...

基本上,当我更改数据库中的数据时,我重新初始化 Cursor 和 ListAdapter 并重新将 ListAdapter 分配给 ListView。

我不完全确定为什么这是必要的,但 notifyDataSetChanged()、notifyDataSetInvalidated() 和我尝试过的所有其他事情都不起作用,所以现在我正在使用这种方法。:o)

  • Zyb3r
于 2011-09-28T07:57:56.910 回答