Невозможно использовать LayoutinFlater в пользовательском адаптере

StackOverflow https://stackoverflow.com/questions/4306324

Вопрос

Я собираюсь написать пользовательский адаптер, чтобы заполнить ListView 3 TextView за строку. Я нашел немало примеров кода для этого, но тот, который казался лучшим, был в: 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;
    }

}

Поэтому я попробовал закомментированный способ получить усердку и в настоящее время не начнут. Я попытался пропустить «родитель», чтобы раздуть, а также NULL, и передал «истину», «False» и полностью пропустил последний параметр. Ни один из них не работал, и все примеры, которые я нашел до сих пор, были с 2008 года, которые, как я чувствую, немного устарели.

Если бы кто -то мог помочь с этим, я хотел бы решить проблему.

Это было полезно?

Решение

Я новичок также так взять этот ответ с щепоткой соли - если это не сработает, двигайтесь и Google еще. Не знаком с AdapterView Поскольку у меня традиционно есть ListView или GridView и пользовательский адаптер расширил 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с. Почему это так, я нахожу совершенно сбивающим с толку, но приведенный выше шаблон сработал для меня.

Для AdaptertView addView Метод:

void AddView (просмотр ребенка)

Этот метод не поддерживается и бросает UnsupportedOperationException при вызове. »(Из документации Android)

Вероятно, процедура раздувания вызывает addView метод, и это невозможно от AdapterView, или его AdapterView.

Из документации:

«Объект адаптера выступает в качестве моста между AdapterView и основными данными для этой точки зрения. Адаптер обеспечивает доступ к элементам данных. Адаптер также несет ответственность за создание каждого элемента в наборе данных».

Я думаю, что операция подувания может быть выполнена из простой деятельности, которая моделирует ваше представление и все другие операции, например, получение данных и отображение данных в других классах.

Надеюсь, это будет полезно!

Ответ @Axel22 - это ключ, но в вашем коде отсутствует еще несколько вещей. Во -первых, вы должны продлевать либо BaseAdapter, либо ArrayAdapter, в зависимости от ваших предпочтений. Во -вторых, вы хотите принять участие в использовании владельца, чтобы не делать чрезмерных вызовов для 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;

}

Для получения множества примеров (и других советов по оптимизации) см. этот пост в блоге (или просто Google для Viewholder).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top