7

我正在研究编写自定义适配器来填充每行3个textviews的listview。我发现了相当多的示例代码来做到这一点,但似乎最好的代码是:http://www.anddev.org/custom_widget_adapters-t1796.html无法在自定义适配器中使用LayoutInflater

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

ERROR/AndroidRuntime(281):java.lang.UnsupportedOperationException:addView(查看,的LayoutParams)不支持的适配器视图

所以我做了很多的研究,发现了很多可能的原因和修复。没有一件事改变了。我的适配器代码当前是:

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年开始的,我的感觉有些过时。

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

回答

6

我也是初学者,所以拿一点盐加这个答案 - 如果不行的话,继续前进,谷歌更多。不熟悉AdapterView,因为我传统上有一个ListViewGridView和一个自定义适配器扩展了BaseAdapter,然后listView.setAdapter(myCustomAdapter)

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

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

然后:

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

还需要更多的优化它在getView方法:

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

3

对于AdaptertView addView方法:

无效addView(查看孩子)

不支持此方法和 抛出 UnsupportedOperationException异常时 称为”(从Android文档)

充气程序可能会调用addView方法,但这不可能从AdapterView或其AdapterView

从文档:

“适配器对象作为一个AdapterView和该视图的 底层数据之间的桥梁 。 适配器提供对数据 项目的访问。该适配器也是在 数据组中的”为每个项目视图负责 。

我认为充气操作可以从一个简单的活动来做到这一点的模型视图和所有其他操作,例如,检索数据并显示在其他类别的数据

希望这将有助于

16

我相信这条线是有过错:

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

你需要,而不是:

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

假使膨胀的视图独立于父,不重视它,这很奇怪,似乎是内AdapterView S表示自定义视图接受设计的。为什么这样,我觉得非常莫名其妙,但上面的模式对我很有用。

+2

当使用`AdapterView`时,你希望你的视图独立于父对象,`getView()`负责将它附加到父对象上。 – 2013-02-05 01:01:27

1

@Axel22的答案是关键,但是还有一些其他的东西在代码中缺失。首先,您应该扩展BaseAdapter或ArrayAdapter,具体取决于您的偏好。其次,您想要使用ViewHolder来避免过多调用findViewById,并且(最重要的是)回收视图。

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; 

}

对于吨以上的例子(和其他优化技巧),见this blog post(或只是谷歌为ViewHolder)。

相关问题