사용자 정의 어댑터에서 notifyDataSetChange가 작동하지 않음

내을 다시 채울 때 ListViewAdapter.

문제 :

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();

목록이 다른 객체를 가리키고 있고,이 객체는 어댑터의 새 객체에 대해 전혀 알지 못하며, notifyDataSetChanged ()는 아무 영향도주지 않기 때문에 목록보기의 데이터에는 영향을주지 않습니다. 따라서 객체의 데이터를 변경하고 어댑터에 대한 새 객체를 다시 생성하지 않도록해야합니다.


답변

이 문제의 원인과 다른 답변 스레드에서 처리하는 방법을 이미 설명했듯이 여기 . 여전히 여기에 솔루션 요약을 공유하고 있습니다.

notifyDataSetChanged()작동하지 않는 주된 이유 중 하나는

어댑터가 목록에 대한 참조를 잃습니다 .

새 목록을 만들고 Adapter. 항상 다음 지침을 따르십시오.

  1. arrayList전역 적으로 선언하면서 초기화하십시오 .
  2. null 및 빈 값을 확인하지 않고 목록을 어댑터에 직접 추가합니다. 어댑터를 목록에 직접 설정하십시오 (조건을 확인하지 마십시오). 어댑터는 데이터를 변경할 때마다arrayList 처리하지만 참조 .
  3. (데이터가 전화 할 수있는 것보다 완전히 새로운 경우 항상 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);
}

답변

class StudentAdapter extends BaseAdapter {
    ArrayList<LichHocDTO> studentList;

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

당신은 시도 할 수 있습니다. 그것은 나를 위해 일합니다


답변

경우 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