it-roy-ru.com

Дублированные записи в 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

17
Valentin Lorentz

Попробуй это:

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 повторно используют объекты пользовательского интерфейса. Ожидается, что вы будете повторно использовать convertView, а не создавать новый, если он не равен нулю. Конечно, вы обязаны установить соответствующее значение для повторного использования экземпляра. В противном случае значение остается от последнего «использования».

32
Vit Khudenko
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;
}
4
Chien_Khmt

ListView не гарантирует уникальность элементов, которые вы добавили туда. Это ваша ответственность. Вы используете ArrayList для хранения элементов, и он может хранить столько дублирующих элементов, сколько вы хотите.

Если вы хотите удалить дубликаты, поместите ваши элементы в набор, а затем снова в список:

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

LinkedHashSet удалит дубликаты, сохранив первоначальный порядок элементов, ArrayList позволит получить доступ к элементам по позиции. 

2
AlexR

Вы должны использовать парадигму ViewHolder в своем ListAdapter

хороший пример можно найти здесь: http://developer.Android.com/resources/samples/ApiDemos/src/com/example/Android/apis/view/List14.html

0
Michele

Предложение - добавьте оператор log после title.setText и запишите значение, полученное из getTitle (). Вы можете узнать, почему вы получаете повторяющиеся записи.

0
user994886