我在创建基于GridView的日历时遇到问题。这是Grid:
这应该是一个填充了事件的日历,所以我有我的适配器实现OnClickListener,我为日历中的每个按钮设置了该监听器。它适用于每个按钮 EXCEPT 第一个按钮(在本例中为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,除了左上角的第一个
答案 0 :(得分:13)
我遇到了同样的问题。在if(view == null)子句中保留了setLayoutParams。你不必以这种方式牺牲视图回收。
喜欢:
if(row == null){
// inflate row
row.setLayoutParams(params);
//remaining code
}else{
holder = (ViewHolder)row.getTag();
}
// everything else
我不知道它为什么有效但它对我有用。我还注意到,stackoverflow中有关同一问题的所有代码也使用了if子句之外的setLayoutParams。这是我的第一次,所以我不知道我是否可以在任何地方发布。希望它有所帮助。
来源:很多追踪和错误。
答案 1 :(得分: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();
}
当在那里设置gridCell按钮的实例时,它会以某种方式混合适配器中第一个位置的单击侦听器。我最后通过在每次传递中设置持有者来修复它,而不是通过标记获取它(这对于性能更好,但是很好)。谢谢大家的帮助。
答案 2 :(得分:8)
在 .setAdapter()方法后的活动中使用 OnClickListener(),而不是在适配器类中。
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();
}
});
答案 3 :(得分:1)
对于它的价值,我也遇到了这个问题(gridview中的第一个单元格延迟了onclick)。
在我的情况下,我使用(轻微自定义)网格视图和动态的图像视图集,我将使其可见/消失并重绘网格视图。预先准备好并存储在适配器中的所有图像视图。
最初,我在适配器上使用了notifyDataSetChanged(),但是每当更新集合时,这都会导致第一个单元格的延迟点击问题。我改为使gridview无效,现在情况还不错。请记住,我的所有视图都已创建并存储在适配器中,它只是用于检查哪些视图真正可见的getview方法。
答案 4 :(得分:1)
我有同样的问题。第一个项目的点击事件明显延迟。我已经在使用notifyDataSetInvalidated()了。 使用onItemClickListener()解决了问题,虽然我仍然不明白为什么单个项目上的onClick侦听器有这种行为。
答案 5 :(得分:0)
在GridView对象上设置onItemClickListener,而不是在每个按钮上设置onClickListeners。
我发现了您的问题here的另一个问题。赏金可能吗?
答案 6 :(得分:0)
请参考此link,它已将gridview背景颜色设置为TRANSPARENT。它可能对你有帮助。
答案 7 :(得分:0)
花费了很多天后,按如下所示设置布局参数。
if (view == null) {
// call the user's implementation
view = mInflater.inflate(mViewId, null);
holder = createHolder(view);
// we set the holder as tag
view.setTag(holder);
rlMainCell = (RelativeLayout)view.findViewById(R.id.rlMainCell);
rlMainCell.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) view.getResources().getDimension(R.dimen._128sdp)));
} else {
// get holder back...much faster than inflate
holder = (ViewHolder) view.getTag();
}
对我来说绝对正常