2013-04-30 4 views
0

J'ai un ListView personnalisé avec un button, donc quand je clique sur un button il devrait disparaître et il disparaît mais quand je défile vers le bas et reviens le button réapparaît et un autre button disparaît. Comment puis-je faire la button spécifique Disparaître en cliquant .... Je suis en utilisant ce codeComment définir la visibilité d'un bouton dans un ListView personnalisé?

holder.checkbox = (Button) view.findViewById(R.id.checkBox1); 

holder.checkbox.setOnClickListener(new View.OnClickListener() { 

@Override 
public void onClick(View v) { 
    holder.checkbox.setVisibility(View.INVISIBLE); 
+0

Avez-vous obtenu votre solution? Si vous l'avez obtenu à partir de n'importe quelle réponse, acceptez-la sinon postez votre réponse. Si vous acceptez une réponse, cela aidera les autres et votre réputation augmentera également. – Ankit

+0

je defenitely mais je dint obtenir une bonne solution peut être toutes les réponses fonctionne mais je ne suis pas capable de comprendre lequel cocher ... – Saad

Répondre

2

En ListView lorsqu'un élément sort de l'écran, pour une efficacité ListView détruit l'élément et lors du défilement de cet élément il le recrée en appelant la méthode getView() de l'adaptateur, donc vous devez garder un tableau ayant un booléen pour l'état du bouton qui sera par défaut vrai pour visible et getView() vous venez de mettre une vérification en obtenant la valeur booléenne de l'état à partir du tableau booléen qui si vrai alors l'élément est visible sinon l'élément est invisible. Donc, quand vous disparaissez un élément, vous devez définir le statut de l'élément également faux. Je suppose que c'est le code dans votre getView() et vous avez déjà défini votre tableau de boolean avec la même longueur que les éléments de ListView et la valeur true avec le nom "yourButtonStatusBooleanArray" puis les modifications suivantes fonctionneront pour vous.

holder.checkbox = (Button) view.findViewById(R.id.checkBox1); 

if(!yourButtonStatusBooleanArray[position]) 
{ 
holder.checkbox.setVisibility(View.INVISIBLE); 
} 
holder.checkbox.setOnClickListener(new View.OnClickListener() { 

@Override 
public void onClick(View v) { 
holder.checkbox.setVisibility(View.INVISIBLE); 
yourButtonStatusBooleanArray[position]=false; 
+0

comment puis-je faire cela ... sry im nouveau en programmation ... – Saad

+0

j'ai édité mon réponse .. s'il vous plaît vérifier le code –

+0

vous voulez dire "Boolean yourButtonStatusBooleanArray = true" ?? – Saad

1

Essayez d'ajouter holder.checkbox.setVisibility(View.VISIBLE); après la déclaration de bouton

+0

il est un peu de travail mais quand je défiler vers le bas et revenir le bouton j'ai cliqué sur réapparaître ... – Saad

+0

C'est à cause des ressources de réutilisation de ListView. Essayez de regarder cette réponse, ils m'ont donné pour une question similaire: http://stackoverflow.com/a/15900881/1006156 – Mangusto

1

Ceci est dû au recyclage des vues. Ce que vous devez faire est de maintenir un tableau de dire booléens et chaque fois qu'un bouton est cliqué, basculez le booléen correspondant. Ensuite, dans votre getview, vérifiez la position du tableau booléen correspondant et définissez l'état du bouton.

pour plus de détails reffer ce lien

check box in listview not working properly

exemple ci-dessus est case à cocher modifier votre code.

+0

Je n'ai pas de case à cocher, j'ai un bouton, donc ça marchera encore ?? – Saad

+0

yup. Vous devrez juste vérifier l'état du bouton cliqué. cela n'a pas d'importance plutôt c'est la case à cocher ou le bouton –

+0

juste ajouter les lignes dans votre code qui est marqué comme "nouveau" dans ce lien –

1

Le problème est que la vue de la ligne est réutilisée et que, par conséquent, après le défilement, la vue de ligne peut afficher le bouton avec l'état d'une ligne différente. Vous pouvez résoudre ce problème en définissant explicitement la visibilité de votre bouton à l'initialisation de la vue. Donc, vous devez vous rappeler l'état de la rangée quelque part, par exemple. dans votre objet de données ou dans un tableau qui conserve la trace des éléments déjà sélectionnés.

holder.checkbox.setVisibility(dataObject.getVisibilityState()); 

EDIT Réponse à commenter, ici d'avoir des blocs de code

vous devez implémenter la méthode vous-même, le code était juste un exemple comment une méthode personnalisée pourrait être utilisé. Donc, vous pourriez faire quelque chose comme ça en vous classe d'article:

public class Item { 
private int visibility; 
... other attributes of your item 

public int getVisibilityState(){ 
    return visibility; 
} 

public void setVisible(){ 
    visibility = View.VISIBLE; 
} 

public void setInvisible(){ 
    visibility = View.INVISIBLE; 
} 
} 
+0

j'obtiens une erreur "La méthode getVisibilityState() est indéfinie pour le type Liste " – Saad

+0

vous devez implémenter la méthode vous-même, le code était juste un exemple comment une méthode personnalisée pourrait être utilisée. Donc, vous pouvez faire quelque chose comme ça dans votre article Classe: 'public class Item { private int visibility; ... autres attributs de votre article public int getVisibilityState() { retour visibilité; Public void setVisible() { visibility = View.VISIBLE; } Public void setInvisible() { visibility = View.INVISIBLE; } } ' – Sven

1

Vous devez implémenter cette méthode dans votre ListAdapter qui est appelé à chaque fois que votre vue de la ligne passe de hors-écran pour l'écran en raison de la utilisateur faisant défiler la liste. La vue transmise à votre méthode getView peut en fait être utilisée pour afficher des données pour une ligne totalement différente. En effet, les objets sont recyclés. Si vous disposez de données sur 1 000 lignes mais que seules 8 vues sont affichées à l'écran, le système crée 8 objets Afficher pour vos lignes, et non 1 000.

Si votre classe implémente ListAdapter vous pouvez remplacer la méthode getView comme suit:

public class MyClass implements ListAdapter { 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

View rowView = convertView; 

//Create a view for this row if none exists yet 
if (rowView == null) { 
    LayoutInflater inflater = (LayoutInflater) _context 
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    rowView = inflater.inflate(R.layout.YOUR_ROW_LAYOUT, parent, false); 

//make the button go away if it should not be visible 
if (buttonShouldBeNotVisible(convertView)) { //Your code should determine this 
    convertView.checkbox.setVisibility(View.INVISIBLE); 
    //Use View.GONE to make it take up no space 
} 
return convertView 

}}

1

Les vues sont recyclés dans le listview. Vous devrez enregistrer l'état du bouton dans une sorte de structure de données et le définir dans les adaptateurs getView(int, View, ViewGroup).

private HashMap<Integer, Boolean> mButtonMap = new HashMap<Integer, Boolean>(); 

[...] 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View retVal; 

    // Do all your stuff with each row 



    if (!mButtonMap.containsKey(new Integer(position))) { 
     button.setVisibility(View.VISIBLE); 
    } 
    else { 
     button.setVisibility(View.INVISIBLE); 
    } 
    button.setTag(""+position); 
    return retVal; 
} 

//In your onClickListener 
    onClick(View v) { 
     [...] 
     int position = Integer.parseInt((String) v.getTag()); 
     mButtonMap.put(position, true); 
     button.setVisibility(View.INVISIBLE); 
    } 
+0

il y a une petite erreur" La méthode Integer (int) est indéfinie pour le type ListRowAdapter ", comment puis-je résoudre ce ?? – Saad

+0

Peut être un «nouveau» manqué. J'ai mis à jour la réponse. – mach

+0

04-30 09: 14: 44.463: E/AndroidRuntime (4214): java.lang.ClassCastException: java.lang.Integer ne peut pas être converti en java.lang.String 04-30 09: 14: 44.463: E/AndroidRuntime (4214): \t à com.envesage.ListRowAdapter $ 1.onClick (ListRowAdapter.java:341) – Saad

1

Vous pouvez faire quelque chose comme ceci:

public View getView(int position, View convertView, ViewGroup parent) { 
     View vi = convertView; 
     ViewHolder holder; 
     if (convertView == null) { 
      vi = inflater.inflate(R.layout.grid_adapter, null); 
      holder = new ViewHolder(); 
      holder.checkbox = (Button) view.findViewById(R.id.checkBox1); 
      holder.checkbox.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        if (arg0.getTag().equals("0")) { 
         arg0.setVisibility(View.INVISIBLE); 
         arg0.setTag("1"); 
        } 
        notifyDataSetChanged(); 
       } 
      }); 

      vi.setTag(holder); 
     } else 
      holder = (ViewHolder)vi.getTag(); 

     try { 

      if (holder.checkbox.getTag().equals("1")) { 
       holder.checkbox.setVisibility(View.INVISIBLE); 
      } else { 
       holder.checkbox.setVisibility(View.VISIBLE); 
      } 

     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return vi; 
    } 
Questions connexes