notifyDataSetChange不是从自定义适配器工作(notifyDataSetChange

2019-07-21 16:27发布

当我重新填充我ListView ,我把从我具体的方法Adapter

问题

当我打电话updateReceiptsList从我的Adapter ,数据被刷新,但我ListView不反映更改。

问题

为什么我ListView显示新的数据时,我打电话notifyDataSetChanged

适配器

public class ReceiptListAdapter extends BaseAdapter {

    public List<Receipt> receiptlist;
    private Context context;
    private LayoutInflater inflater;
    private DateHelpers dateH;

    public ReceiptListAdapter(Activity activity, Context mcontext, List<Receipt> rl) {
        context = mcontext;
        receiptlist = rl;
        Collections.reverse(receiptlist);
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        dateH = new DateHelpers();
    }

    @Override
    public int getCount() {
        try {
            int size = receiptlist.size();
            return size;
        } catch(NullPointerException ex) {
            return 0;
        }
    }

    public void updateReceiptsList(List<Receipt> newlist) {
        receiptlist = newlist;
        this.notifyDataSetChanged();
    }

    @Override
    public Receipt getItem(int i) {
        return receiptlist.get(i);
    }

    @Override
    public long getItemId(int i) {
        return receiptlist.get(i).getReceiptId() ;
    }

    private String getPuntenString(Receipt r) {
        if(r.getPoints().equals("1")) {
            return "1 punt";
        }
        return r.getPoints()+" punten";
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;

        final Receipt receipt = receiptlist.get(position);
        ReceiptViewHolder receiptviewholder;
        Typeface tf_hn = Typeface.createFromAsset(context.getAssets(), "helveticaneue.ttf");        
        Typeface tf_hn_bold = Typeface.createFromAsset(context.getAssets(), "helveticaneuebd.ttf");

        if (vi == null) { //convertview==null
            receiptviewholder = new ReceiptViewHolder();
            vi = inflater.inflate(R.layout.view_listitem_receipt, null);
            vi.setOnClickListener(null);
            vi.setOnLongClickListener(null);
            vi.setLongClickable(false);
            receiptviewholder.shop = (TextView) vi.findViewById(R.id.tv_listitemreceipt_shop);
            receiptviewholder.date = (TextView) vi.findViewById(R.id.tv_listitemreceipt_date);
            receiptviewholder.price = (TextView) vi.findViewById(R.id.tv_listitemreceipt_price);
            receiptviewholder.points = (TextView) vi.findViewById(R.id.tv_listitemreceipt_points);
            receiptviewholder.shop.setTypeface(tf_hn_bold);
            receiptviewholder.price.setTypeface(tf_hn_bold);
            vi.setTag(receiptviewholder);
        }else{//convertview is not null
            receiptviewholder = (ReceiptViewHolder)vi.getTag();
        }

        receiptviewholder.shop.setText(receipt.getShop());
        receiptviewholder.date.setText(dateH.timestampToDateString(Long.parseLong(receipt.getPurchaseDate())));
        receiptviewholder.price.setText("€ "+receipt.getPrice());
        receiptviewholder.points.setText(getPuntenString(receipt));

        vi.setClickable(false);
        return vi;
    }

    public static class ReceiptViewHolder {
        public TextView shop;
        public TextView date;
        public TextView price;
        public TextView points;
    }

    public Object getFilter() {
        // XXX Auto-generated method stub
        return null;
    }

}

- 编辑:

找到解决方法

只是有一些功能代码我现在做的事:

listview.setAdapter( new ReceiptListAdapter(activity,mcontext, -new dataset-);

的作品,但它不应该如何工作。

Answer 1:

改变从你的方法

public void updateReceiptsList(List<Receipt> newlist) {
    receiptlist = newlist;
    this.notifyDataSetChanged();
}

public void updateReceiptsList(List<Receipt> newlist) {
    receiptlist.clear();
    receiptlist.addAll(newlist);
    this.notifyDataSetChanged();
}

所以,你保持相同的对象作为你的适配器的数据集。



Answer 2:

我有同样的问题,我也意识到这一点。 当我们创建适配器并将其设置为列表视图,列表视图将指向内存中的哪一个适配器保持,在这个对象数据会在列表视图显示某处对象。

adapter = new CustomAdapter(data);
listview.setadapter(adapter);

如果我们再次创建适配器对象与其他数据和notifydatasetchanged():

adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();

这将在列表视图不会影响到数据,因为该列表是指向不同的对象,这个对象并不知道在适配器新的对象什么,notifyDataSetChanged()影响什么。 因此,我们应该在改变对象的数据,并避免再次为适配器创建新对象



Answer 3:

正如我已经解释了这背后的问题的原因,以及如何处理它在一个不同的答案线程在这里 。 不过我在这里分享的解决方案总结。

的主要原因之一notifyDataSetChanged()将不会为你工作-是,

你的适配器失去参考列表

当创建和添加新的列表的Adapter 。 始终遵循以下原则:

  1. 初始化arrayList ,同时宣布全球范围内它。
  2. 列表对于空和空值进行检查,直接添加到适配器。 直接将适配器列表(不检查任何条件)。 适配器保证您您随时随地进行更改的数据arrayList会照顾它,却永远失去了参考。
  3. 随时修改ArrayList中本身的数据(如果你的数据完全是新的比你可以调用adapter.clear()arrayList.clear()其实之前将数据添加到列表中),但不设置适配器,即如果新数据在填充arrayList不仅仅是adapter.notifyDataSetChanged()

希望这可以帮助。



Answer 4:

也许尝试刷新的ListView:

receiptsListView.invalidate()

编辑:另一个想法进入了我的脑海里。 只是为了记录在案,尝试禁用列表视图缓存:

<ListView
    ...
    android:scrollingCache="false"
    android:cacheColorHint="@android:color/transparent"
    ... />


Answer 5:

我使用了同样的问题ListAdapter

我让Android Studio中实现我的方法,这是我得到了什么:

public class CustomAdapter implements ListAdapter {
    ...
    @Override
    public void registerDataSetObserver(DataSetObserver observer) {

    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {

    }
    ...
}

问题是,这些方法不调用super实现这样notifyDataSetChange永远不会被调用。

无论是手动删除这些替代或补充超级调用,它应该重新工作。

@Override
public void registerDataSetObserver(DataSetObserver observer) {
    super.registerDataSetObserver(observer);
}

@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
    super.unregisterDataSetObserver(observer);
}


Answer 6:

如果adapter设置为AutoCompleteTextView然后notifyDataSetChanged()不起作用。

需要它来更新适配器:

myAutoCompleteAdapter = new ArrayAdapter<String>(MainActivity.this, 
        android.R.layout.simple_dropdown_item_1line, myList);

myAutoComplete.setAdapter(myAutoCompleteAdapter);

请参阅: http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html



Answer 7:

添加该代码

runOnUiThread(new Runnable() { public void run() {
               adapter = new CustomAdapter(anotherdata);
            adapter.notifyDataSetChanged();
            }
        });


Answer 8:

class StudentAdapter extends BaseAdapter {
    ArrayList<LichHocDTO> studentList;

    private void capNhatDuLieu(ArrayList<LichHocDTO> list){
        this.studentList.clear();
        this.studentList.addAll(list);
        this.notifyDataSetChanged();
    }
}

你可以试试。 它为我工作



文章来源: notifyDataSetChange not working from custom adapter