简体   繁体   中英

Adapter getView is called multiple times with position 0

I am facing some problem for rendering ListView from a dynamic layout. I don't know why the getView is called only with position 0 and several times!

I searched over internet and stackoverflow but cannot find a suitable answer.

I am actually trying to do a demo of this: http://www.framentos.com/en/android-tutorial/2012/07/16/listview-in-android-using-custom-listadapter-and-viewcache/

Notably, my main layout file is surrounded by scrollbar.

main activity layout file:

    <ListView
        android:id="@+id/city_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/questionsList"
        android:paddingTop="20sp" >
    </ListView>

My layout file for list view:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="80dip" >

        <ImageView
            android:id="@+id/ImageCity"
            android:layout_width="90sp"
            android:layout_height="90sp" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_toRightOf="@id/ImageCity"
            android:orientation="vertical"
            android:paddingLeft="10sp">

            <TextView
                android:id="@+id/cityName"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="25sp" />

            <TextView
                android:id="@+id/cityLinkWiki"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:autoLink="web"
                android:textSize="15sp" />
        </LinearLayout>

    </RelativeLayout>

Adapter class:

    import com.incidentreport.app.classes.objects.City;

    public class CityListAdapter extends ArrayAdapter{

        private int resource;
        private LayoutInflater inflater;
        private Context context;

        public CityListAdapter ( Context ctx, int resourceId, List objects) {

            super( ctx, resourceId, objects );
            resource = resourceId;
            inflater = LayoutInflater.from( ctx );
            context=ctx;
        }

        @Override
        public View getView ( int position, View convertView, ViewGroup parent ) {

            Log.v("adapter", "pos: " + position + "#" + resource);
            /* create a new view of my layout and inflate it in the row */

            convertView = ( RelativeLayout ) inflater.inflate( resource, null );

            /* Extract the city's object to show */
            City city = (City)getItem( position );

            /* Take the TextView from layout and set the city's name */
            TextView txtName = (TextView) convertView.findViewById(R.id.cityName);

            txtName.setText(city.getName());

            /* Take the TextView from layout and set the city's wiki link */
            TextView txtWiki = (TextView) convertView.findViewById(R.id.cityLinkWiki);
            txtWiki.setText(city.getUrlWiki());

            /* Take the ImageView from layout and set the city's image */
            ImageView imageCity = (ImageView) convertView.findViewById(R.id.ImageCity);

            return convertView;
        }
    }

main activity code snipps:

    List listCity= new ArrayList();

    listCity.add(new City("London","http://en.wikipedia.org/wiki/London","london"));
    listCity.add(new City("Rome","http://en.wikipedia.org/wiki/Rome","rome"));
    listCity.add(new City("Paris","http://en.wikipedia.org/wiki/Paris","paris"));

    ListView listViewCity = ( ListView ) findViewById( R.id.city_list);

    listViewCity.setAdapter( new CityListAdapter(this, R.layout.layout_city, listCity     ) );

Okay, I figured out the issue by expanding ListView as much possible. Meaning to say, giving a dynamic full height so that all item becomes visible.

I followed the below solution:

Calculate the size of a list view or how to tell it to fully expand

Use a ViewHolder pattern for better performance.

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

static class ViewHolder
{
     TextView txtName,txtWiki;
     ImageView imageCity; 
}

Change getView to

    @Override
    public View getView ( int position, View convertView, ViewGroup parent ) {

        ViewHolder holder;
        if(convertView == null)
        {

        convertView = ( RelativeLayout ) inflater.inflate( resource, parent, false );
        holder = new ViewHolder();
        holder.txtName = (TextView) convertView.findViewById(R.id.cityName);  
        holder.txtWiki = (TextView) convertView.findViewById(R.id.cityLinkWiki);  
        holder.imageCity = (ImageView) convertView.findViewById(R.id.ImageCity);
        convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag(); 
        } 

        City city = (City)getItem( position );

        holder.txtName.setText(city.getName());
        holder.txtWiki.setText(city.getUrlWiki());

        return convertView;
    }

ListView recyclues view's. You may also want to read

How ListView's recycling mechanism works

Try this way,hope this will help you to solve your problem.

public class CityListAdapter extends BaseAdapter{
    private Context context;
    private List objects;

    public CityListAdapter ( Context context, int resourceId, List objects) {
        this.context=context;
        this.objects=objects;

    }

    @Override
    public int getCount() {
        return objects.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Object getItem(int position) {
        return objects.get(position);
    }

    @Override
    public View getView ( int position, View convertView, ViewGroup parent ) {
        ViewHolder holder;

        if(convertView==null){
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.layout_city,null);
            holder.txtName = (TextView) convertView.findViewById(R.id.cityName);
            holder.txtWiki = (TextView) convertView.findViewById(R.id.cityLinkWiki);
            holder.imageCity = (ImageView) convertView.findViewById(R.id.ImageCity);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.txtName.setText(((City)getItem(position)).getName());
        holder.txtWiki.setText(((City)getItem(position)).getUrlWiki());

        return convertView;
    }

    class ViewHolder{
        TextView txtName;
        TextView txtWiki;
        ImageView imageCity;
    }
}

I ran into this same issue. My list view is mostly working, but there's a certain sequence of actions which will make certain items disappear. Clicking on them afterwards causes a NullPointerException.

Here's the steps to reproduce the bug:

  1. Drag an item to the top.
  2. Drag another item up or down.
  3. The item at the top will disappear.
  4. Drag another item up or down.
  5. The top item will reappear.
  6. Behavior continues if you go to step 2

After debugging, I found that my StableArrayAdapter.getView() method was being called twice, only for the blank item at the top of the list.

To fix it, per masum7's answer, I set the layout_height for my DynamicListView to "wrap_content".

Try to get layout inflater as LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE); This may work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM