2017-07-29 3 views
0

Informations générales:Boutons gridview ne répondant pas à onClickListener

Je suis obligé de créer un jeu SOS. J'ai décidé d'implémenter une vue de grille avec une grille 7x7 de SOSButtons (Button extension AppCompatButton).


Problème:

Après avoir appelé setOnClickListener() dans mon SOSButton classe, je pense voir un onClickListener de quelque sorte à être attaché à mon bouton, mais il n'y a rien.

Lors de l'exécution de l'application, il n'a aucun problème et affiche parfaitement. Lorsque vous cliquez sur un bouton de la grille, aucun écouteur n'est déclenché.

Lorsque vous cliquez sur un autre bouton en dehors de la grille, il se déclenche comme prévu.

Note: Je vois cela en définissant un point d'arrêt après la setOnClickListener() la ligne, et afficher l'objet SOSButton "mListeners = null"

Note 2: J'ai essayé de supprimer tous les unnecessaries et utiliser un simple Button objet, avec un onClickListener() comme indiqué ci-dessous, mais sans succès:

Button button = new Button(this); 
button.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     Toast.makeText(MainActivity.this, "click occured from main avtivity delcaration", Toast.LENGTH_SHORT).show(); 
     Button b = (Button) view; 
     String s = b.getText().toString(); 
     switch (s){ 
      case "S" : { 
       b.setText("O"); 
       break; 
      } 
      case "O" : { 
       b.setText(""); 
       break; 
      } 
      case "" : { 
       b.setText("S"); 
       break; 
      } 
     } 
    } 
}); 
list.add(button); 

J'ai essayé:

  • SOSButton avec onClickListener ensemble dans Button constructeur
  • SOSButton avec onClickListener ensemble dans le constructeur Button et GridView.setOnItemClickListener
  • SOSButton avec seulement GridView.setOnItemClickListener
  • Button avec onClickListener ensemble dans Button constructeur
  • Button avec onClickListener ensemble i n Button constructeur et GridView.setOnItemClickListener
  • Button avec seulement GridView.setOnItemClickListener

Aucune de ces feu tout auditeur. Les seuls écouteurs qui tiraient étaient ceux des boutons PAS dans la grille.


Plus d'info:

SOSButton.java

package wrap302.nmu.task1_sos; 

import android.content.Context; 
import android.support.v7.widget.AppCompatButton; 
import android.view.View; 

public class SOSButton extends AppCompatButton { 

    private SO_Select so_select; 

    public SOSButton(Context context) { 
     super(context); 
     so_select = SO_Select.None; 
     OnClickListener onClickListener = new OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       switch (so_select) { 
        case None: { 
         so_select = SO_Select.S; 
         break; 
        } 
        case S: { 
         so_select = SO_Select.O; 
         break; 
        } 
        case O: { 
         so_select = SO_Select.None; 
         break; 
        } 
       } 
       SOSButton.this.update(); 
      } 
     }; 
     setOnClickListener(onClickListener); 
     update(); 
    } 

    private void update(){ 
     setText(so_select.toString()); 
    } 

    @Override 
    public String toString() { 
     return "SOSButton{" + 
       "so_select=" + so_select.toString() + 
       '}'; 
    } 
} 

SO_Select enum:

package wrap302.nmu.task1_sos; 

public enum SO_Select { 
    None(""), 
    S("S"), 
    O("O"); 

    private String state; 

    SO_Select(String state) { 
     this.state = state; 
    } 

    @Override 
    public String toString() { 
     return state; 
    } 
} 

interface SOSButtonMatch:

package wrap302.nmu.task1_sos; 

import android.widget.Button; 

interface SOSButtonMatch { 
    /** 
    * Interface to check 3 buttons' text and return true if text follows a sequence specified 
    * 
    * @param b1 Start button 
    * @param b2 Middle button 
    * @param b3 End button 
    * @return Boolean 
    */ 
    boolean check(Button b1, Button b2, Button b3); 
} 

SOS_Adapter pour la grille:

package wrap302.nmu.task1_sos; 

import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 

import java.util.List; 

public class SOS_Adapter<T> extends ArrayAdapter<T>{ 

    private int resourceId; 
    private Context mContext; 
    private List<T> items; 

    public SOS_Adapter(Context context, int resource, List<T> objects) { 
     super(context, resource, objects); 
     this.mContext = context; 
     this.items = objects; 
     this.resourceId = resource; 
    } 

    @Override 
    public View getView(int i, View view, ViewGroup viewGroup) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View v = inflater.inflate(resourceId, viewGroup, false); 
     v.setTag(getItem(i)); 
     Button b = v.findViewById(R.id.sosButton); 
     b.setText(((SOSButton)getItem(i)).getText()); 
     return b; //runs twice 
    } 
} 

code MainActivity:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    initGui(); 
} 

/** 
* Initialize gui objects 
*/ 
private void initGui() { 
    btnDone = (Button) findViewById(R.id.btnDone); 
    btnExit = (Button) findViewById(R.id.btnExit); 
    btnReset = (Button) findViewById(R.id.btnReset); 
    grid = (GridView) findViewById(R.id.grid); 
    lblGridPosOpen = (TextView) findViewById(R.id.lblGridPosOpen); 
    lblP1_Score = (TextView) findViewById(R.id.lblP1_Score); 
    lblP2_Score = (TextView) findViewById(R.id.lblP2_Score); 
    lblPTurn = (TextView) findViewById(R.id.lblPTurn); 

    createAdapter(); 
    grid.setAdapter(sos_adapter); 

    OnItemClickListener clickListener = new OnItemClickListener() { //runs twice 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
      Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show(); 
      /*SO_Select so_select = SO_Select.None; 
      switch (so_select) { 
       case None: { 
        so_select = SO_Select.S; 
        break; 
       } 
       case S: { 
        so_select = SO_Select.O; 
        break; 
       } 
       case O: { 
        so_select = SO_Select.None; 
        break; 
       } 
      } 
      Object itemAtPosition = adapterView.getItemAtPosition(i); 
      SOSButton b = ((SOSButton) itemAtPosition); 
      b.setText(so_select.toString());*/ 
     } 
    }; 
//  grid.setOnItemClickListener(clickListener); 
    Toast.makeText(this, "displaying", Toast.LENGTH_SHORT).show(); 

} 

private void createAdapter() { 
    List<SOSButton> sosButtons = generateButtons(GRID_SIZE); 
    sos_adapter = new SOS_Adapter(this, R.layout.sosbutton,sosButtons); 
} 

private List<SOSButton> generateButtons(int grid_size) { 
    List<SOSButton> l = new ArrayList<>(); 
    for (int i = 0; i < grid_size; i++) { 
     SOSButton sosButton = new SOSButton(this); 
     sosButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Toast.makeText(MainActivity.this, "click occured from main avtivity delcaration", Toast.LENGTH_SHORT).show(); 
      } 
     }); 
     l.add(sosButton); 
    } 
    return l; 

} 

Répondre

0

bien, j'ai trouvé le solution après un peu plus de googling.

Obtenir le bouton pour répondre à un événement de clic alors que l'adaptateur est pas aussi simple que l'ajout d'un auditeur sur le bouton lui-même.

Dans le SOS_Adapter, le getView() est le lieu d'ajouter l'auditeur.

Cela se fait simplement en ajoutant:

 b.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Button b = (Button) view; 
      String s = b.getText().toString(); 
      switch (s){ 
       case "S" : { 
        b.setText("O"); 
        break; 
       } 
       case "O" : { 
        b.setText(""); 
        break; 
       } 
       case "" : { 
        b.setText("S"); 
        break; 
       } 
      } 
     } 
    }); 

juste avant le return

Puis une réponse recieves durement gagné à son contact.

Quelqu'un peut-il expliquer pourquoi cela doit être fait dans un beat-around-the-bush façon?

+0

Désolé, je ne peux pas expliquer pourquoi il doit être fait de cette façon. Heureux que vous étiez en mesure de résoudre votre problème cependant. Pourriez-vous accepter cette réponse il est évident que cette question a reçu une réponse? – Gary99