2011-11-24 290 views
17

我在ListView中獲得重複的項目。往回滾動有時會改變項目順序。 我搜索了一下,發現很多線程都報告了這個錯誤,但是他們都沒有幫我解決我的問題。ListView中的重複條目

這裏是我的代碼:

活動:

package com.github.progval.SeenDroid; 

import java.util.ArrayList; 
import java.util.List; 

import com.github.progval.SeenDroid.lib.Connection; 
import com.github.progval.SeenDroid.lib.Message; 
import com.github.progval.SeenDroid.lib.MessageFetcher; 
import com.github.progval.SeenDroid.lib.Query.ParserException; 

import android.app.Activity; 
import android.app.ListActivity; 
import android.content.SharedPreferences; 
import android.os.Bundle; 

public class ShowUserActivity extends ListActivity { 
    private Connection connection; 

    public ArrayList<Message> listMessages = new ArrayList<Message>(); 
    public MessageAdapter adapter; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.profile); 
     this.connection = new Connection(); 
     this.setTitle(R.string.homefeed_title); 


     this.listMessages = new MessageFetcher(this.connection).fetchUser(); 
     this.bindUi(); 
    } 

    private void bindUi() { 
     this.adapter = new MessageAdapter(this, this.listMessages); 
     this.setListAdapter(adapter); 

     // TODO Bind buttons 
    } 
} 

MessageAdapter:

package com.github.progval.SeenDroid; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.zip.Inflater; 

import com.github.progval.SeenDroid.lib.Message; 

import android.content.Context; 
import android.text.Layout; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.webkit.WebView; 
import android.widget.ArrayAdapter; 
import android.widget.BaseAdapter; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class MessageAdapter extends BaseAdapter { 
    private Context context; 
    private List<Message> items = new ArrayList<Message>(); 
    private int lastPosition = 0; 

    public MessageAdapter(Context context, List<Message> items) { 
     super(); 
     this.context = context; 
     this.items = items; 
    } 

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

     if (null == convertView) { 
      LinearLayout view; 
      view = (LinearLayout) LinearLayout.inflate(this.context, R.layout.message, null); 
      Log.d("SeenDroid", String.format("Get view %d", position)); 
      TextView title = new TextView(view.getContext()); 
      title.setText(this.items.get(position).getTitle()); 
      view.addView(title); 
      return view; 
     } else { 
      return convertView; 
     } 
    } 


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


    @Override 
    public Object getItem(int location) { 
     return this.items.get(location); 
    } 


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


} 

順便說一句,輸出爲:

D/SeenDroid(30939): Get view 0 
D/SeenDroid(30939): Get view 1 
D/SeenDroid(30939): Get view 2 
D/SeenDroid(30939): Get view 3 
D/SeenDroid(30939): Get view 4 
D/SeenDroid(30939): Get view 5 
D/SeenDroid(30939): Get view 6 
D/SeenDroid(30939): Get view 7 
D/SeenDroid(30939): Get view 8 
D/SeenDroid(30939): Get view 0 
D/SeenDroid(30939): Get view 16 

問候, ProgVal

回答

32

試試這個:

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

    if (null == convertView) { 
     LinearLayout view = (LinearLayout) LinearLayout.inflate(this.context, 
      R.layout.message, null); 
     Log.d("SeenDroid", String.format("Get view %d", position)); 
     TextView title = new TextView(view.getContext()); 
     title.setText(this.items.get(position).getTitle()); 
     view.addView(title); 
     return view; 
    } else { 
     LinearLayout view = (LinearLayout) convertView; 
     TextView title = (TextView) view.getChildAt(0); 
     title.setText(this.items.get(position).getTitle()); 
     return convertView; 
    } 
} 

說明:你有重複的,因爲在Android重用UI對象名單。預計您將重用convertView,而不是創建一個新的如果它不爲空。當然,您有責任爲正在重用的實例設置適當的值。否則,該值將從最後一個「用法」中留下。

+0

好吧,我知道了。我認爲這只是重複使用對象的同一項目,而不是其他人。 但是,當我滾動時,滾動條現在變得越來越小,這取決於當前顯示的項目的高度。 –

+0

@Arhimed你能否詳細解釋一下「解釋」部分。我很長時間以來一直困擾着這個問題。 – AbhishekB

+1

@abhishekb:請查看詳情 - http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ –

0

建議 - 在title.setText後面添加一個日誌語句並寫入從getTitle()獲得的值。你可能會知道爲什麼你會得到重複的條目。

2

ListView不保證您添加的項目的唯一性。這是你的責任。您正在使用ArrayList來存儲項目,並且可以根據需要存儲儘可能多的重複項目。

如果你想刪除重複的把你的物品放入集,然後將列表中再次:

listMessages = new ArrayList<Messages>(new LinkedHashSet<Message>(listMessages))

LinkedHashSet將刪除重複保留項目的初始訂單,ArrayList將允許按位置訪問元素。

4
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) context 
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View gridView; 
    if (convertView == null) { 
     gridView = new View(context); 
    } else { 
     gridView = (View) convertView; 
    } 
    gridView = inflater.inflate(R.layout.worker_listmain, null); 
    // your source code here!!! Run 100% 
    // I got this problem also, I found out the way to solve it! 
    // Please use my source code :D SIMPLE is PERFECT :D 
    return gridView; 
}