Unable to use LayoutInflater in custom adapter

后端 未结 4 1118
太阳男子
太阳男子 2021-01-02 10:48

I\'m looking into writing a custom adapter to populate a listview with 3 textviews per line. I\'ve found quite a bit of example code to do this, but the one that seemed the

相关标签:
4条回答
  • 2021-01-02 11:07

    I'm a beginner also so take this answer with a pinch of salt - if it doesn't work, move on and Google some more. Not familiar with AdapterView since I traditionally have a ListView or GridView and a custom Adapter extended off a BaseAdapter and then listView.setAdapter(myCustomAdapter).

    You could try making something like this inside the WeatherAdapter class:

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

    Then in the class that calls WeatherAdapter:

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

    Also you need to optimize it more in the getView method:

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

    0 讨论(0)
  • 2021-01-02 11:07

    For the AdaptertView addView method:

    void addView(View child)

    This method is not supported and throws an UnsupportedOperationException when called." (From Android documentation)

    Probably the inflating procedure calls the addView method and this is not possible from an AdapterView, or its AdapterView.

    From the documentation:

    "An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set".

    I think that the inflating operation could be done from a simple Activity that models your view and all other operations, for example, retrieving data and showing data in other classes.

    Hope it will be helpful!

    0 讨论(0)
  • 2021-01-02 11:18

    @Axel22's answer is key, but there are a few other things missing from your code. First, you should be extending either BaseAdapter or ArrayAdapter, depending on your preference. Second, you want to get in the practice of using a ViewHolder to avoid making excessive calls to findViewById, and (most importantly) recycling 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 recycle views and utilize 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 tons more examples (and other optimization tips), see this blog post (or just google for ViewHolder).

    0 讨论(0)
  • 2021-01-02 11:32

    I believe this line is at fault:

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

    You need instead:

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

    The false makes the inflated view independent of the parent, not attached to it, which very oddly seems to be the accepted design for custom views within AdapterViews. Why this is so, I find utterly baffling, but the pattern above worked for me.

    0 讨论(0)
提交回复
热议问题