Подтвердить что ты не робот

OnClickListener не работает для первого элемента в GridView

У меня возникла проблема с созданием календаря на основе GridView. Вот сетка:

GridView Calendar

Предполагается, что это календарь, заполненный событиями, поэтому у меня есть адаптер, реализующий OnClickListener, и я установил этот слушатель для каждой кнопки в календаре. Он отлично работает для каждой кнопки EXCEPT первой (в этом случае номер 30). Когда я нажимаю на него, это просто не работает, но когда я нажимаю на другую кнопку после того, как попытаюсь щелкнуть по первому, он выполняет щелчок первой, прежде чем выполнить щелчок для другой кнопки.

Я просмотрел около 10 страниц соответствующих вопросов и не нашел кого-то, кто имел эту проблему. Помогите пожалуйста!

Как уже было сказано, вот функция getView моего кода:

    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();
        }
    }

OnClick получает вызов для каждой ячейки сетки EXCEPT первый в верхнем левом углу

4b9b3361

Ответ 1

Хорошо, я нашел решение. Проблема заключалась в следующих строках:

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();
}

При размещении кнопки gridCell там, так или иначе, он смешивает прослушиватель кликов первой позиции в адаптере. Я закончил тем, что исправил это, просто установив держателя на каждом проходе, вместо того, чтобы получать его по тегу (что лучше для производительности, но хорошо). Спасибо всем за помощь.

Ответ 2

У меня была та же проблема. Сохранение setLayoutParams внутри предложения if (view == null). Вы не должны приносить в жертву вид переустановки таким образом.

like:

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

Я не знаю, почему это работает, но это сработало для меня. Я также заметил, что все коды, относящиеся к одной и той же проблеме в stackoverflow, также использовали setLayoutParams вне предложения if. Это мой первый раз, поэтому я не знаю, могу ли я опубликовать это везде. Надеюсь, что это помогло.

Источник: много следов и ошибок.

Ответ 3

Используйте OnClickListener() в своей деятельности после .setAdapter(), а не в классе адаптера.

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();
    }
});

Ответ 4

Для чего это стоит, у меня была и эта проблема (первая ячейка в gridview с задержкой onclick).

В моем случае я использовал (слегка настроенные) gridviews с динамическими наборами изображений, которые я бы сделал видимым/ушел и перерисовал gridview. Все изображения, подготовленные заранее и сохраненные в адаптере.

Вначале я использовал notifyDataSetChanged() на адаптере, но это привело к проблеме с задержкой нажатия для первой ячейки всякий раз, когда набор был обновлен. Я изменил просто аннулирование gridview, и теперь все в порядке. Имейте в виду, что все мои представления уже созданы и сохранены в адаптере, это просто метод getview, который проверяет, какие из них действительно видны.

Ответ 5

У меня была такая же проблема. Событие клика по первому элементу было значительно задержано. Я уже использовал notifyDataSetInvalidated(). Использование onItemClickListener() решило проблему, хотя я до сих пор не понимаю, почему слушатель onClick для отдельных элементов имеет такое поведение.

Ответ 6

Установите onItemClickListener в объект GridView вместо установки onClickListeners на каждой кнопке.

И я нашел еще один вопрос с вашей проблемой здесь. Может быть, Bounty?

Ответ 7

Пожалуйста, обратитесь к этой ссылке , она установила цвет фона сетки на TRANSPARENT. Это может помочь вам.

Ответ 8

Потратив так много дней, установите параметры макета следующим образом.

if (view == null) {

        // call the user implementation
        view = mInflater.inflate(mViewId, null);
        holder = createHolder(view);
        // we set the holder as tag
        view.setTag(holder);

        rlMainCell = (RelativeLayout)view.findViewById(R.id.rlMainCell);
        rlMainCell.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) view.getResources().getDimension(R.dimen._128sdp)));

    } else {
        // get holder back...much faster than inflate
        holder = (ViewHolder) view.getTag();
    }

это работает абсолютно нормально для меня