notifyDataSetChange does not refresh ListView with custom adapter

不羁的心 提交于 2019-12-11 20:14:07

问题


I am trying to figure this out, but i just cant see what i am doing wrong. I want to dynamically fill ListView with products (add product to array then refresh list, basically for every click add one product to array then display content of array in ListView) which is in 2nd fragment with the data from the first Fragment. Passing Data is working (used Log to confirm), but my main problem is updating the ListView which has custom adapter. With this code nothing is happening (ViewList is not refreshing, I can see every log (and everything else works) and no errors). Here is the code (All this is in 2nd Fragment):

This code is global

ReceiptListAdapter receiptListAdapter; 
ArrayList<ReceiptItem> receiptItemArrayList;
int cat = 0;
int prodct = 0;

With this i get 2 numbers from 1st fragment (to this 2nd fragment)

public void use(int num1, int num2) {
     Log.d("LOG","Category: " + num1 + "Product: "  + num2); //This works
     cat = num1;
        prodct = num2;

    ListView receiptItemListView = (ListView) getView().findViewById(
                R.id.receiptItemsList);
        receiptItemArrayList = (ArrayList<ReceiptItem>)generateReceiptItemsForTest();

        receiptItemListView.setAdapter(receiptListAdapter); //i think here is the problem

             receiptListAdapter.notifyDataSetChanged();    

}

OnViewCreated

public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    ListView receiptItemListView = (ListView) getView().findViewById(
            R.id.receiptItemsList);




    receiptItemArrayList = (ArrayList<ReceiptItem>) generateReceiptItemsForTest();

    receiptListAdapter = new ReceiptListAdapter(
            getActivity().getBaseContext(), R.layout.receipt_item,
            receiptItemArrayList);



    receiptItemListView.setAdapter(receiptListAdapter);


    TextView txtTotalAmmount = (TextView) getView().findViewById(
            R.id.txtReceiptTotalAmmount);
    double totalAmmount = getTotalAmmount(receiptItemArrayList);
    totalAmmount = Math.round(totalAmmount * 100) / 100;
    txtTotalAmmount.append(String.valueOf(totalAmmount));

}

private List<ReceiptItem> generateReceiptItemsForTest() { 
    List<ReceiptItem> receiptItemList = new ArrayList<ReceiptItem>();

    DatabaseAdapter db = new DatabaseAdapter(getActivity());




    if(cat != 0 && prodct != 0 )
    {

    name = db.readFromCategoriesAndGetOnePreduct(cat, prodct).getName();
    price = db.readFromCategoriesAndGetOnePreduct(cat, prodct).getPrice();
    Log.d("Name: " + name,"Price: " + String.valueOf(price)); //Also working (showing what i want) and i can see it in log but the ListView isnt refreshing this data

    receiptItemList.add(new ReceiptItem(name,1,price,1);


    }
                }


    return receiptItemList;
}



private double getTotalAmmount(ArrayList<ReceiptItem> receiptItems) {
    double totalAmmount = 0;
    for (ReceiptItem receiptItem : receiptItems) {
        totalAmmount += receiptItem.getTotalPrice();
    }
    return totalAmmount;
}

ReceiptListAdapter

public class ReceiptListAdapter extends ArrayAdapter<ReceiptItem> {

private Context context;

public ReceiptListAdapter(Context context, int rowResourceId,
        ArrayList<ReceiptItem> items) {
    super(context, rowResourceId, items);
    this.context = context;
}

@SuppressWarnings("deprecation")
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;



    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.receipt_item, null);
    }

    ReceiptItem item = getItem(position);
    if (item != null) {
        TextView itemDescription = (TextView) view
                .findViewById(R.id.txtReceiptItemDescription);
        TextView itemAmmount = (TextView) view
                .findViewById(R.id.txtReceiptItemAmmount);
        TextView itemPrice = (TextView) view
                .findViewById(R.id.txtReceiptItemPrice);
        TableRow listItem = (TableRow) view
                .findViewById(R.id.trReceiptItem);
        if (position % 2 == 0)

listItem.setBackgroundDrawable(view.getResources().getDrawable(
                    R.drawable.list_item_selector_a));
        else
                listItem.setBackgroundDrawable(view.getResources().getDrawable(
                    R.drawable.list_item_selector_b));

        itemDescription.setText(item.getDescription());
        itemAmmount.setText(String.valueOf(item.getAmmount()));
        itemPrice.setText(String.format("%.2f", item.getPrice()));
    }

    return view;
}

 }

Only time I got the list to update is when I used this code

receiptListAdapter = new ReceiptListAdapter(getActivity().getBaseContext(),R.layout.receipt_item,

instead of

receiptItemListView.setAdapter(receiptListAdapter);

But it only adds one time and refreshes the list again on click, but i know why.


回答1:


Can you post the ReceiptListAdapter code? That is where you need to make the connection between the data source and the UI. You do this by registering ContentObservers on the database and then the ListView registers its ContentObserver with the Adapter. The Adapter notifies the ListView to update by calling the onChanged() method of the ListView DataSetObserver.

When working with a database, a common choice is to use a CursorLoader to fetch the data from the database on a background thread paired with a CursorAdapter. The CursorLoader automatically registers with the database to be notified of changes. You then implement the LoaderManager callbacks which tell you when the dataset changes and passes you an updated cursor. You then call swapCursor(cursor) on the CursorAdapter, passing it the new cursor and it notifies the ListView DataSetObserver that the dataset has changed. The ListView then queries the adapter to get the new values and refreshes the UI.

Check out this tutorial for some good example code: http://www.vogella.com/tutorials/AndroidSQLite/article.html




回答2:


I figured it out i had to make this global List<ReceiptItem> receiptItemList = new ArrayList<ReceiptItem>(); Also I would like to thank middleseatman for explaining some things, it really helped me.



来源:https://stackoverflow.com/questions/24193090/notifydatasetchange-does-not-refresh-listview-with-custom-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!