无法在自定义适配器中使用layoutinflater
-
29-09-2019 - |
题
我正在考虑编写一个自定义适配器,以填充每行3个文本视图的ListView。我发现了很多示例代码可以做到这一点,但是看起来最好的代码是: http://www.anddev.org/custom_widget_adapters-t1796.html
经过一些小调整以解决最新的Android SDK解决一些编译器问题之后,我开始运行它,只是为了获得例外:
错误/androidruntime(281):java.lang.unsupportedoperationException:addView(view,layoutparams)不支持AdapterView
因此,我做了很多研究,并为此找到了很多可能的原因和解决方案。这些都没有改变。我的适配器代码当前是:
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;
}
}
因此,我尝试了评论的方法来获取充气者,以及目前的注释。我试图通过“父”和零,并传递“ true”,“ false”,并完全省略最后一个参数。它们都没有工作,到目前为止,我发现的所有例子都是从2008年开始的,我感觉到这一点已经过时了。
如果有人能帮助您,那么我很想解决这个问题。
解决方案
我也是一个初学者,所以用少许盐来接受这个答案 - 如果它不起作用,请继续搜索更多。不熟悉 AdapterView
因为我传统上有一个 ListView
或者 GridView
和一个自定义适配器扩展了 BaseAdapter
进而 listView.setAdapter(myCustomAdapter)
.
您可以尝试在内部做这样的事情 WeatherAdapter
班级:
public void addToList(Weather mWeather) {
weatherList.add(mWeather);
}
然后在呼叫的课堂上 WeatherAdapter
:
weatherAdapter.addToList(weatherToAdd);
weatherAdapter.notifyDataSetChanged();
另外,您需要在GetView方法中进行更多优化:
其他提示
我相信这条线是错误的:
View v = inflater.inflate(R.layout.weather_row, null, true);
您需要:
View v = inflater.inflate(R.layout.weather_row, parent, false);
错误使膨胀的视图独立于父母,而不是附属于父母,这似乎很奇怪地是在内部接受的自定义视图的设计 AdapterView
s。为什么这样做,我感到非常困惑,但是上面的模式对我有用。
为了 AdaptertView addView
方法:
void addview(查看孩子)
该方法不支持并在调用时会引发无pupportedoperationException。”(摘自Android文档)
大概是夸大程序称 addView
方法,这是不可能的 AdapterView
, ,或它 AdapterView
.
从文档中:
“适配器对象充当适配视图与该视图的基础数据之间的桥梁。适配器提供对数据项的访问。适配器还负责对数据集中的每个项目进行视图”。
我认为可以通过简单的活动来完成膨胀操作,该活动对您的视图和所有其他操作进行建模,例如检索数据并在其他类中显示数据。
希望它会有所帮助!
@axel22的答案是关键,但是您的代码中还有其他一些内容。首先,根据您的喜好,您应该扩展Baseadapter或ArrayAdapter。其次,您想练习使用视图持有人来避免过多的呼叫来查找ViewByid,并(最重要的是)回收您的视图。
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;
}
对于更多示例(和其他优化提示),请参见 这篇博客文章 (或者只是Google for Viewholder)。