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

OnClickListener无法处理GridView中的第一项

长孙雅志
2023-03-14

我在创建基于GridView的日历时遇到问题。下面是网格:

这应该是一个包含事件的日历,所以我让适配器实现OnClickListener,并为日历中的每个按钮设置侦听器。它适用于除第一个按钮(在本例中为30号)以外的每个按钮。当我单击它时,它就是不起作用,但当我在尝试单击第一个按钮后单击另一个按钮时,它会在单击另一按钮之前对第一个按钮执行单击。

我已经浏览了大约10页的相关问题,没有发现有人有这个问题。请帮帮我!

如前所述,下面是我代码的getView函数

    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        ViewHolder holder;
        if (row == null)
        {
            holder = new ViewHolder();
            LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
            holder.gridCell = (Button) row.findViewById(R.id.calendar_day_gridcell);
            holder.multiDayEvent = (EventLengthView)row.findViewById(R.id.eventLengthView);
        }
        else{
            holder = (ViewHolder)row.getTag();
        }

        int calendarGridHeight = (calendarView.getHeight()-5)/(getCount()/7);
        AbsListView.LayoutParams params = new AbsListView.LayoutParams(
                android.view.ViewGroup.LayoutParams.FILL_PARENT,
                calendarGridHeight);
        row.setLayoutParams(params);

        //Change the background drawable depending on the position in the calendar
        if ((position+1) % 7 == 0){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_row));
        }
        if (getCount() - position < 8){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end_column));
        }
        if (position == getCount()-1){
            holder.gridCell.setBackgroundDrawable(getResources().getDrawable(R.drawable.calendar_button_selector_end));
        }
        holder.gridCell.setOnClickListener(this);

        holder.gridCell.setTag(null);//clear tags

        // ACCOUNT FOR SPACING
        String[] day_color = list.get(position).split("-");
        int theday = Integer.parseInt(day_color[0]);
        int themonth = Integer.parseInt(day_color[2]);
        int theyear = Integer.parseInt(day_color[3]);
        String date = DateFormat.format("dd/M/yy", new Date(theyear,themonth,theday)).toString();
        if ((!eventsMap.isEmpty()) && (eventsMap != null))
        {
            if (eventsMap.containsKey(date))
            {
                holder.multiDayEvent.SetMeasure(calendarView.getWidth()/7, calendarGridHeight);

                holder.multiDayEvent.setVisibility(View.VISIBLE);
                //holder.singleDayEvent.setVisibility(View.VISIBLE);
                Event event = (Event) eventsMap.get(date);
                holder.multiDayEvent.AddEvent(event);
                holder.gridCell.setTag(event);
            }
            else{
                //holder.singleDayEvent.setVisibility(View.GONE);
                holder.multiDayEvent.setVisibility(View.GONE);
            }
        }

        // Set the Day GridCell
        holder.gridCell.setText(Integer.toString(theday));

        if (day_color[1].equals("GREY"))
        {
            holder.gridCell.setTextColor(Color.GRAY);
        }
        if (day_color[1].equals("WHITE"))
        {
            holder.gridCell.setTextColor(Color.WHITE);
        }
        if (day_color[1].equals("BLUE"))
        {
            holder.gridCell.setTextColor(Color.BLUE);
        }

        row.setTag(holder);
        return row;
    }

    public class ViewHolder{
        Button gridCell;
        ImageView singleDayEvent;
        EventLengthView multiDayEvent;
    }

    public void onClick(View view)
    {
        if (view.getTag() != null){
            Event event = (Event)view.getTag();

            eventListView.setAdapter(new EventListAdapter(CalendarScreen.this, event));
            eventListViewLayout.setVisibility(View.VISIBLE);
            eventListViewLayout.startAnimation(fadeIn);
        }
        else if (eventListViewLayout.getVisibility() == View.VISIBLE){
            onBackPressed();
        }
    }

除了左上角的第一个网格单元外,每个网格单元都会调用onClick

共有3个答案

齐夕
2023-03-14

好的,我找到了解决办法。问题是这些行:

ViewHolder holder;
if (convertView == null)
{
    holder = new ViewHolder();
    LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
    holder.gridCell = (Button) convertView.findViewById(R.id.calendar_day_gridcell_button);
    holder.multiDayEvent = (EventLengthView) convertView.findViewById(R.id.eventLengthView);
    convertView.setTag(holder);
}
else {
    holder = (ViewHolder) convertView.getTag();
}

当在那里安装gridCell按钮时,不知何故,它混合了适配器第一个位置的点击监听器。我最终通过在每次传递中安装支架来修复它,而不是通过标签来获取它(这对性能更好,但是哦,好吧)。谢谢大家的帮助。

归和惬
2023-03-14

在 .setAdapter() 方法之后的活动中使用 OnClick 通知程序 (),而不是在适配器类中使用。

gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
    Toast.makeText(GridViewActivity.this, "" + position,
             Toast.LENGTH_SHORT).show();
    }
});
房项禹
2023-03-14

我有同样的problem.Keepingif(view==null)子句中的setLayoutParams解决了。你不必以这种方式牺牲视图回收。

例如:

 if(row == null){
   // inflate row
   row.setLayoutParams(params);
   //remaining code
 }else{
    holder = (ViewHolder)row.getTag();
 }
 // everything else

我不知道它为什么有效,但它对我有效。我还注意到,stackoverflow中关于同一问题的所有代码都在if子句之外使用了setLayoutParams。这是我第一次,所以我不知道我是否可以到处张贴。希望能有所帮助。

来源:大量的尝试和错误。

 类似资料:
  • 在ViewPager中,有一个网格视图,其中有一个带有文本视图和图像的单选答案网格。当我点击任何答案时,文本视图应该将其颜色更改为红色或白色。除了第一个答案,其他所有答案都可以正常工作。当我第一次点击网格视图中的第一个答案时,它不会更改颜色,第二次点击时它会变成红色,但是当我更改选项时,第一个选项的红色不会更改为白色。请看下面的屏幕, 抱歉,由于我是新用户,不允许提交屏幕。。。 在< code >

  • 我有GridView,其中项目是带有图像(ImageView)和标题(TextView)的视图。我想在这个ImageView上执行onClick操作,但不是在整个GridView项上。如果我使用这个代码: 只有第二次单击ImageView才能进行操作。如何通过第一次单击GridView在ImageView上执行操作?

  • 本文向大家介绍php第一次无法获取cookie问题处理,包括了php第一次无法获取cookie问题处理的使用技巧和注意事项,需要的朋友参考一下 首先编写以下简单的代码: 第一次访问时,报错: 报错的原因是$_COOKIE['a']的值不存在。第二次访问: 问:为什么第一次访问的时候,会没有cookie呢??我不是先设置,再获取吗?? 答:使用firefox的firebug查看”网络“: 客户端:

  • 问题内容: 在OnClickListener内部,我无法访问范围“外部”的大多数变量,如下所示: 在此示例中,我需要获取PacketManager,但由于在OnClickListener内部没有可用的上下文,因此无法获取它。 我可以在外面做一个静态引用,并在里面使用它,对吗?似乎总是必须这样做吗? 问题答案: 将代码替换为MyActivity是Activity子类的类名。 说明:当您使用代码的这一

  • 是否有人使用RecyclerView找到了将onClickListener设置为RecyclerView中的项的方法? 请帮帮我...我是初学者:)

  • 问题内容: 我收到错误 消息“无法解析符号“ OnClickListener” 和 “无法解析符号“ V””, 我开始使用Java,因此我不太擅长此语言,并且对语言不太熟悉 我的代码: 问题答案: 我不确定您为什么要这样做,但请将初始化和侦听器移至: 只需剪切以下代码行: 并将它们粘贴到: 然后阅读编码的基础及其标准。