Cannot use LayoutInflater in user adapter

I am writing a custom adapter to populate a list with 3 text fields per line. For this, I found a pretty sample code, but the one that seemed the best was: http://www.anddev.org/custom_widget_adapters-t1796.html

After a few small tweaks to fix some problems with the compiler with the latest Android SDK, I got it just to get an exception:

ERROR / AndroidRuntime (281): java.lang.UnsupportedOperationException: addView (View, LayoutParams) is not supported in AdapterView

So, I did a lot of research and found many possible causes and corrections for this. None of this has changed. My adapter code now:

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; } } 

So, I tried to comment on the way to get a scammer, and currently it is not framed. I tried passing “parent” to inflate as well as “zero”, and passed “true”, “false” and completely excluded the last parameter. None of them worked, and all the examples that I have found so far have been since 2008, which I feel is a bit outdated.

If anyone can help with this, I would happily solve the problem.

+7
android android-layout listview android-xml android-adapter
Nov 29 '10 at 17:29
source share
4 answers

I'm also a newbie, so take this answer with a pinch of salt - if that doesn't work, go and google a little more. Not familiar with AdapterView , since I traditionally have a ListView or GridView , and the custom adapter is expanded with BaseAdapter and then listView.setAdapter(myCustomAdapter) .

You can try to do something like this inside the WeatherAdapter class:

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

Then in the class that calls the WeatherAdapter :

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

You also need to optimize it more in the getView method:

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

+6
Jan 19 2018-11-11T00:
source share
— -

I believe this line is to blame:

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

You need instead:

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

false makes the inflated view independent of the parent, not tied to it, which very strange seems to be the accepted design for custom views in AdapterView s. Why this is so, I find it completely incomprehensible, but the sample above worked for me.

+16
Jun 21 '11 at 2:01
source share

For the AdaptertView addView method:

void addView (View child)

This method is not supported and throws an UnsupportedOperationException when (from the Android documentation)

The pumping procedure probably calls the addView method, and this is not possible from the AdapterView or its AdapterView .

From the documentation:

“The Adapter object acts as a bridge between the adapter and the underlying data for this view. The adapter provides access to the Items data. The adapter is also responsible for creating a view for each item in the dataset.”

I think that the bloat operation can be done from a simple Activity that models your presentation and all other operations, such as retrieving data and displaying data in other classes.

Hope this will be helpful!

+3
May 28 '11 at 13:17
source share

@ The answer to Axel22 is key, but there are several other things in the code. First, you must expand either BaseAdapter or ArrayAdapter, depending on your preference. Secondly, you want to be able to use ViewHolder to avoid excessive calls to findViewById and (most importantly) to reuse your 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; } 

Your getView function can process views and use the ViewHolder class as follows:

 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; 

}

For finer examples (and other optimization tips) see this blog post (or just Google for ViewHolder).

+1
Sep 18 '13 at 16:02
source share



All Articles