notifyDataSetChange不会使用自定义适配器刷新ListView

时间:2014-06-12 20:06:39

标签: android android-fragments android-listview

我想弄清楚这一点,但我只是看不出我做错了什么。我想用产品动态填充ListView(将产品添加到数组然后刷新列表,基本上每次点击都将一个产品添加到数组然后在ListView中显示数组内容),这是第二个片段中包含来自第一个片段的数据。传递数据正在工作(使用日志确认),但我的主要问题是更新具有自定义适配器的ListView。使用此代码没有任何事情发生(ViewList不刷新,我可以看到每个日志(和其他所有工作),没有错误)。 这是代码(所有这些都在第二片段中):

此代码为全局

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

这样我从第一个片段(到第二个片段)获得2个数字

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;
}

 }

只有当我使用此代码

时才更新列表
receiptListAdapter = new ReceiptListAdapter(getActivity().getBaseContext(),R.layout.receipt_item,

而不是

receiptItemListView.setAdapter(receiptListAdapter);

但它只增加一次并在点击时再次刷新列表,但我知道原因。

2 个答案:

答案 0 :(得分:1)

您可以发布ReceiptListAdapter代码吗?这是您需要在数据源和UI之间建立连接的地方。您可以通过在数据库上注册ContentObservers然后ListView使用适配器注册其ContentObserver来执行此操作。适配器通过调用ListView DataSetObserver的onChanged()方法通知ListView更新。

使用数据库时,常见的选择是使用CursorLoader在与CursorAdapter配对的后台线程上从数据库中获取数据。 CursorLoader自动向数据库注册以通知更改。然后,您可以实现LoaderManager回调,它会告诉您数据集何时更改并通过更新的游标。然后,在CursorAdapter上调用swapCursor(cursor),向其传递新游标,并通知ListView DataSetObserver数据集已更改。然后,ListView查询适配器以获取新值并刷新UI。

查看本教程,了解一些优秀的示例代码:http://www.vogella.com/tutorials/AndroidSQLite/article.html

答案 1 :(得分:0)

我想通了我必须让这个全球List<ReceiptItem> receiptItemList = new ArrayList<ReceiptItem>();我还要感谢midseatman解释一些事情,它真的帮助了我。