OnItemClickListener не запускается в Android GridView

У меня есть Gridview, заполненный адаптером, который возвращает LinearLayouts, каждый из которых содержит ImageButton и TextView.

В адаптере я привязываю событие onClick и onLongClick к ImageButton.

Я пытаюсь привязать OnItemClickListener к сетке, но я не знаю, почему onItemclicked никогда не срабатывал.

Это мой 6-й час без ничего.

Кстати; OnItemSelectListener отлично работает с сеткой.

Я проверяю, случайно ли какая-то часть кода обрабатывает onItemClicked, но пока не может поймать.

Мне нужна помощь, ребята.

gridView = (GridView) layoutInflater.inflate(R.layout.gridview, null);
gridView.setOnItemClickListener(new ItemClickListener());
. 
.
.

//inner handler class
class ItemClickListener implements AdapterView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Toast.makeText(mainActivity.getApplicationContext(),view + " clicked at pos " +            
        i,Toast.LENGTH_SHORT).show();
    }
}

person Olgun Kaya    schedule 18.11.2011    source источник
comment
Есть ли исключения в LogCat?   -  person Michel Foucault    schedule 18.11.2011
comment
нет. так как я не поймал никаких исключений, я бы увидел, что приложение разбилось. я бы не ??   -  person Olgun Kaya    schedule 18.11.2011
comment
Я не вижу ничего плохого в этом коде, возможно, проблема где-то в другом.   -  person Caner    schedule 18.11.2011
comment
Я тоже не мог понять. Я видел много сообщений о onITemClickHandler. Вот почему я хотел написать здесь о помощи. Что смешно; Это работает для OnItemSelectHandler :)   -  person Olgun Kaya    schedule 18.11.2011
comment
Android не любит, когда вы размещаете кликабельный элемент внутри другого кликабельного элемента (например, элемента сетки). Я бы вынул ImageButton и посмотрел, запустится ли onClickListener. Если это проблема, есть способы заставить работать обоих слушателей.   -  person dmon    schedule 18.11.2011
comment
@дмон; спасибо за вашу большую помощь. это действительно сработало. Решение — не помещать кликабельный объект в сетку. Вы можете обрабатывать событие щелчка других объектов, но не объект, по которому можно щелкнуть по умолчанию. В моем случае; Я должен показать пользователю изображение, а также на это изображение нужно щелкнуть. Поэтому сначала я решил использовать ImageButton. Но теперь я использую ImaveViews и, кажется, немного работаю.   -  person Olgun Kaya    schedule 21.11.2011
comment
@дмон; Можете ли вы рассказать больше о том, как заставить работать оба слушателя? Является ли это проблематичным для моего способа решения? это использование ImageView вместо ImageButton.   -  person Olgun Kaya    schedule 21.11.2011


Ответы (6)


Не используйте кликабельные объекты в сетке. В этом случае Android не может обработать событие click GridView.

Вместо этого используйте что-нибудь, чтобы показать аналогичный вид пользовательского интерфейса. Затем обработайте действия щелчка этого объекта.

Нельзя ставить Button вместо GridView, чтобы выполнить некоторые действия по клику.

Что нужно сделать: поставьте ImageView вместо ImageButton и обработайте события кликов ImageView.

person Olgun Kaya    schedule 21.11.2011
comment
Например, в подклассе AdapterView внутри подкласса GridView: @Override public View getView(final int position, View convertView, ViewGroup parent) { ImageView imageView = new ImageView(getContext()); imageView.setOnClickListener(new OnClickListener() { @Override onClick(View v) { if (getOnItemClickListener() != null) { getOnItemClickListener().onItemClick(MyGridView.this, v, position, getItemId(position)); } return imageView; } - person EricRobertBrewer; 16.02.2016
comment
stackoverflow.com/ вопросов/36474607/ Не могли бы вы посмотреть на этот похожий вопрос? - person A_rmas; 08.04.2016

Если вы хотите использовать Button или ImageButton, вам нужно написать эти атрибуты в вашем XML-коде виджетов.

android:focusable="false"
android:focusableInTouchMode="false"

Это работает для меня.

Но в GridView старайтесь избегать использования этих виджетов. Вместо них вы можете использовать любые другие виджеты (например, ImageView или любые другие).

person MPG    schedule 21.11.2014
comment
Как ни странно, это работает и по-прежнему позволяет вам нажимать и запускать кнопку, если вы установили для нее onclicklistener, но позволяет вам щелкнуть элемент сетки, если вы нажмете в любом другом месте, если хотите. - person Riot Goes Woof; 14.07.2015
comment
Пришлось ставить и для детей, и для родительских взглядов. Включая макеты и некликабельные представления. Странно, не так ли? - person Sergio Daniel L. García; 12.10.2015
comment
отличный ответ. Большое спасибо МПГ! - person richc; 12.09.2017

Также убедитесь, что ваш ListAdpter возвращает true для

общественное логическое значение isEnabled (int _position)

для позиции, которую вы хотите щелкнуть.

person r-hold    schedule 28.12.2012

Эй, ребята, наконец-то есть решение ...

то, что мы делали, — это прямой доступ к макету внутри GridView, поэтому onItemClickListener считает, что доступ к элементу сбивает с толку.

Таким образом, решение состоит в том, чтобы применить onClickListener внутри адаптера (т.е. обычно ArrayAdapter)

так что я пытаюсь сказать:

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

            //Here row is a view and we can set OnClickListener on this
    final View row;
    ViewHolder holder = null;

    if (convertView == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        //Here we inflate the layout to view (linear in my case)
        row = inflater.inflate(layoutResourceId, parent, false);
        holder = new ViewHolder();
        holder.imageTitle = (TextView) row.findViewById(R.id.text);
        holder.image = (ImageView) row.findViewById(R.id.image);
        row.setTag(holder);
    } else {
        row = convertView;
        holder = (ViewHolder) row.getTag();
    }

    ImageItem item = data.get(position);
    holder.imageTitle.setText(item.getTitle());
    holder.image.setImageBitmap(item.getImage());

    //Now get the id or whatever needed
    row.setId(position);
    // Now set the onClickListener
    row.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Toast.makeText(context, "Clicked" + row.getId() + "!!",
                    Toast.LENGTH_SHORT).show();
        }
    });
    return row;
}
person Angesh K Chettiar    schedule 22.01.2014

Попробуйте установить

    android:clickable="false"
    android:focusable="false"
person newbie    schedule 22.04.2016

Я тоже сталкиваюсь с той же проблемой по нескольким причинам. Итак, вот мои советы:

  1. Расширьте BaseAdapter для вашего адаптера;
  2. Используйте OnClickListener внутри getView в адаптере вместо установки OnItemClickListener для GridView;
  3. Не устанавливайте LayoutParams несколько раз;
  4. Убедитесь, что position = 0, не используйте convertView, создайте новый View;
  5. Установите OnClickListener не только для родительского View, но и для любого дочернего View, если таковой имеется;
  6. Сделайте все свои представления кликабельными.

Я только что протестировал его на 4 устройствах, и это решение работает, как и ожидалось. Надеюсь, это поможет в вашем случае. Поправьте меня, если я что-то не так сделал.

Код макета XML:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="#273238"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:padding="1dp">

<ImageView
    android:id="@+id/open_image_item_imageview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/loh"
    android:clickable="true"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:scaleType="centerCrop"/>
<TextView
    android:id="@+id/open_image_item_textview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:layout_gravity="bottom"
    android:padding="4dp"
    android:textSize="10sp"
    android:ellipsize="start"
    android:background="#55000000"
    android:textColor="#FFFFFF"
    android:text="image name"/>

</FrameLayout>

Код адаптера Java:

 @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view = null;
        if(convertView != null && position != 0)
            view = convertView;
        else{
            view = LayoutInflater.from(getContext()).inflate(R.layout.open_image_item_layout, null, false);
            view.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));
        }

        TextView textView = (TextView)view.findViewById(R.id.open_image_item_textview);
        ImageView imageView = (ImageView)view.findViewById(R.id.open_image_item_imageview);

        ...

        View.OnClickListener onClickListener = getOnClickListener(files[position]);
        view.setOnClickListener(onClickListener);
        textView.setOnClickListener(onClickListener);
        imageView.setOnClickListener(onClickListener);

        return view;
    }
person Dr. Failov    schedule 05.11.2017