5

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     ) );
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
masum7
  • 822
  • 6
  • 17

5 Answers5

3

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

Community
  • 1
  • 1
masum7
  • 822
  • 6
  • 17
2

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

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Hi mate I tried with that.. but still facing the same issue. I have put a Log.v inside the getView. It seems the getView is called with 0 09-11 02:40:13.006 2508-2508/ V/test﹕ #0 09-11 02:40:13.063 2508-2508/ V/test﹕ #0 09-11 02:40:13.066 2508-2508/ V/test﹕ #0 09-11 02:40:13.068 2508-2508/ V/test﹕ #0 09-11 02:40:13.070 2508-2508/ V/test﹕ #0 – masum7 Sep 11 '14 at 06:41
  • @masum7 it should work. Never put listview inside a scrollview. – Raghunandan Sep 11 '14 at 06:42
  • What alternate I have? Instead of ListView? I have to have a scrollview – masum7 Sep 11 '14 at 06:44
  • @masum7 you can add views as a header and footer to listview. ListView will scroll by itself. So never put a listview inside of scorllview – Raghunandan Sep 11 '14 at 06:45
  • Actually my main activity layout has many inputs and it needs scrollview – masum7 Sep 11 '14 at 06:47
  • @masum7 i hope you understand my previous comment. You can add all those views as a header or a footer to listview. But never put listview inside a scrollview. read the docs of both scrollview and listview further – Raghunandan Sep 11 '14 at 06:48
1

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;
    }
}
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
1

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".

Patrick
  • 1,227
  • 14
  • 17
0

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

sachithkn
  • 457
  • 1
  • 4
  • 13