2011-11-24 9 views
17

Tôi nhận được các mục trùng lặp trong một ListView. Cuộn xuống và xuống đôi khi thay đổi thứ tự mục. Tôi googled và tìm thấy nhiều chủ đề báo cáo lỗi này, nhưng không ai trong số họ đã giúp tôi trong việc sửa chữa vấn đề của tôi.Mục nhập trùng lặp trong ListView

Đây là mã của tôi:

Hoạt động:

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


} 

Bằng cách này, đầu ra là:

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 

Kính trọng, ProgVal

Trả lời

32

Hãy thử điều này:

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

Giải thích: bạn có các bản sao vì danh sách trên Android đối tượng tái sử dụng giao diện người dùng. Bạn dự kiến ​​sẽ sử dụng lại convertView thay vì tạo một cái mới nếu nó không phải là rỗng. Tất nhiên, bạn có trách nhiệm đặt một giá trị thích hợp cho cá thể đang được sử dụng lại. Nếu không, giá trị còn lại từ "sử dụng" cuối cùng.

+0

Ok, tôi đã nhận nó. Tôi nghĩ rằng nó chỉ tái sử dụng đối tượng cho cùng một mục, và không phải người khác. Tuy nhiên, thanh cuộn bây giờ sẽ lớn hơn và nhỏ hơn khi tôi cuộn, tùy thuộc vào chiều cao của mục hiện được hiển thị. –

+0

@Arhimed Bạn có thể giải thích phần "Giải thích" chi tiết hơn không. Tôi bị mắc kẹt với vấn đề này trong một thời gian dài. – AbhishekB

+1

@abhishekb: vui lòng kiểm tra thông tin này để biết chi tiết - http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ –

0

Đề xuất - thêm câu lệnh nhật ký sau title.setText và viết giá trị thu được từ getTitle(). Bạn có thể tìm hiểu lý do tại sao bạn nhận được các mục trùng lặp.

2

Chế độ xem danh sách không đảm bảo tính duy nhất của các mục bạn được thêm ở đó. Đó là trách nhiệm của bạn. Bạn đang sử dụng ArrayList để lưu trữ các mục và nó có thể lưu trữ nhiều mục trùng lặp như bạn muốn.

Nếu bạn muốn loại bỏ bản sao đưa các mục của bạn vào thiết lập và sau đó vào danh sách một lần nữa:

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

Các LinkedHashSet sẽ loại bỏ bản sao bảo quản trật tự ban đầu của mặt hàng, ArrayList sẽ cho phép các yếu tố truy cập vào vị trí.

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