8

我正在考虑编写一个自定义适配器来填充每行 3 个文本视图的列表视图。我找到了相当多的示例代码来执行此操作,但似乎最好的一个位于: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;
    }

}

所以我尝试了获取充气机的注释方法,以及当前未注释的方法。我尝试将“父级”传递给 inflate 和 null,并传递“true”、“false”并完全省略最后一个参数。他们都没有奏效,到目前为止我发现的所有例子都是2008年的,我觉得有点过时了。

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

4

4 回答 4

16

我相信这条线有问题:

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

你需要:

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

false 使膨胀的视图独立于父视图,而不是附加到它,这很奇怪似乎是AdapterViews 中自定义视图的公认设计。为什么会这样,我觉得完全莫名其妙,但上面的模式对我有用。

于 2011-06-21T02:01:04.700 回答
6

我也是一个初学者,所以对这个答案持怀疑态度 - 如果它不起作用,请继续并谷歌更多。不熟悉,AdapterView因为我传统上有一个ListVieworGridView和一个从 a BaseAdapterand then扩展而来的自定义适配器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

于 2011-01-19T03:49:28.753 回答
3

对于AdaptertView addView方法:

无效的addView(查看孩子)

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

可能是膨胀过程调用了该addView方法,而这不可能从 aAdapterView或它的AdapterView.

从文档中:

“适配器对象充当适配器视图和该视图的基础数据之间的桥梁。适配器提供对数据项的访问。适配器还负责为数据集中的每个项目创建视图”。

我认为膨胀操作可以通过一个简单的 Activity 来完成,该 Activity 对您的视图和所有其他操作进行建模,例如,检索数据和在其他类中显示数据。

希望它会有所帮助!

于 2011-05-28T13:17:28.747 回答
1

@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)。

于 2013-09-18T16:02:48.393 回答