在Android GridView中,OnItemClickListener未被触发

32

我有一个GridView,由适配器填充,适配器返回的每个LinearLayout都包含一个ImageButton和TextView。

在适配器中,我将onClick和onLongClick事件绑定到了ImageButton上。

我正在尝试将OnItemClickListener绑定到gridview上,但是我不知道为什么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();
    }
}

1
没有异常抛出,那我不就应该看到应用程序崩溃了吗? - Olgun Kaya
我没有看到这段代码有任何问题,也许问题出在其他地方。 - Caner
1
我也无法弄清楚。我看到很多关于onItemClickHandler的消息,这就是为什么我想在这里寻求帮助的原因。有趣的是,它对OnItemSelectHandler有效 :) - Olgun Kaya
7
Android 不支持将可点击的项目放在另一个“可点击”的项目中(例如网格项)。我建议移除 ImageButton,看看是否可以触发 onClickListener。如果这是问题所在,有一些方法可以让两个监听器都起作用。 - dmon
@dmon;非常感谢您的帮助,真的解决了我的问题。 解决方案是不要在网格中放置可点击的对象。您可以处理其他对象的单击事件,但不能处理默认可点击对象的事件。在我的情况下,我必须向用户显示一张图片,并且还需要点击该图片。因此,我首先选择使用ImageButton,但现在我正在使用ImageViews,似乎效果稍微好些。 - Olgun Kaya
显示剩余2条评论
6个回答

84

不要在网格中使用可点击的对象。在这种情况下,Android 无法处理 GridView 的点击事件。

相反,使用类似用户界面视图的其他东西来展示。然后处理该对象的点击操作。

不要:GridView 中放置 Button 来执行某些点击操作。

要: 放置一个 ImageView 来替代 ImageButton 并处理 ImageView 的点击事件。


例如,在 GridView 的子类中的子类化的 AdapterView 中: @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; } - EricRobertBrewer
你能否看一下这个类似的问题? - A_rmas

18

如果你想使用ButtonImageButton,那么你需要在小部件的xml代码中编写这些属性。

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

这对我起作用。

但在GridView中,请避免使用这些小部件。您可以使用其他任何小部件来代替它们(例如ImageView或其他任何小部件)。


奇怪的是,这个方法可以让你设置一个onclicklistener来触发按钮,但是如果你在其他地方点击网格项,它也会响应。 - Riot Goes Woof
我必须同时考虑到儿童和家长的视图,包括布局和“不可点击”的视图。有点奇怪,不是吗? - Sergio Daniel L. García
非常好的回答。非常感谢MPG! - richc

4

同时,请确保你的ListAdpter对于需要点击的位置,返回true:

public boolean isEnabled(int _position)

这样可以保证可点击。


2

大家好,终于找到了一个解决方案...

我们之前是直接访问GridView中的Layout,因此onItemClickListener在访问该项时会感到困惑。

因此,解决方法是在Adapter(通常是ArrayAdapter)中应用onClickListner。

我的意思是:

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

1
尝试设置


    android:clickable="false"
    android:focusable="false"

1
我也遇到了同样的问题,由于几个原因。所以这是我的建议:
  1. 为您的适配器扩展BaseAdapter
  2. 在适配器的getView中使用OnClickListener,而不是为GridView设置OnItemClickListener
  3. 避免多次设置LayoutParams
  4. 检查如果position = 0,则不要使用convertView,而是膨胀新的View
  5. 不仅为父View设置OnClickListener,而且为任何子View设置OnClickListener(如果有);
  6. 使所有View可点击。
我在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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接