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 listMessages = new ArrayList();
    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 items = new ArrayList();
    private int lastPosition = 0;

    public MessageAdapter(Context context, List 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

5 答え

これを試して:

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

Explanation: you got the duplicates because lists on Android reuse UI objects. You are expected to reuse convertView rather than create a new one if it is not null. Of course, you are responsible to set an appropriate value to the instance being reused. Otherwise the value is left from the last "usage".

32
追加された
@Arhimed「説明」の部分をより詳しく説明できますか?私は長い間この問題に悩まされています。
追加された 著者 AbhishekB,
@abhishekb:詳細はこちらをご確認ください - lucasr.org/ 2012/04/05/performance-tips for androids-listview
追加された 著者 Vit Khudenko,
はい、分かりました。私はそれが同じアイテムのものだけを再利用していると思っていました。ただし、現在表示されている項目の高さに応じて、スクロールするとスクロールバーが大きくなったり小さくなったりするようになりました。
追加された 著者 Valentin Lorentz,
ありがとう@Arhimedあなたは私の一日を救った。
追加された 著者 Rahul Vats,
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
追加された

ListViewは、そこに追加された項目の一意性を保証しません。それはあなたの責任です。アイテムを格納するために ArrayList を使用していて、必要な数の重複アイテムを格納できます。

重複を削除したい場合は、アイテムをセットしてからリストに追加します。

listMessages = new ArrayList(new LinkedHashSet(listMessages))

LinkedHashSet はアイテムの初期順序を保持する重複を削除し、 ArrayList は位置によってアクセス要素を許可します。

2
追加された

提案 - title.setTextの後にログ文を追加し、getTitle()から取得した値を書き込みます。なぜあなたは重複したエントリを取得しているのか分かるかもしれません。

0
追加された

あなたはListAdapterでViewHolder paradigmaを使うべきです

a nice example can be found here: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

0
追加された
バインドビューの新しいビューで何をすべきか、タグホルダーパターンを試しましたが、それはまだ重複しています。
追加された 著者 Skynet,