0

私はこれを理解しようとしてここ数日苦労してきました。あなたが私を助けてくれることを願っています...

次のように listadapter を設定して、プレイヤーのリストを表示するアクティビティがあります。

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 の使用をやめ、代わりにカーソルからテキストを読み取ってテキスト フィールドに直接割り当てると、うまくいきます... ???

どんな助けでも大歓迎です!

ありがとう!

  • Zyb3r
4

1 に答える 1

0

解決策を見つけました...

基本的に、データベース内のデータを変更すると、Cursor と ListAdapter を再初期化し、さらに ListAdapter を ListView に再度割り当てます。

なぜこれが必要なのか完全にはわかりませんが、notifyDataSetChanged()、notifyDataSetInvalidated()、および私が試した他のすべてのことはうまくいかなかったので、今はこのアプローチを使用しています. :o)

  • Zyb3r
于 2011-09-28T07:57:56.910 に答える