Дублированные записи в ListView - программирование
Подтвердить что ты не робот

Дублированные записи в ListView

Я получаю дублированные элементы в ListView. Прокрутка назад и вниз иногда изменяет порядок элементов. Я googled и нашел много потоков, сообщающих об этой ошибке, но никто из них не помог мне в решении моей проблемы.

Вот мой код:

Активность:

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

4b9b3361

Ответ 1

Попробуйте следующее:

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

Объяснение: у вас есть дубликаты, потому что списки на объектах пользовательского интерфейса повторно используются. Вы должны повторно использовать convertView вместо того, чтобы создавать новый, если он не является нулевым. Конечно, вы несете ответственность за установку соответствующего значения для повторного использования экземпляра. В противном случае значение осталось от последнего "использования".

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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