当我重新填充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-);
工作,但不是如何工作。
答案 0 :(得分:292)
从
更改您的方法public void updateReceiptsList(List<Receipt> newlist) {
receiptlist = newlist;
this.notifyDataSetChanged();
}
要
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist.clear();
receiptlist.addAll(newlist);
this.notifyDataSetChanged();
}
因此,您在适配器中保留与DataSet相同的对象。
答案 1 :(得分:22)
我有同样的问题,我意识到了。当我们创建适配器并将其设置为listview时,listview将指向内存中某个适配器保持的对象,此对象中的数据将显示在listview中。
adapter = new CustomAdapter(data);
listview.setadapter(adapter);
如果我们再次使用另一个数据创建适配器的对象并且notifydatasetchanged():
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
这不会影响listview中的数据,因为列表指向不同的对象,此对象对适配器中的新对象一无所知,而notifyDataSetChanged()不会影响任何内容。 因此我们应该更改对象中的数据并避免再次为适配器
创建新对象答案 2 :(得分:11)
我已经解释了这个问题背后的原因,以及如何在不同的答案线程Here中处理它。我仍然在这里分享解决方案摘要。
notifyDataSetChanged()
为您效劳的主要原因之一是,
您的适配器失去对列表的引用。
创建新列表并向Adapter
添加新列表时。始终遵循以下准则:
arrayList
。arrayList
的数据进行更改,它会处理它,但永远不会松散
参考adapter.clear()
和arrayList.clear()
实际上将数据添加到列表中)但是没有设置适配器,即If
新数据填充在arrayList
而不仅仅是
adapter.notifyDataSetChanged()
希望这有帮助。
答案 3 :(得分:3)
也许尝试刷新ListView:
receiptsListView.invalidate()
。
<ListView
...
android:scrollingCache="false"
android:cacheColorHint="@android:color/transparent"
... />
答案 4 :(得分:3)
我使用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);
}
答案 5 :(得分:1)
如果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
答案 6 :(得分:0)
添加此代码
runOnUiThread(new Runnable() { public void run() {
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
}
});
答案 7 :(得分:0)
class StudentAdapter extends BaseAdapter {
ArrayList<LichHocDTO> studentList;
private void capNhatDuLieu(ArrayList<LichHocDTO> list){
this.studentList.clear();
this.studentList.addAll(list);
this.notifyDataSetChanged();
}
}
您可以尝试。它对我有用
答案 8 :(得分:0)
我有同样的问题 但是我刚完成!!
您应该更改为
public class ReceiptListAdapter extends BaseAdapter {
public List<Receipt> receiptlist;
private Context context;
private LayoutInflater inflater;
private DateHelpers dateH;
private List<ReceiptViewHolder> receiptviewlist;
public ReceiptListAdapter(Activity activity, Context mcontext, List<Receipt> rl) {
context = mcontext;
receiptlist = rl;
receiptviewlist = new ArrayList<>();
receiptviewlist.clear();
for(int i = 0; i < receiptlist.size(); i++){
ReceiptViewHolder receiptviewholder = new ReceiptViewHolder();
receiptviewlist.add(receiptviewholder);
}
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 receiptviewholder = receiptviewlist.get(position);
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;
}
}
答案 9 :(得分:0)
如果您偶然碰上了这个线程,并且想知道为什么没有adapter.invaidate()
或adapter.clear()
方法,那么可能是因为您可能使用RecyclerView.Adapter
而不是{{1 }},此问题的询问者使用。如果清除BaseAdapter
或list
不能解决问题,则可能会发生arraylist
的两个或更多实例例如:>
MainActivity
adapter
和
SomeFragment
...
adapter = new CustomAdapter(list);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
...
如果在第二种情况下,您期望在回收者视图中的膨胀视图列表中发生更改,则不会发生这种情况,因为在第二次创建未附加到...
adapter = new CustomAdapter(newList);
adapter.notifyDataSetChanged();
...
的新实例时回收者视图。在第二个适配器中设置adapter
不会更改回收器视图的内容。为此,在 SomeFragment 中创建回收器视图的新实例,并将其附加到适配器的新实例。
SomeFragment
notifyDataSetChanged
尽管如此,我不建议在同一适配器和回收站视图中创建多个实例。
答案 10 :(得分:0)
我的情况不同,但其他人情况可能相同
对于仍然找不到解决方案并尝试了以上所有步骤的用户,如果您在片段内部使用适配器,则说明适配器不起作用的原因fragment could be recreating so the adapter is recreating everytime the fragment recreate
您应在初始化之前验证适配器和对象列表是否为空
if(adapter == null){
adapter = new CustomListAdapter(...);
}
...
if(objects == null){
objects = new ArrayList<>();
}
答案 11 :(得分:0)
就我而言,我只是忘记添加片段do_package_qa[noexec] = "1"
EXCLUDE_FROM_SHLIBS = "1"
答案 12 :(得分:0)
我犯了一个非常菜鸟的错误,我在像这样初始化适配器本身之前设置了 RecyclerView 的适配器。
// Assuume oneOffJobTasksListRVAdapter is declared already
recyclerView.setAdapter(oneOffJobTasksListRVAdapter);
oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
切换线路解决了我的问题。
oneOffJobTasksListRVAdapter = new OneOffJobTasksListRVAdapter();
recyclerView.setAdapter(oneOffJobTasksListRVAdapter);