2011-04-05 3 views
1

Hé les gars, j'ai une liste qui utilise une disposition de ligne personnalisée. La mise en page se compose de 2 étiquettes, d'une imageview et d'une case à cocher.Afficher les événements dans une ligne ListView

J'essaie de déclencher un écouteur lorsque la case à cocher est cochée. L'écouteur que j'ai écrit fonctionne, mais au lieu de tirer pour la ligne individuelle, il se déclenche pour chaque ligne de la liste. Comme si je coche la case dans ma première rangée, la boîte de dialogue s'ouvrira et fonctionnera correctement, mais les 2e, 3e et 4e rangées se déclencheront également.

Voici la zone appropriée de mon code:

public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if (v == null) { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.row, null); 
    } 
    final item o = items.get(position); 
    if (o != null) { 
     TextView tt = (TextView) v.findViewById(R.id.name); 
     TextView bt = (TextView) v.findViewById(R.id.game); 
     CheckBox cb = (CheckBox) v.findViewById(R.id.caught); 
     if (cb != null && o.getStatus()) { 
      cb.setChecked(true); 
     } else { 
      cb.setChecked(false); 
     } 
     if (tt != null) { 
      tt.setText(o.getName()); 
     } 
     if (bt != null && o.getStatus()) { 
      bt.setText("Game: " + o.getGame()); 
     } 

     cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton buttonView, 
        boolean isChecked) { 
       o.setStatus(isChecked); 
       if (isChecked) { 
       AlertDialog.Builder builder2 = new AlertDialog.Builder(
         context); 
       builder2.setTitle("What game are we talkin gabout?"); 
       builder2.setItems(Checklist.GAMES, 
         new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, 
            int item) { 
           Toast.makeText(context, 
             Checklist.GAMES[item], 
             Toast.LENGTH_SHORT).show(); 
           o.setGame(Checklist.GAMES[item]); 
           o.setStatus(true); 
           me.notifyDataSetChanged(); 
          } 
         }); 
       builder2.show(); 
       } else { 
        o.setGame(""); 
        o.setStatus(false); 
        me.notifyDataSetChanged(); 
       } 
      } 
     }); 
    } 
    return v; 

} 

est-il un endroit plus approprié pour créer mon écouteur pour la case à cocher?

+0

Voulez-vous dire que onCheckedChanged() est appelée pour chaque rangée - après un seul clic? – DJC

+0

Oui, peu importe quelle ligne, ils vont tous appeler. – Vizirship

Répondre

1

Je pense que ce n'est pas une bonne solution d'assigner un nouveau OnCheckedChangeListener chaque fois qu'une vue est mise à jour avec des valeurs. Il vaudrait mieux ne placer qu'une seule fois un auditeur à une vue au point où cette nouvelle vue est inflatet. Vous pouvez rendre o-Object disponible pour l'auditeur en le plaçant dans la balise cb (setTag (..)). Notez que l'événement onCheckedChanged se déclenche également lorsque vous définissez l'état CB par cb.setChecked().

par exemple:

CheckBox cb = null; 
if (v == null) { 
    LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
      Context.LAYOUT_INFLATER_SERVICE); 
    v = vi.inflate(R.layout.row, null); 
    cb = (CheckBox) v.findViewById(R.id.caught); 
    // set a listener 
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
      item o = (item) buttonView.getTag(); 
      // show your dialog 
     } 
    }); 
} 

item o = items.get(position); 
if (o != null) { 
    TextView tt = (TextView) v.findViewById(R.id.name); 
    TextView bt = (TextView) v.findViewById(R.id.game); 
    cb = (CheckBox) v.findViewById(R.id.caught); 
    cb.setTag(o); 
    // set checked state & text 
    // ... 
} 
Questions connexes