Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android notifyDataSetChange无法从自定义适配器工作_Android_Listview_Baseadapter_Notifydatasetchanged - Fatal编程技术网

Android notifyDataSetChange无法从自定义适配器工作

Android notifyDataSetChange无法从自定义适配器工作,android,listview,baseadapter,notifydatasetchanged,Android,Listview,Baseadapter,Notifydatasetchanged,当我重新填充我的列表视图时,我从我的适配器调用一个特定的方法 问题: public class ReceiptListAdapter extends BaseAdapter { public List<Receipt> receiptlist; private Context context; private LayoutInflater inflater; private DateHelpers dateH; public Receipt

当我重新填充我的
列表视图
时,我从我的
适配器
调用一个特定的方法

问题

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

}
当我从我的
适配器
调用
更新接收列表
时,数据会被刷新,但我的
列表视图
不会反映更改

问题

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

}
为什么我的
列表视图
在调用
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;
    }

}

工作正常,但不是它应该如何工作。

可能尝试刷新您的列表视图:

receiptsListView.invalidate()

编辑:另一个想法出现在我的脑海里。仅针对记录,尝试禁用列表视图缓存:


将您的方法从

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

public void updateReceiptsList(列表新建列表){
receiptlist.clear();
receiptlist.addAll(newlist);
this.notifyDataSetChanged();
}

因此,在适配器中保留与数据集相同的对象。

我也有同样的问题,我意识到了这一点。当我们创建适配器并将其设置为listview时,listview将指向适配器所在内存中的某个对象,该对象中的数据将显示在listview中

adapter = new CustomAdapter(data);
listview.setadapter(adapter);
如果我们再次使用另一个数据为适配器创建对象,并通知DataSetChanged():

这不会影响listview中的数据,因为列表指向不同的对象,该对象不知道适配器中的新对象,notifyDataSetChanged()不影响任何内容。
因此,我们应该更改对象中的数据,避免再次为适配器创建新对象

我在使用
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);
}

正如我已经解释了这个问题背后的原因,以及如何在不同的回答线程中处理它。我仍然在这里分享解决方案摘要

notifyDataSetChanged()
不适合您的主要原因之一是

适配器失去了对列表的引用

适配器中创建和添加新列表时
。始终遵循以下准则:

  • 在全局声明时初始化
    arrayList
  • 直接将列表添加到适配器,而不检查null和empty 价值观直接将适配器设置到列表中(不检查任何 条件)。适配器保证,无论您在何处 对
    arrayList的数据进行更改,它将处理该数据,但不会丢失
    参考资料
  • 始终修改arrayList本身中的数据(如果您的数据是全新的 然后可以调用
    adapter.clear()
    arrayList.clear()
    实际将数据添加到列表中),但不要设置适配器,即如果 新数据填充在
    arrayList
    中,而不仅仅是
    adapter.notifyDataSetChanged()

  • 希望这有帮助。

    添加此代码

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

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

    需要此更新适配器:

    myAutoCompleteAdapter = new ArrayAdapter<String>(MainActivity.this, 
            android.R.layout.simple_dropdown_item_1line, myList);
    
    myAutoComplete.setAdapter(myAutoCompleteAdapter);
    
    myAutoCompleteAdapter=new ArrayAdapter(MainActivity.this,
    android.R.layout.simple\u下拉列表\u项目\u 1行,myList);
    设置适配器(myAutoCompleteAdapter);
    
    请参阅:

    class StudentAdapter扩展BaseAdapter{
    ArrayList学生名单;
    私有无效capNhatDuLieu(ArrayList列表){
    this.studentList.clear();
    this.studentList.addAll(list);
    this.notifyDataSetChanged();
    }
    }
    
    你可以试试。它对我有用我也有同样的问题 但是我刚刚完成了

    你应该换成

    公共类ReceiptListAdapter扩展了BaseAdapter{
    公共列表接收列表;
    私人语境;
    私人充气机;
    私人约会助手dateH;
    私有列表receiptviewlist;
    public ReceiptListAdapter(活动、上下文mcontext、列表rl){
    上下文=mcontext;
    receiptlist=rl;
    receiptviewlist=新建ArrayList();
    receiptviewlist.clear();
    对于(int i=0;imyAutoCompleteAdapter = new ArrayAdapter<String>(MainActivity.this, 
            android.R.layout.simple_dropdown_item_1line, myList);
    
    myAutoComplete.setAdapter(myAutoCompleteAdapter);
    
    class StudentAdapter extends BaseAdapter {
        ArrayList<LichHocDTO> studentList;
    
        private void capNhatDuLieu(ArrayList<LichHocDTO> list){
            this.studentList.clear();
            this.studentList.addAll(list);
            this.notifyDataSetChanged();
        }
    }
    
        // Assuume oneOffJobTasksListRVAdapter is declared already 
        recyclerView.setAdapter(oneOffJobTasksListRVAdapter);        
        oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
    
        oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
        recyclerView.setAdapter(oneOffJobTasksListRVAdapter);