2012-02-16 30 views
1

我正在開發Android 2.3.3(薑餅),我有這個特殊的活動,顯示在ListView 50項。問題是,當活動開始時,當我開始在ListView中向下滾動時,listview不會正確顯示這些項目。列表視圖中存在誤導性元素,其中位置12應該顯示「標題:12」,「元素:12」而不是「標題:xx」,「元素:xx」,其中xx-> 1 < = xx < = ELEMENT_SIZE ,但是,當我點擊該位置時,它顯示正確的元素。Android ListView BUG?

xml和源代碼位於下方。

的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; 
     } 

    } 

} 

在此先感謝。

回答

2

我不會講關於ViewHolders,但現在,在getView方法中移動childTitle和childDetail實例化應該可以解決您遇到的問題。 如果您發現在列表視圖中需要更多速度和效率,請點擊鏈接。

+0

我來試試呢。性能是我可以考慮的最佳解決方案。 – 2012-02-16 11:08:44

+0

這個解決方案非常棒。它幫助我加上卓越的表現。然而,最後一個與主要問題相似的元素存在問題。 – 2012-02-16 11:23:31

+0

但是您是否將實例化移動到getView()的內部? – josephus 2012-02-16 11:54:48

0

變線:

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

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()); 
      } 
     } 
+2

真的,你可以在初始化childTitle之前設置文本? – josephus 2012-02-16 11:03:39

+0

我認爲現在是正確的 – jeet 2012-02-16 11:05:31

+0

Ooops。抱歉。我的代碼可能會導致NullPointerException。但據我所知,當convertView爲null時,childTitle和childDetail也爲空否則其他情況。 – 2012-02-16 11:06:26