OnClickListener不适用于GridView中的第一项

Val*_*tin 21 android android-gridview

我在创建基于GridView的日历时遇到问题.这是网格:

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

Bru*_*yne 14

我遇到了同样的问题.在if(view == null)子句中保留setLayoutParams.你不必以这种方式牺牲视图回收.

喜欢 :

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

我不知道它为什么有效,但它对我有用.我还注意到,stackoverflow中有关同一问题的所有代码也使用了if子句之外的setLayoutParams.这是我的第一次,所以我不知道我是否可以在任何地方发布.希望它有所帮助.

来源:很多追踪和错误.

  • 为我工作,为我节省了很多时间 (2认同)

小智 8

好的,我找到了解决方案.问题是这些问题:

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();
}
Run Code Online (Sandbox Code Playgroud)

当在那里设置gridCell按钮的实例时,它会以某种方式混合适配器中第一个位置的单击侦听器.我最后通过在每次传递中设置持有者来修复它,而不是通过标记获取它(这对于性能更好,但是很好).谢谢大家的帮助.


Ras*_*hid 8

用你的OnClickListener()在后您的活动.setAdapter()方法,而不是在你的适配器类.

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();
    }
});
Run Code Online (Sandbox Code Playgroud)