Jump to content

Custom ListView où les CheckBox cochées ne sont pas considérées comme tel


Recommended Posts

Bonjour à tous,

je me suis récemment décidé à me replonger dans le code afin de développer une application pour une probable future tablette sous Androïd. Jusque là tout va bien, sauf que le développement ça fait un paquet de temps que j'en ai pas fait du coup je suis bien rouillé et en plus découvre Androïd, là ça se gâte :P

J'ai pas mal avancé avec des datas codées en dur dans le code source mais maintenant je tente d'alimenter mon programme avec des informations plus dynamiques. Je coince maintenant depuis 2 jours sur une problématique un peu pénible :

1. Je lance une activité dans mon appli (pas la main). OK

2. Une AlertDialog qui contient ma ListView s'ouvre au lancement de l'activité puis Parse un fichier XML pour en ressortir des infos que je rentre dans un Array<Object> qui va bien et remplit la ListView avec son contenu. OK

3. La ListView est "inflate" à partir d'une RelativeLayout qui comprend une CheckBox dont le label est personnalisé avec le nom de mes Objets récupérés dans le XML puis une EditText qui permettra de choisir le nombre de "vilain" à sélectionner.

Capture.PNG

J'ai tout fait en custom (Layout, Adapters, Listeners...) en m'aidant beaucoup sur quelques tutos (dont celui-là http://mickael-lt.developpez.com/tutoriels/android/personnaliser-listview/#LIII).

Quand je clique sur le nom ou la box ça Enable ou Disable l'EditText de la ligne et je suis bien content d'y être arrivé.

Mais la conclusion est moins bonne. Je veux que lorsque l'on clique sur OK, on vérifie pour chaque ligne Checked que la valeur du champ EditText ne soit pas nulle.

Seulement quand je veux les récupérer les petits pépères de la liste, et quand je fais un getClickedItemsPositions, le tableau qui m'est renvoyé n'a rien à TRUE... en gros la checkbox est bien considérée comme cliquée mais pas l'item de la ListView :/

La CheckBox est "prioritaire" ? Ca ne marche pas sur une RelativeLayout ? Est-ce que vous auriez des idées ?

Merci !

Link to comment
Share on other sites

Hello,

rien de trouvé de mieux hier soir.

Je rajoute qqes bouts de codes source.

L'activité d'où part l'AlertDialog :

public class Fight extends Activity implements EnemyAdapterListener {
private int nbEnemy;
private ArrayList<String> enemyNames = new ArrayList<String>();
private ListView listEnemysFromXml;
private View initBar;
private ArrayList<Character> enemys = new ArrayList<Character>();
private Character fighters[];
private int id_activePlayer;
private boolean checked[] = null;

public void onCreate(Bundle icicle) {
	super.onCreate(icicle);
	setContentView(R.layout.screenfight);

	requestEnemy();
}

private void requestEnemy() {

	LayoutInflater factory = LayoutInflater.from(this);
	final View alertDialogView = factory.inflate(R.layout.dlgdefturn, null);
	AlertDialog.Builder adb = new AlertDialog.Builder(this);
	adb.setView(alertDialogView);
	adb.setTitle("Choisissez les ennemis");
	adb.setIcon(android.R.drawable.ic_dialog_alert);

	// Récupération des vilains
	getEnemyFromXml();

	// On définit la listview sur la fenêtre qui va bien
	listEnemysFromXml = (ListView) alertDialogView.findViewById(R.id.get_Enemy);
	EnemyAdapter mon_adap = new EnemyAdapter(getBaseContext(), enemys);
	mon_adap.addListener(this);
	listEnemysFromXml.setAdapter(mon_adap);
	listEnemysFromXml.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);



	//On affecte un bouton "OK" à notre AlertDialog et on lui affecte un évènement
	adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int which) {
		 SparseBooleanArray count = listEnemysFromXml.getCheckedItemPositions();

		 if (count != null && count.size() != 0) {
		  for (int i=0;i<count.size();i++) {
		   int index = count.keyAt(i);
		   Toast.makeText(getBaseContext(), "Index du vilain"+Integer.toString(index), Toast.LENGTH_SHORT).show();
		   // on copie le joueur "checked" dans le nouveau tableau des joueurs actifs
		  }
		 }
		 if (count == null)
		  Toast.makeText(getBaseContext(), "On click sur OK mais liste nulle", Toast.LENGTH_SHORT).show();
		 if (count.size() == 0)
		  Toast.makeText(getBaseContext(), "On click sur OK mais rien n'est coché", Toast.LENGTH_SHORT).show();

		 //initializeInitBar();
	  } });
	 //On crée un bouton "Annuler" à notre AlertDialog et on lui affecte un évènement
	adb.setNegativeButton("Annuler", new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int which) {
		 //Lorsque l'on cliquera sur annuler on quittera l'application
		 finish();
	  } });
	adb.show();
}

private void getEnemyFromXml() {
//blabla
}

private void initializeInitBar() {
 //  génération liste des combattants
}

private void initializeAttacker() {
//blabla
}
public void onClickNom(Character item, int position) {
 // TODO Auto-generated method stub

 if (listEnemysFromXml.isItemChecked(position)) {
  checked[position] = true;
  Toast.makeText(getBaseContext(), "c'est coché", Toast.LENGTH_SHORT).show();
 }
 else {
  checked[position] = false;
  Toast.makeText(getBaseContext(), "c'est décoché", Toast.LENGTH_SHORT).show();
 }
}
}

Puis le custom adapter :

package W40k.Fighter.Manager;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RelativeLayout;
public class EnemyAdapter extends BaseAdapter {
// Une liste de Characters
private ArrayList<Character> mListC;
//Le contexte dans lequel est présent notre adapter
private Context mContext;
//Un mécanisme pour gérer l'affichage graphique depuis un layout XML
private LayoutInflater mInflater;

public EnemyAdapter(Context context, ArrayList<Character> aListC) {
 // TODO Auto-generated constructor stub
 mContext = context;
 mListC = aListC;
 mInflater = LayoutInflater.from(mContext);
}
public int getCount() {
 // TODO Auto-generated method stub
 return mListC.size();
}
public Object getItem(int arg0) {
 // TODO Auto-generated method stub
 return mListC.get(arg0);
}
public long getItemId(int arg0) {
 // TODO Auto-generated method stub
 return arg0;
}

private class Holder {
 CheckBox leNom;
 EditText leNbr;
}
public View getView(int position, View convertView, ViewGroup parent) {
final Holder hold;

//(1) : Réutilisation des layouts
if (convertView == null) {
 hold = new Holder();
 //Initialisation de notre item à partir du  layout XML "select_enemy.xml"
 convertView = (RelativeLayout)mInflater.inflate(R.layout.select_enemy, null);
 hold.leNom = (CheckBox)convertView.findViewById(R.id.checkbox);
 hold.leNbr = (EditText)convertView.findViewById(R.id.nbr_Enemy);
 convertView.setTag(hold);
 convertView.setClickable(true);
} else {
 hold = (Holder) convertView.getTag();
}

//(3) : Renseignement des valeurs	  
hold.leNom.setText(mListC.get(position).getName());
hold.leNbr.setText("1");
hold.leNbr.setEnabled(false);
//------------ Début de l'ajout -------
//On mémorise la position de la "Personne" dans le composant textview
hold.leNom.setTag(position);
hold.leNbr.setTag(position);

//On ajoute un listener
  hold.leNom.setOnClickListener(new OnClickListener() {
  public void onClick(View v) {
 //Lorsque l'on clique sur le nom, on récupère la position de "l'Enemy"
 Integer position = (Integer)v.getTag();

 // on des/active l'EditText dans le cas où les ennemis sont cochés ou pas
 if (hold.leNom.isChecked()) {
  hold.leNbr.setEnabled(true);
 }
 if (!hold.leNom.isChecked()) {
  hold.leNbr.setEnabled(false);
 }

 //On prévient les listeners qu'il y a eu un clic sur le TextView "enemy_Nom".
 sendListener(mListC.get(position), position);

}

  });

//On retourne l'item créé.
return convertView;
}

/**
 * Interface pour écouter les évènements sur le nom d'une personne d'une CheckBox
 */
public interface EnemyAdapterListener {
 public void onClickNom(Character item, int position);
}

//Contient la liste des listeners
private ArrayList<EnemyAdapterListener> mListListener = new ArrayList<EnemyAdapterListener>();
/**
 * Pour ajouter un listener sur notre adapter
 */
public void addListener(EnemyAdapterListener aListener) {
 mListListener.add(aListener);
}

private void sendListener(Character item, int position) {
 for(int i = mListListener.size()-1; i >= 0; i--) {
  mListListener.get(i).onClickNom(item, position);
 }
}
}

Link to comment
Share on other sites

  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...