【问题标题】:Android - OnClickListener in Adapter for GridViewAndroid - GridView 适配器中的 OnClickListener
【发布时间】:2014-07-15 16:01:52
【问题描述】:

我正在使用 GridView 来显示“车辆”列表(一个显示有关车辆的一些简短信息的矩形),当我单击一个矩形时,它会展开视图以显示更多信息。 这很好用。 但是,当我想用​​其他数据重建我的 gridview 时,gridview 的孩子不再捕获点击。 我不想使用一些 onItemClickListener 因为它只是孩子的显示/隐藏功能...... 所以我在自定义适配器的 getView() 函数中设置了 onClickListener。 这是我的适配器代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (rowView == null) {
        LayoutInflater inflater = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.encart_vehicule, parent, false);
        final ViewHolder vh = new ViewHolder();
        vh.text = (TextView) rowView.findViewById(R.id.libVehi);
        vh.text2 = (TextView) rowView.findViewById(R.id.heureEngagement);
        vh.back = (LinearLayout) rowView.findViewById(R.id.backcolor);
        vh.listEq = (LinearLayout) rowView.findViewById(R.id.equipage);
        vh.vIndicator = (View) rowView.findViewById(R.id.view1);
        vh.more = (TextView) rowView.findViewById(R.id.more);

        vh.vIndicator.setVisibility(View.GONE);
        vh.listEq.setVisibility(View.GONE);

        if (mlistMoyenMateriel.get(position).getLstPersonnels().size() == 0) {
            vh.more.setVisibility(View.GONE);
        } else {
            rowView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!vh.opened) {
                        vh.more.setVisibility(View.GONE);
                        vh.vIndicator.setVisibility(View.VISIBLE);
                        vh.listEq.setVisibility(View.VISIBLE);
                    } else {
                        vh.more.setVisibility(View.VISIBLE);
                        vh.vIndicator.setVisibility(View.GONE);
                        vh.listEq.setVisibility(View.GONE);
                    }
                    vh.opened = !vh.opened;
                }
            });
        }

        vh.back.setBackgroundColor(Color.parseColor("#"
                + mlistMoyenMateriel.get(position).getEtat()
                        .getm_strColor()));

        for (Personnel p : mlistMoyenMateriel.get(position)
                .getLstPersonnels()) {
            TextView tv = new TextView(getContext());
            tv.setText(p.getm_strNom() + " " + p.getm_strPrenom() + " "
                    + p.getm_strMatricule());
            Resources r = getContext().getResources();
            float px = TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, 5, r.getDisplayMetrics());
            tv.setPadding(0, 0, 0, (int) px);
            vh.listEq.addView(tv);
        }
        rowView.setTag(vh);
    }

    ViewHolder holder = (ViewHolder) rowView.getTag();
    holder.text.setText(mlistMoyenMateriel.get(position).getType()
            + " "
            + mlistMoyenMateriel.get(position).getNumeroOrdre()
                    .substring(1) + " "
            + mlistMoyenMateriel.get(position).getCode_centre());
    holder.text2.setText(dateUtil.Date_heureToString(mlistMoyenMateriel
            .get(position).getdEngagement(), "dd MMMMMMMM HH:mm")
            + (mlistMoyenMateriel.get(position).getDureeASLL() == null ? ""
                    : "+" + mlistMoyenMateriel.get(position).getDureeASLL()
                            + "mn"));

    holder.back.setBackgroundColor(Color.parseColor("#"
            + mlistMoyenMateriel.get(position).getEtat().getm_strColor()));

    // holder.back.setBackgroundColor(Color.parseColor("#"+mlistMoyenMateriel.get(position).getEtat().getm_strColor()));

    return rowView;
}

然后我的gridView实例化:

    GridView gv = null;
    gv = (GridView) rlInter
            .findViewById(R.id.listAutresVehiculesEngages);
    gv.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
    MoyenMaterielAdapter mma = new MoyenMaterielAdapter(this,
            inter.getm_lstListeDesobjetVehiculePourCetteOperation());
    gv.setAdapter(mma);
    gv.invalidateViews();

当我第二次回忆这段代码时,列表已正确重建,但是,即使它从 getView 函数传入“rowView.setOnClickListener”,对子项的点击也不再有效(它没有扩展我的意见)。我尝试在点击事件上做一个 Toast,它也不再显示了。

有人知道这个问题吗?我做错了什么?我可以尝试使用 OnItemClickListener,但我认为这对于那个小功能来说有点太多了,知道它仍然有效但只是第一次...... 感谢您的帮助!

(我真的很抱歉我的英语)

编辑: 我错过了一些东西:第二次它没有传入 setOnClickListener 代码。即使我显示了新项目。

【问题讨论】:

  • 我发现了我的问题,在我的子布局(包括我的网格视图)的整个重建之前,顶部布局(相对布局)没有被清除。现在,我在重建所有视图之前先清除它,顶部布局不再吸引我的点击。

标签: android gridview adapter onclicklistener


【解决方案1】:

添加为 onClick() ViewHolder vh =(ViewHolder)v.getTag(); 的第一行。

【讨论】:

  • 你的 'v' 是我的 'rowView',所以如果 rowView 为 null,rowView.getTag() 将抛出 NullPointerException... 而且,正如您在我的代码中看到的那样,我已经在我的 rowView 构建后使用 getTag()。
  • 确实如此。这就是当 v 为空时会发生的情况。不要使用行视图。你为什么这样做?使用 v.getTag()。奇怪的是,在 OnClick(View v) 中 v 将为空。以前从未见过。难以置信。
  • 好的,我对你的 v 感到困惑,但我明白了!你在谈论 onClick 参数,我在想我的 getView 参数。对不起!我发现了我的问题,在我的子布局(包括我的网格视图)的整个重建之前,顶部布局(相对布局)没有被清除。现在,我在重建所有视图之前先清除它,并且顶部布局不再吸引我的点击。
  • 那么请再次阅读我的答案。但是....现在有效吗?我想知道。你忘了说。
  • 是的,它在我从我的 gridview 的顶级父级调用 removeAllViews 后工作。我的数据集完全改变了,所以我只是用我的自定义适配器的一个新实例来重建我的 gridview。但这还不够,我必须先从父视图中删除所有视图,然后重建所有子视图,包括我的网格视图。出于某种原因,在重建时,点击事件没有分派给顶视图的子视图。
【解决方案2】:

rowView 只是您的列表第一次加载时的null

将您的 onclick 移到 if (rowView == null) 块之外。另外,建议在列表适配器中使用 holder 模式。

【讨论】:

  • 它实际上是一个持有者模式(这就是为什么有if (rowView == null) 声明)。我试图将 setOnClickListener 放在外面(即使它对性能不是很好,因为它会在每次重绘时调用此代码),但效果并不好。
猜你喜欢
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多