사용자 정의 어댑터에서 notifyDataSetChange가 작동하지 않습니다
를 다시 채울 때에서 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-);
작동하지만 작동 방식이 아닙니다.
방법 변경
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist = newlist;
this.notifyDataSetChanged();
}
에
public void updateReceiptsList(List<Receipt> newlist) {
receiptlist.clear();
receiptlist.addAll(newlist);
this.notifyDataSetChanged();
}
따라서 어댑터의 DataSet과 동일한 객체를 유지하십시오.
나는 같은 문제가 있으며 그것을 알고 있습니다. 우리가 어댑터를 생성하고 그것을 listview로 설정하면, listview는 어댑터가 보유하고있는 메모리 어딘가에있는 객체를 가리키고,이 객체의 데이터는 listview에 표시됩니다.
adapter = new CustomAdapter(data);
listview.setadapter(adapter);
다른 데이터로 어댑터에 대한 객체를 다시 작성하고 notifydatasetchanged () :
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
목록이 다른 객체를 가리키고 있기 때문에 listview의 데이터에는 영향을 미치지 않습니다.이 객체는 어댑터의 새 객체에 대해 아무것도 모르며 notifyDataSetChanged ()는 아무것도 영향을 미치지 않습니다. 따라서 객체의 데이터를 변경하고 어댑터에 대해 새 객체를 다시 작성하지 않아야합니다.
이미이 문제의 원인과 다른 답변 스레드에서 처리하는 방법을 설명 했으므로 Here . 여전히 솔루션 요약을 여기에서 공유하고 있습니다.
주요 이유 중 하나가 효과 notifyDataSetChanged()
가없는 것입니다.
어댑터가 목록을 참조하지 않습니다 .
작성하고에 새로운 목록을 추가 할 때 Adapter
. 다음 지침을 항상 따르십시오.
arrayList
전역으로 선언하면서 초기화하십시오 .- null 값과 빈 값을 확인하지 않고 어댑터에 직접 List를 추가하십시오. 어댑터를 목록으로 직접 설정하십시오 (조건을 확인하지 마십시오). 어댑터는 데이터를 변경할 때마다 데이터를
arrayList
관리하지만 참조 를 잃지 않도록 보장합니다 . - (데이터가 전화 할 수있는 것보다 완전히 새로운 경우 항상 ArrayList를 자체 데이터를 수정
adapter.clear()
하고arrayList.clear()
있지만, 새로운 데이터가 채워집니다 경우 어댑터 예를 설정하지 전에 실제로 목록에 데이터를 추가)arrayList
보다는 다만adapter.notifyDataSetChanged()
도움이 되었기를 바랍니다.
아마도 ListView를 새로 고치십시오.
receiptsListView.invalidate()
.
편집 : 또 다른 생각이 떠 올랐습니다. 레코드의 경우 목록보기 캐시를 비활성화하십시오.
<ListView
...
android:scrollingCache="false"
android:cacheColorHint="@android:color/transparent"
... />
나는 같은 문제를 겪었다. 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);
}
경우 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
class StudentAdapter extends BaseAdapter {
ArrayList<LichHocDTO> studentList;
private void capNhatDuLieu(ArrayList<LichHocDTO> list){
this.studentList.clear();
this.studentList.addAll(list);
this.notifyDataSetChanged();
}
}
당신은 시도 할 수 있습니다. 그것은 나를 위해 작동
우연히이 스레드에 착륙하여 왜 adapter.invaidate()
또는 adapter.clear()
방법이 귀하의 사례에 존재하지 않는지 궁금한 경우 아마도이 질문의 asker가 RecyclerView.Adapter
대신 사용 하는 것이기 때문일 수 있습니다 BaseAdapter
. 을 삭제하는 경우 list
또는 arraylist
하지이 문제를 해결 당신이 만드는 것을 발생할 수 있습니다 인스턴스를 두 개 이상 의를 adapter
전을 위해 :
주요 활동
...
adapter = new CustomAdapter(list);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
...
그리고
SomeFragment
...
adapter = new CustomAdapter(newList);
adapter.notifyDataSetChanged();
...
If in the second case you are expecting a change in the list of inflated views in recycler view then it is not gonna happen as in the second time a new instance of the adapter
is created which is not attached to the recycler view. Setting notifyDataSetChanged
in the second adapter is not gonna change the content of recycer view. For that make a new instance of the recycler view in SomeFragment and attach it to the new instance of the adapter.
SomeFragment
...
recyclerView = new RecyclerView();
adapter = new CustomAdapter();
recyclerView.setAdapter(adapter);
...
Although, I don't recommend making multiple instances of the same adapter and recycler view.
Add this code
runOnUiThread(new Runnable() { public void run() {
adapter = new CustomAdapter(anotherdata);
adapter.notifyDataSetChanged();
}
});
I have the same problem but I just finished it!!
you should change to
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;
}
}
참고URL : https://stackoverflow.com/questions/15422120/notifydatasetchange-not-working-from-custom-adapter
'IT story' 카테고리의 다른 글
빌드 도구 개정판 23.0.1을 찾지 못했습니다. (0) | 2020.07.28 |
---|---|
C ++를 배우기 전에 C를 배워야합니까? (0) | 2020.07.28 |
SQL Server에서 앞에 0을 채워서 숫자 서식 지정 (0) | 2020.07.28 |
파일 대신 문자열에 쓰는 XmlWriter (0) | 2020.07.28 |
아이폰 시뮬레이터-느린 연결을 시뮬레이션? (0) | 2020.07.28 |