在GridView中多次调用getView()

我的活动包含GridView,它包含40多个元素。 启动活动后,用户最多可以看到15个项目(3行,每行5个项目)。 我在getView()体中编写了传递给获取View的LogCat数:

Log.i("getView()", "GETTING VIEW_POSITION[" + String.valueOf(position) + "]" + (convertView != null?convertView.toString():"null")); 

启动我的应用程序后,我得到这样的日志:

 02-09 14:34:56.900: INFO/getView()(388): GETTING VIEW_POSITION[0]null 02-09 14:34:57.300: INFO/getView()(388): GETTING VIEW_POSITION[0]android.widget.FrameLayout@44c7a9c0 02-09 14:34:57.300: INFO/getView()(388): GETTING VIEW_POSITION[1]null 02-09 14:34:57.400: INFO/getView()(388): GETTING VIEW_POSITION[2]null 02-09 14:34:57.510: INFO/getView()(388): GETTING VIEW_POSITION[3]null 02-09 14:34:57.620: INFO/getView()(388): GETTING VIEW_POSITION[4]null 02-09 14:34:57.720: INFO/getView()(388): GETTING VIEW_POSITION[5]null 02-09 14:34:57.840: INFO/getView()(388): GETTING VIEW_POSITION[6]null 02-09 14:34:57.930: INFO/getView()(388): GETTING VIEW_POSITION[7]null 02-09 14:34:58.273: DEBUG/dalvikvm(388): GC freed 3530 objects / 322744 bytes in 270ms 02-09 14:34:58.280: INFO/getView()(388): GETTING VIEW_POSITION[8]null 02-09 14:34:58.300: INFO/getView()(388): GETTING VIEW_POSITION[9]null 02-09 14:34:58.320: INFO/getView()(388): GETTING VIEW_POSITION[10]null 02-09 14:34:58.340: INFO/getView()(388): GETTING VIEW_POSITION[11]null 02-09 14:34:58.360: INFO/getView()(388): GETTING VIEW_POSITION[12]null 02-09 14:34:58.380: INFO/getView()(388): GETTING VIEW_POSITION[13]null 02-09 14:34:58.400: INFO/getView()(388): GETTING VIEW_POSITION[14]null 02-09 14:34:59.220: INFO/getView()(388): GETTING VIEW_POSITION[0]null 02-09 14:34:59.490: INFO/getView()(388): GETTING VIEW_POSITION[0]android.widget.FrameLayout@44c69ef0 

关于这样的问题,我也发了这篇文章。 但我的GridView在XML描述中的高度设置为填充父级:

   

最后删除所有疑问,这是我的适配器代码:

 public class ImageAdapter extends BaseAdapter { private Activity activity; private LayoutInflater inflater = null; private ArrayList photoes; public ImageAdapter(Activity a, ArrayList pictures) { photoes = pictures; activity = a; inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("getView()", "GETTING VIEW_POSITION[" + String.valueOf(position) + "]" + (convertView != null?convertView.toString():"null")); View mViewSlice = convertView; if(convertView == null) { mViewSlice = inflater.inflate(R.layout.photo_preview, null); ((TextView) mViewSlice.findViewById(R.id.name_of_photo)).setText(photoes.get(position).getName()); mViewSlice.setPadding(5, 5, 5, 5); mViewSlice.setLayoutParams(new GridView.LayoutParams(-2, -2)); } return mViewSlice; } @Override public int getCount() { return photoes.size(); } @Override public Object getItem(int position) { return photoes.get(position); } @Override public long getItemId(int position) { return position; } } 

我希望有人会回答我的问题,并帮助我解决它。

等待你的建议。 亚历克斯。

我认为,如果非常明确的话,对该链接的回应

对于任何给定位置,getView()的调用次数绝对无法保证

现在这句话也暗示你不应该使用wrap_content

通常发生在列表和网格的高度设置为wrap_content

但这并不意味着它不会发生在其他情况下。 该错误被关闭为“WorkingAsIntended”,所以我认为你不能做太多。 这只是可能发生的事情。

对我来说,情况更糟:0位通常被称为10次。 即使我在列表的末尾,屏幕上没有位置0,也会调用它。

我的解决方案是当前正在处理以显示的项目的静态ArrayList,我忽略了这些双重调用。 这不是最好的解决方案,因为它仍然使用资源来获得0位置,而它甚至不在屏幕上。

因为它看起来像一个bug,我想我会为位置0缓存一个View,这样即使位置不在屏幕上,它也会获得快速和正确的返回值。

Android 4.2.2。

我有同样的问题,我的解决方案是在适配器外创建一个List,然后将List提供给适配器,类似于:

  class MyAdapter extends BaseAdapter{ List views; public MyAdapter(List views){ this.views = views; } ... public View getView(int position, View convertView, ViewGroup parent){ return views.get(position); // now your safe even if element[0] is called n times } } class MyActivity extends Activity{ GridView grid; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); List views = create_your_views(): MyAdapter adapter = new MyAdapter(views); grid.setAdapter(adapter); } }