【问题标题】:OnClickListener for Buttons in GridViewGridView 中按钮的 OnClickListener
【发布时间】:2016-12-13 15:09:22
【问题描述】:

我有一个GridView 适配器,显示Buttons 的网格。现在我想为我的按钮设置一个OnClickListener,但当然它们没有我可以访问的自己的 R.id,因为它们是通过适配器而不是 layout.xml 添加到网格中的。

我尝试使用OnItemClickListener如下:

m_onItemClickListener = new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
            switch(pos) {
                case MyConstants.POS_OF_BUTTON_1:
                        // Do stuff...
                    break;
                case MyConstants.POS_OF_BUTTON_2:
                        // Do stuff...
                    break;
            }
        }
    };

但据我了解,您不能将 clickablefocusable 项目与 OnItemClickListener 一起使用。我该如何解决这个问题?谢谢!

【问题讨论】:

    标签: android button gridview onclicklistener


    【解决方案1】:

    有更优雅的方法来完成这整个事情(从使用带有 GridLayoutManager 而不是 GridView 的 RecyclerView 开始),但是如果您正在寻找快速简便的解决方案来使用您已有的东西,这是你可以做什么:

    首先,您应该在按钮上设置一些 ID,它们不必来自 R.id(尽管如果您从布局中扩展视图,并在其中定义 ID 并使用一个 ViewHolder)。

    最坏的情况,您可以在适配器中为每个种类按钮(例如static final int DELETE_BUTTON = 1;)定义要使用的ID的常量,然后在按钮上手动设置这些ID,在代码中。

    然后您可以将一个简单的 OnClickListener(不是 OnItemClickListener)传递给您的适配器,它会处理单个项目中所有这些不同按钮的点击,并让适配器在其中的每一个上设置侦听器按钮,用于网格中的每个项目视图。

    您还需要将项目的位置设置为按钮视图本身的标签,以便当点击发生时,您可以确定点击是针对哪个项目发生的。

    示例代码如下:

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Object tag = v.getTag();
            if (!(tag instanceof Integer)) {
                // Show error message or just throw an exception.
            }
            int position = (Integer) tag;
            // We get the item at this position, to know which one to use
            Item item = adapter.getItem(position);
            switch (v.getId()) {
                case DELETE_BUTTON:
                    // Delete stuff here
                    break;
                case EDIT_BUTTON:
                    // Edit stuff here
                    break;
                ...
            }
        }
    };
    
    adapter.setOnClickListener(listener);
    

    然后,在适配器的getView 方法中,您需要在每个按钮上设置此侦听器,并将项目的位置设置为按钮上的标记。这样,您将能够在上面的侦听器代码中确定按钮属于哪个项目。

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ...
        deleteButton.setId(DELETE_BUTTON);
        deleteButton.setOnClickListener(listener);
        deleteButton.setTag(i);
        ...
    }
    

    总的来说,我真诚地建议您在有时间的时候也研究一下 ViewHolder 模式,以及 RecyclerView 和 GridLayoutManager。其中大部分内容也将在那里翻译。

    编辑

    为了使列表/网格项目内的多个视图可点击/聚焦,您需要在项目的根视图上将descendantFocusability 属性设置为blocksDescendants,可以简单地在 XML 中,也可以在代码中通过:

    viewGroup.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);

    【讨论】:

    • 非常感谢您的详细解答。我现在正在实践!
    • @petehallw,很高兴听到我能提供帮助!让我知道是否需要进一步澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多