OnClickListener ne fonctionne pas pour le premier article dans GridView

j'ai un problème avec la création d'un calendrier GridView. Voici la grille:

GridView Calendar

c'est supposé être un calendrier peuplé d'événements, donc j'ai mon adaptateur implémenter OnClickListener et j'ai réglé cet écouteur pour chaque bouton du calendrier. Il fonctionne parfaitement pour chaque simple bouton sauf le premier(dans ce cas numéro 30). Quand je clique ça ne marche pas, mais quand je cliquez sur un autre bouton après j'ai essayé de cliquer sur le premier, il effectue le clic pour le premier, juste avant d'effectuer le clic pour le bouton.

j'ai scanné environ 10 pages de questions pertinentes et n'ai pas trouvé quelqu'un pour avoir ce problème. De l'aide s'il vous plaît!

comme demandé, voici la fonction getView de mon code:

    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        ViewHolder holder;
        if (row == null)
        {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
            holder.gridCell = (Button) row.findViewById(R.id.calendar_day_gridcell);
            holder.multiDayEvent = (EventLengthView)row.findViewById(R.id.eventLengthView);
        }
        else{
            holder = (ViewHolder)row.getTag();
        }

        int calendarGridHeight = (calendarView.getHeight()-5)/(getCount()/7);
        AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                android.view.ViewGroup.LayoutParams.FILL_PARENT,
                calendarGridHeight);
        row.setLayoutParams(params);

        //Change the background drawable depending on the position in the calendar
        if ((position+1) % 7 == 0){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_row));
        }
        if (getCount() - position < 8){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_column));
        }
        if (position == getCount()-1){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end));
        }
        holder.gridCell.setOnClickListener(this);

        holder.gridCell.setTag(null);//clear tags

        // ACCOUNT FOR SPACING
        String[] day_color = list.get(position).split("-");
        int theday = Integer.parseInt(day_color[0]);
        int themonth = Integer.parseInt(day_color[2]);
        int theyear = Integer.parseInt(day_color[3]);
        String date = DateFormat.format("dd/M/yy", new Date(theyear,themonth,theday)).toString();
        if ((!eventsMap.isEmpty()) && (eventsMap != null))
        {
            if (eventsMap.containsKey(date))
            {
                holder.multiDayEvent.SetMeasure(calendarView.getWidth()/7, calendarGridHeight);

                holder.multiDayEvent.setVisibility(View.VISIBLE);
                //holder.singleDayEvent.setVisibility(View.VISIBLE);
                Event event = (Event) eventsMap.get(date);
                holder.multiDayEvent.AddEvent(event);
                holder.gridCell.setTag(event);
            }
            else{
                //holder.singleDayEvent.setVisibility(View.GONE);
                holder.multiDayEvent.setVisibility(View.GONE);
            }
        }

        // Set the Day GridCell
        holder.gridCell.setText(Integer.toString(theday));

        if (day_color[1].equals("GREY"))
        {
            holder.gridCell.setTextColor(Color.GRAY);
        }
        if (day_color[1].equals("WHITE"))
        {
            holder.gridCell.setTextColor(Color.WHITE);
        }
        if (day_color[1].equals("BLUE"))
        {
            holder.gridCell.setTextColor(Color.BLUE);
        }

        row.setTag(holder);
        return row;
    }

    public class ViewHolder{
        Button gridCell;
        ImageView singleDayEvent;
        EventLengthView multiDayEvent;
    }

    public void onClick(View view)
    {
        if (view.getTag() != null){
            Event event = (Event)view.getTag();

            eventListView.setAdapter(new EventListAdapter(CalendarScreen.this, event));
            eventListViewLayout.setVisibility(View.VISIBLE);
            eventListViewLayout.startAnimation(fadeIn);
        }
        else if (eventListViewLayout.getVisibility() == View.VISIBLE){
            onBackPressed();
        }
    }

l'onClick est appelé pour chaque gridcell sauf le premier dans le coin supérieur gauche

21
demandé sur Valentin 2012-08-02 17:16:35

7 réponses

Ok, j'ai trouvé la solution. Le problème était ces lignes:

ViewHolder holder;
if (convertView == null)
{
    holder = new ViewHolder();
    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
    holder.gridCell = (Button) convertView.findViewById(R.id.calendar_day_gridcell_button);
    holder.multiDayEvent = (EventLengthView) convertView.findViewById(R.id.eventLengthView);
    convertView.setTag(holder);
}
else {
    holder = (ViewHolder) convertView.getTag();
}

lors de la mise en place du bouton gridCell, d'une certaine manière, il mélange l'écouteur de clic de la première position dans l'adaptateur. J'ai fini par le réparer en installant simplement le support dans chaque passe, au lieu de l'obtenir par tag (ce qui est mieux pour la performance, mais oh bien). Merci à tous pour l'aide.

8
répondu Rory Kelly 2014-12-05 14:04:07

j'ai eu le même problème.Garder les paramètres de setlayout à l'intérieur de la clause if(view == null) a fonctionné. Vous n'avez pas à sacrifier la vue de recyclage.

comme :

 if(row == null){
   // inflate row
   row.setLayoutParams(params);
   //remaining code
 }else{
    holder = (ViewHolder)row.getTag();
 }
 // everything else

Je ne sais pas pourquoi ça marche mais ça a marché pour moi. J'ai également remarqué que tous les codes concernant le même problème dans stackoverflow avaient également utilisé desparames setlayout en dehors de la clause if. C'est ma première fois donc je ne sais pas si je peux poster partout. Espérons qu'il a aidé .

Source: beaucoup de traces et d'erreurs .

13
répondu BruceWayne 2014-03-24 13:23:12

utilisez votre OnClickListener () dans votre activité après .méthode setAdapter() , pas dans votre classe d'adaptateur.

gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
    Toast.makeText(GridViewActivity.this, "" + position,
             Toast.LENGTH_SHORT).show();
    }
});
8
répondu Rashid 2014-01-15 19:01:16

pour ce que ça vaut, j'ai aussi eu ce problème (première cellule dans le gridview ayant retardé onclick).

dans mon cas, j'utilisais un gridviews (légèrement personnalisé) avec des ensembles dynamiques d'imageviews que je rendrais visible/parti et redessinerais le gridview. Tous les imageviews ont été préparés à l'avance et stockés dans l'adaptateur.

au départ, j'ai utilisé notifyDataSetChanged () sur l'adaptateur mais cela a entraîné un problème de clic retardé pour la première cellule chaque fois que l'ensemble a été mis à jour. J'ai changé pour invalider le gridview et maintenant tout va bien. Gardez à l'esprit que toutes mes vues sont déjà créées et stockées dans l'adaptateur, c'est juste la méthode getview qui vérifie lesquelles sont vraiment visibles.

1
répondu pgrav 2013-12-04 16:49:03

j'ai eu ce même problème. L'événement de clic sur le premier élément a été considérablement retardée. J'utilisais déjà notifyDataSetInvalidated (). en utilisant onItemClickListener () résolu la question , bien que je ne comprends toujours pas pourquoi l'auditeur onClick sur les articles individuels a ce comportement.

1
répondu danp 2014-02-08 16:49:54

définit onItemClickListener sur L'objet GridView au lieu de définir onClickListeners sur chaque bouton.

et j'ai trouvé une autre question avec votre problème ici . Bounty peut-être?

0
répondu cosmincalistru 2017-05-23 11:54:10

s'il vous Plaît se référer à cette lien , il a mis en gridview couleur d'arrière-plan TRANSPARENT. Il peut vous aider.

0
répondu Archa 2017-05-23 12:25:24