Невозможно использовать LayoutinFlater в пользовательском адаптере
-
29-09-2019 - |
Вопрос
Я собираюсь написать пользовательский адаптер, чтобы заполнить 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:
Другие советы
Я считаю, что эта линия виновата:
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).