无法在自定义适配器中使用LayoutInflater

我正在研究编写一个自定义的适配器来填充每行3个textviews的列表视图。 我已经find了相当多的示例代码来做到这一点,但似乎最好的代码是: http : //www.anddev.org/custom_widget_adapters-t1796.html

经过一些小的调整,以解决最新的Android SDK的一些编译器问题,我得到它运行,只是为了得到exception:

ERROR / AndroidRuntime(281):java.lang.UnsupportedOperationException:addView(View,LayoutParams)在AdapterView中不受支持

所以我做了大量的研究,并find了很多可能的原因和解决办法。 没有一件事改变了。 我的适配器代码目前是:

public class WeatherAdapter extends BaseAdapter { private Context context; private List<Weather> weatherList; public WeatherAdapter(Context context, int rowResID, List<Weather> weatherList ) { this.context = context; this.weatherList = weatherList; } public int getCount() { return weatherList.size(); } public Object getItem(int position) { return weatherList.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { Weather weather = weatherList.get(position); //LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(R.layout.weather_row, null, true); TextView cityControl = (TextView)v.findViewById( R.id.city ); TextView temperatureControl = (TextView)v.findViewById( R.id.temperature ); ImageView skyControl = (ImageView)v.findViewById( R.id.sky ); return v; } } 

所以我试了一下把注射器的注意方式和目前的注释掉了。 我曾尝试通过“父”来夸大和空,并通过“真”,“假”,完全省略最后一个参数。 他们都没有工作,而我迄今发现的所有例子都是从2008年开始的,我感觉有些过时了。

如果有人可以帮助,那么我很乐意解决这个问题。

我也是一个初学者,所以拿一点盐的这个答案 – 如果它不工作,继续和谷歌一些。 不熟悉AdapterView因为我传统上有一个ListViewGridView和一个自定义适配器扩展BaseAdapter然后listView.setAdapter(myCustomAdapter)

你可以尝试在WeatherAdapter类中做这样的事情:

 public void addToList(Weather mWeather) { weatherList.add(mWeather); } 

然后在调用WeatherAdapter的类中:

 weatherAdapter.addToList(weatherToAdd); weatherAdapter.notifyDataSetChanged(); 

你也需要在getView方法中进行更多的优化:

http://www.youtube.com/watch?v=wDBM6wVEO70

我相信这条线是错的:

 View v = inflater.inflate(R.layout.weather_row, null, true); 

您需要改为:

 View v = inflater.inflate(R.layout.weather_row, parent, false); 

虚假使膨胀的视图独立于父,而不是附加到它,这非常奇怪似乎是AdapterView视图内自定义视图的公认的devise。 为什么这是这样,我觉得非常莫名其妙,但上面的模式为我工作。

对于AdaptertView addView方法:

void addView(View child)

此方法不受支持,并在调用时引发UnsupportedOperationException。“(来自Android文档)

可能膨胀过程调用addView方法,这是不可能从一个AdapterView ,或它的AdapterView

从文档:

“Adapter对象充当AdapterView和该视图底层数据之间的桥梁,Adapter提供对数据项的访问,Adapter也负责为数据集中的每个项目创build一个View。

我认为膨胀操作可以从一个简单的Activity来完成,这个简单的Activity可以模拟你的视图和所有其他操作,例如检索数据并在其他类中显示数据。

希望它会有帮助!

@ Axel22的答案是关键,但是还有一些其他的东西从你的代码中遗漏了。 首先,您应该扩展BaseAdapter或ArrayAdapter,具体取决于您的偏好。 其次,你想要使用ViewHolder来避免过多地调用findViewById,最重要的是回收View。

 private Class ViewHolder { public TextView cityControl; public TextView temperatureControl; public ImageView skyControl; public ViewHolder(TextView cityControl, TextView temperatureControl, ImageView skyControl) { this.cityControl = cityControl; this.temperatureControl = temperatureControl; this.skyControl = skyControl; } 

您的getView函数可以回收视图并使用ViewHolder类,如下所示:

 public View getView(int position, View convertView, ViewGroup parent) { Weather weather = weatherList.get(position); // This is how you attempt to recycle the convertView, so you aren't // needlessly inflating layouts. View v = convertView; ViewHolder holder; if (null == v) { v = LayoutInflater.from(getContext()).inflate(R.layout.weather_row, parent, false); TextView cityControl = (TextView)v.findViewById( R.id.city ); TextView temperatureControl = (TextView)v.findViewById( R.id.temperature ); ImageView skyControl = (ImageView)v.findViewById( R.id.sky ); holder = new ViewHolder(cityControl, temperatureControl, skyControl); v.setTag(holder); } else { holder = (ViewHolder) v.getTag(); } holder.cityControl.setText("Metropolis"); holder.temperatureControl.setText("78"); holder.skyControl.setImageResource(R.drawable.daily_planet); return v; 

}

对于更多的例子(和其他优化技巧),请参阅此博客文章 (或只是谷歌的ViewHolder)。