Rozwijam się na Androidzie 2.3.3 (Gingerbread) i mam tę szczególną aktywność, która wyświetla 50 elementów w ListView. Problem polega na tym, że po uruchomieniu działania widok listy nie wyświetla poprawnie elementów, gdy zacząłem przewijać w dół w widoku ListView. W liście występują elementy wprowadzające w błąd, w których pozycja 12 powinna wyświetlać „Tytuł: 12”, „Element: 12” zamiast „Tytuł: xx”, „Element: xx”, gdzie xx -> 1 <= xx <= ELEMENT_SIZE . Jednak po kliknięciu tej pozycji wyświetla właściwy element.

XML i kod źródłowy znajdują się poniżej.

Główny.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>

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

    }

}

Z góry dziękuję.

1
David B 16 luty 2012, 14:53

2 odpowiedzi

Najlepsza odpowiedź

Nie będę wykładał o ViewHolders , ale na razie przeniesienie instancji childTitle i childDetail do metody getView powinno rozwiązać problem. Jeśli stwierdzisz, że potrzebujesz większej szybkości i wydajności w widoku listy, kliknij link.

2
josephus 16 luty 2012, 15:01

Zmień linię:

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

Do

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());
             }
        }
0
jeet 16 luty 2012, 15:16