Когда я заново заполняю свой 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-);
Работает, но не так, как предполагается.
Ответы:
Измените свой метод с
к
Таким образом, вы сохраняете тот же объект, что и ваш DataSet, в вашем адаптере.
источник
ReceiptListObject
вместо aList
of objects, что вы можете сделать для решения этой проблемы?BaseAdapter
и этот адаптер не знает, к каким данным он привязан ... поэтому, если у меня есть настраиваемый объект и я использую настраиваемые функции этого объекта (например,custObject.getCount()
и,custObject.getChildAt(int i)
например), и я хочу обменять этот объект,notifyDataSetChanged
не работает ... в любом случае, я думаю, что эта проблема никогда не возникает сArrayAdapter
У меня такая же проблема, и я это понимаю. Когда мы создаем адаптер и устанавливаем его на listview, listview будет указывать на объект где-то в памяти, который удерживает адаптер, данные в этом объекте будут отображаться в listview.
если мы снова создадим объект для адаптера с другими данными и notifydatasetchanged ():
это не повлияет на данные в списке, потому что список указывает на другой объект, этот объект ничего не знает о новом объекте в адаптере, а notifyDataSetChanged () ни на что не влияет. Поэтому мы должны изменить данные в объекте и избежать повторного создания нового объекта для адаптера.
источник
Как я уже объяснил причины этой проблемы, а также способы ее решения в другом потоке ответов здесь . Тем не менее, я делюсь кратким изложением решения здесь.
Одна из основных причин, по которой у
notifyDataSetChanged()
вас не получится - этоВаш адаптер теряет ссылку на ваш список .
При создании и добавлении нового списка в
Adapter
. Всегда следуйте этим рекомендациям:arrayList
, объявив его глобально.arrayList
он позаботится об этом, но никогда не потеряет ссылку.adapter.clear()
иarrayList.clear()
перед фактическим добавлением данных в список), но не устанавливайте адаптер, т.е. если новые данные заполняютсяarrayList
только вadapter.notifyDataSetChanged()
Надеюсь это поможет.
источник
Возможно, попробуйте обновить свой ListView:
receiptsListView.invalidate()
,РЕДАКТИРОВАТЬ: Еще одна мысль пришла мне в голову. На всякий случай попробуйте отключить кеш представления списка:
источник
У меня была такая же проблема с использованием
ListAdapter
Я позволил Android Studio реализовать для меня методы, и вот что у меня получилось:
Проблема в том, что эти методы не вызывают
super
реализации, поэтомуnotifyDataSetChange
никогда не вызываются.Либо удалите эти переопределения вручную, либо добавьте супервызовы, и он снова должен работать.
источник
Можешь попробовать. Это работает для меня
источник
Если
adapter
установлено,AutoCompleteTextView
тоnotifyDataSetChanged()
не работает.Это нужно для обновления адаптера:
См. Http://android-er.blogspot.in/2012/10/autocompletetextview-with-dynamic.html
источник
Если вы случайно попали в эту ветку и задаетесь вопросом, почему
adapter.invaidate()
илиadapter.clear()
методы отсутствуют в вашем случае, то, возможно, потому, что вы можете использоватьRecyclerView.Adapter
вместо того,BaseAdapter
что используется тем, кто задает этот вопрос. Если очисткаlist
илиarraylist
не решить вашу проблему , то может случиться так, что вы делаете два или более экземпляров изadapter
напр .:Основное занятие
и
SomeFragment
Если во втором случае вы ожидаете изменения в списке расширенных представлений в представлении ресайклера, этого не произойдет, поскольку во второй раз создается новый экземпляр,
adapter
который не прикреплен к представлению ресайклера. НастройкаnotifyDataSetChanged
второго адаптера не изменит содержимое представления ресайсера. Для этого создайте новый экземпляр представления recycler в SomeFragment и прикрепите его к новому экземпляру адаптера.SomeFragment
Хотя я не рекомендую создавать несколько экземпляров одного и того же адаптера и представления ресайклера.
источник
Добавьте этот код
источник
У меня такая же проблема, только что закончил !!
вы должны изменить на
источник
Мой случай был другим, но может быть то же самое для других
для тех, кто все еще не смог найти решение и попробовал все выше, если вы используете адаптер внутри фрагмента, то причина, по которой он не работает
fragment could be recreating so the adapter is recreating everytime the fragment recreate
перед инициализацией вы должны убедиться, что список адаптеров и объектов равен нулю.
источник