Intereting Posts
Разработка Android – «ошибка отсутствия темы» в eclipse ide для макетов xml-файлов Android прослушивает сообщения из серверного сокета Управление перезагрузкой активности Android после остановки процесса Странное поведение updateViewLayout Две панели действий (снизу и вверх) одновременно? Как выбрать видео из галереи и получить реальный путь? Поделиться в Facebook в android (как твиттер) Получение ArrayIndex из Bounds Исключение при добавлении новых элементов в список при прокрутке Отказ от разрешения Android, если другое приложение не установлено первым Интерпретация многоуровневой трассировки производительности (Eclipse / Android) Как использовать googletest для тестирования кода на C ++, который вызывает java на android? Запуск тестов автоматизации пользовательского интерфейса с помощью градиента без удаления Просмотр списка Android исчезает после поворота экрана AS, вынуждающий использовать инструменты разработки Android SDK 25.0.0. Редактирование средств сборки SDK (23.0.3) слишком мало для проекта Идеальный способ отменить выполнение AsyncTask

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

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

Календарь GridView

Предполагается, что это календарь, заполненный событиями, поэтому у меня есть адаптер, реализующий OnClickListener, и я установил этот слушатель для каждой кнопки в календаре. Он отлично работает для каждой отдельной кнопки ЗА ИСКЛЮЧЕНИЕМ первой (в этом случае номер 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 получает вызов для каждого элемента сетки ЗА ИСКЛЮЧЕНИЕМ первого в верхнем левом углу

Solutions Collecting From Web of "OnClickListener не работает для первого элемента в GridView"

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

 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 там, как-то, он смешивает прослушиватель кликов первой позиции в адаптере. Я закончил тем, что исправил это, просто установив держателя на каждом проходе, вместо того, чтобы получать его по тегу (что лучше для производительности, но хорошо). Спасибо всем за помощь.

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

как :

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

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

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

Используйте свой 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(); } }); 

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

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

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

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

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

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

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