当前位置: 首页 > 知识库问答 >
问题:

网格视图中第一项的图像查看打开事件无法正常工作或延迟

华宏逸
2023-03-14

我设计了一个具有自定义项目布局的网格视图,左上角有一个图像视图,右上角有另一个图像视图,中间有一个主图像视图和文本。

我需要为角落的两个ImageView和适配器的OnItemClickListener设置OnClickListener。

一切正常,但只有GridView中的第一项无法触发OnClickListener。有人能解决这个问题吗?

附言:我发现第一个项目ImageView的OnClickListener将在我执行下一个操作时触发(例如单击其他项目)

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    TagView tag;
    if (convertView == null) {
        v = m_LayoutInflater.inflate(R.layout.mydoc_grid_item, null);
        tag = new TagView(
                (ImageView) v.findViewById(R.id.myDoc_GridItem_IV),
                (TextView) v.findViewById(R.id.myDoc_GridItem_TV),
                (ImageView) v.findViewById(R.id.iViewAdd2Category),
                (ImageView) v.findViewById(R.id.iViewDelete));
        v.setTag(tag);
    } else {
        tag = (TagView) v.getTag();
    }

    v.setLayoutParams(new GridView.LayoutParams((int) (180 * v
            .getResources().getDisplayMetrics().density), (int) (180 * v
            .getResources().getDisplayMetrics().density)));


    tag.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
    tag.image.setImageDrawable(new BitmapDrawable(BitmapFactory.decodeFile(m_DisplayItems.get(position)
                    .get("image").toString())));
    tag.text.setText(m_DisplayItems.get(position).get("text").toString());
    tag.iAdd2Category.setVisibility((m_IsEdit) ? View.VISIBLE : View.GONE);
    tag.iDelete.setVisibility((m_IsEdit) ? View.VISIBLE : View.GONE);
    if (m_IsEdit) {
        tag.iAdd2Category.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.i(LOG_TAG, "Click on image add 2 category");
            }
        });

        tag.iDelete.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Log.i(LOG_TAG, "Click on image delete");
            }
        });
    }

    return v;
}

共有3个答案

单于善
2023-03-14

这个问题的原因是,Android不仅在绘制视图时为第一项调用getView(),而且还为布局测量调用调用getView()!在getView()中,没有办法区分度量调用和绘制调用。因此,当您第一次进行绘制调用,然后在某个时间点进行度量调用时,您会覆盖onClickListener。实际上,这样做似乎是正确的——因为您每次都这样做,但我观察到这种行为。也许您设置了clickListener,系统会在getView调用后释放它,因为视图不会被绘制……我没有足够深入地跟踪以确保。

然而,每次重新创建视图都是一个坏主意,因为它非常耗时——你的网格可能无法平滑滚动。

解决方案是编写自己的GridView,如下所示:

public class MyGridView extends GridView{
private GridAdapter adapter;


public MyGridView(Context context) {
    super(context);
}

public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public MyGridView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void setAdapter(GridAdapter adapter) {
    this.adapter = adapter;
    super.setAdapter(adapter);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(adapter!=null)
        adapter.setIsMeasureCall();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}}

并在网格适配器中实现方法集。该方法仅在每次调用时将标志设置为 true。然后,在 getView() 方法中,检查它是否是度量调用,以及是否为真 - 不设置侦听器。

确保在 getView() 方法的末尾将“测量”设置为“假”。

我希望一切都很清楚:)

有关更多信息,您可以查看我的主页,其中我提供了一个完整的Android项目来解决此问题。http://simon.osim.at/projects/gridadapter/#TheSolution

燕翔飞
2023-03-14

我终于在这篇文章里找到了答案。

OnClickListener无法处理GridView中的第一项

在我的情况下:

if (convertView == null) {
    v = m_LayoutInflater.inflate(R.layout.mydoc_grid_item, null);
    tag = new TagView(
            (ImageView) v.findViewById(R.id.myDoc_GridItem_IV),
            (TextView) v.findViewById(R.id.myDoc_GridItem_TV),
            (ImageView) v.findViewById(R.id.iViewAdd2Category),
            (ImageView) v.findViewById(R.id.iViewDelete));
    v.setTag(tag);
} else {
    tag = (TagView) v.getTag();
}

只需删除if else语句,每次都会实例化“标签”。

云洋
2023-03-14

将列表项的< code>OnClickListeners和< code > OnItemClickListeners 混合使用效果不好。

在您的情况下,您可能应该在项目的不同部分使用多个< code>OnClickListeners,而根本不使用< code>OnItemClickListener。

 类似资料:
  • 我在玩新的CardView,但是利润似乎不适用。 顺便说一句,我在视图页程序中的片段中使用它。该卡扩展了屏幕的整个宽度(match_parent),即使我在卡视图上使用和。 你知道我可能做错了什么吗?

  • 我正在尝试创建一个简单的照片库,其中一张照片是大的,也有拇指在底部,当点击成为那张大照片。画廊在单独的模式窗口。我的代码只在第一个模态窗口中工作。事实上,这是我第一次使用jQuery。我甚至找不到如何使用console.log来检查问题出在哪里。 HTML: jQuery:

  • Aspx代码: C#代码: 下拉列表selectedindexchanged事件不会触发。我尝试在运行时更改下拉列表值时,在数据库值中获取更新。

  • 我在列表视图中使用微调器,但它在列表视图中不能正常工作。我能够在微调器中显示所需的值,但无法从微调器中获取选定的项目值。 它没有打印任何东西。布局:

  • 我写了一个日历视图的程序,它不能正常工作,因为我想要。首先,我有一个按钮,当点击打开一个新的活动,里面有一个线性布局,我有3个日月年的文本视图,我有一个对话框打开点击线性布局,因为我说我有3个文本视图在我的线性布局,而不是使用三个不同的点击监听器,我使用了在线性布局ID的帮助下点击,所以我的日历对话框打开了,但当我使用calendar.setOnDateChangeListener我的应用程序崩溃