2011-09-26 8 views
0

나는, 나는 당신이 날 도울 수 있기를 바랍니다이 알아 내려고 지난 몇 일 struggeling 봤는데 ...안드로이드 ViewHolder 목록보기 끝장 얻을 원인

나는이 목록을 보여줍니다 활동

:

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

목록에서 항목을 클릭,이 코드는 옵션 편집을 위해 선수를 제거 "삭제"에 "편집"로 대화를 보여주는 실행되고이 같은 listadapter을 설정하여 플레이어

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

답변

0

발견 솔루션 ...

은 기본적으로 내가 커서를 다시 초기화 나는 데이터베이스에 데이터를 변경할 때 ListAdapter 플러스가 다시 한번 ListView에에 ListAdapter를 할당합니다.

이것이 왜 nessasary인지 알 수는 없지만 notifyDataSetChanged(), notifyDataSetInvalidated() 및 내가 시도한 다른 모든 작업이 작동하지 않아서 이제이 접근법을 사용하고 있습니다. : O)

  • Zyb3r
+0

어떤'Cursor.requery() ''에 대한? –

관련 문제