David B
David B

Reputation: 3571

Android ListView BUG?

I am developing on Android 2.3.3 (Gingerbread) and I have this particular activity that displays 50 items in a ListView. The problem is that when the activity is started, the listview doesn't displays the items properly when I begun scrolling down in the ListView. There are misleading elements of the listview in which the position 12 should display "Title: 12", "Element: 12" instead of "Title: xx", "Element: xx", where xx -> 1 <= xx <= ELEMENT_SIZE. However, when I click on that position it displays the correct element.

The xml and source code are located below.

main.xml :

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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</LinearLayout>

child.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/childTextTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/childTextDetail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

ListViewDebugActivty

public class ListViewDebugActivity extends Activity {

    private final static int ELEMENT_SIZE = 50;
    private ListView listView;
    private List<Element> elements;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initialize();
        fillListView();
    }

    private void initialize() {     
        listView = (ListView) findViewById(R.id.listView);
        elements = new ArrayList<Element>();
    }

    private void fillListView() {
        final String elementTitle = "Title: ";
        final String elementDetail = "Detail: ";

        for(int index = 0; index < ELEMENT_SIZE; index ++) {
            elements.add(new Element(elementTitle + (index + 1), elementDetail + (index + 1)));
        }

        listView.setAdapter(new ListViewAdapter(this, R.layout.child, elements));
        listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
                Element element = elements.get(position);
                String message = position + " = " + element.getTitle() + " : " + element.getDetail();
                Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG).show();
            }
        });
    }

    private class Element {

        private String title, detail;

        public Element(String title, String detail) {
            this.title = title;
            this.detail = detail;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }

    }

    private class ListViewAdapter extends ArrayAdapter<Element> {

        private List<Element> objects;
        private TextView childTitle, childDetail;

        public ListViewAdapter(Context context, int layout, List<Element> objects) {
            super(context, layout, objects);
            this.objects = objects;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Element element = objects.get(position);
            if(convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.child, null);
                childTitle = (TextView) convertView.findViewById(R.id.childTextTitle);
                childDetail = (TextView) convertView.findViewById(R.id.childTextDetail);
            }
            if(element != null && convertView != null) {
                childTitle.setText(element.getTitle());
                childDetail.setText(element.getDetail());
            }

            return convertView;
        }

    }

}

Thanks in advance.

Upvotes: 1

Views: 865

Answers (2)

jeet
jeet

Reputation: 29199

change line:

if(element != null && convertView != null) {
                childTitle.setText(element.getTitle());
                childDetail.setText(element.getDetail());
            }

to

if(convertView == null) {
            convertView = getLayoutInflater().inflate(R.layout.child, null);

        }
        if(onvertView != null)
        {
             childTitle = (TextView) convertView.findViewById(R.id.childTextTitle);
             childDetail = (TextView) convertView.findViewById(R.id.childTextDetail);
             if(element != null ) {
                   childTitle.setText(element.getTitle());
             }
        }

Upvotes: 0

josephus
josephus

Reputation: 8304

I won't be lecturing about ViewHolders, but for now, moving your childTitle and childDetail instantiation inside the getView method should fix the problem you're having. If you find that you want more speed and efficiency in your listview, click on the link.

Upvotes: 2

Related Questions