RecyclerView仅在应用启动时更新

时间:2016-12-25 09:16:27

标签: android android-recyclerview android-sqlite recycler-adapter

新手到Android这里!

我一直在学习如何在我的应用程序中实现SQLite,总结一下,我有一个Accountant类可以访问SQLite数据库。该类从数据库中提取项目并将它们放在ArrayList中。这个ArrayList是我的适配器用于recyclerView的。

每当我在应用程序中添加新项目时,项目的数据都存储在数据库中,Accountant类的ArrayList会使用此信息进行更新。

然后,适配器调用其notifyDataSetChanged()方法来更新View。这就是问题发生的地方; RecyclerView DOES显示所有项目,但仅在应用启动时显示,而不是在添加新项目时。

我已尽我所能,只是看起来它本应该起作用,但事实并非如此,这让我疯狂。

这是代码

ItemAdapter类

private class ItemAdapter extends RecyclerView.Adapter<ItemHolder> {
        private List<Item> mItemList;

        public ItemAdapter(List<Item> itemList) {
            mItemList = itemList;
        }

        public ItemHolder onCreateViewHolder(ViewGroup parent, int ViewType) {
            View view = getLayoutInflater().inflate(R.layout.list_item_item, parent, false);
            return new ItemHolder(view);
        }

        public void onBindViewHolder(ItemHolder holder, int position) {
            Item item = mItemList.get(position);
            holder.bindItem(item);
        }

        public int getItemCount() {
            return mItemList.size();
        }
    }

会计等级

public class Accountant {

    private static Accountant sAccountant;

    private double mTotalMoney;
    private Context mContext;
    private SQLiteDatabase mDatabase;

    private List<Item> mItemList;

    public static Accountant get(Context context) {
        sAccountant = sAccountant == null ? new Accountant(context) : sAccountant;
        return sAccountant;
    }

    private Accountant(Context context) {
        mTotalMoney = 0;
        mContext = context.getApplicationContext();
        mDatabase = new ItemBaseHelper(mContext).getWritableDatabase();
        mItemList = getListFromSQL();
    }

    private static ContentValues getContentValues(Item i) {
        ContentValues values = new ContentValues();
        values.put(ItemTable.cols.NAME, i.getName());
        values.put(ItemTable.cols.PRICE, i.getPrice());
        values.put(ItemTable.cols.COUNT, i.getCount());

        return values;
    }
    public void addItem(Item item) {
        ContentValues cv = getContentValues(item);
        mDatabase.insert(ItemTable.NAME, null, cv);
        mItemList = getListFromSQL();
    }

    public void removeItem(int i) {

    }

    public void addMoney(double money, boolean isSet) {
        mTotalMoney += isSet ? money - mTotalMoney : money;
    }

    public String getTotalMoney() {
        return MoneyUtils.prep(mTotalMoney);
    }

    public String getChange() {
        double cost = 0;

        for (Item item : getItemList())
            cost += item.getPrice() * item.getCount();

        return MoneyUtils.prep(mTotalMoney - cost);
    }

    public List<Item> getItemList() {
        return mItemList;
    }

     private List<Item> getListFromSQL() {
         List<Item> itemList = new ArrayList<>();

         ItemCursorWrapper cursor = queryItems(null, null);
         try {
             cursor.moveToFirst();
             while (!cursor.isAfterLast()) {
                 itemList.add(cursor.getItem());
                 cursor.moveToNext();
             }
         } finally {
             cursor.close();
         }
         return itemList;
     }

    public ItemCursorWrapper queryItems(String whereClause, String[] whereArgs) {
        Cursor cursor = mDatabase.query(ItemTable.NAME, null, whereClause, whereArgs, null, null, null);

        return new ItemCursorWrapper(cursor);
    }

    public String individualPriceOf(Item i) {
        return MoneyUtils.prep(i.getPrice());
    }

    public String totalPriceOf(Item i) {
       return MoneyUtils.prep(i.getCount() * i.getPrice());
    }

    public String countOf(Item i) {
       return String.valueOf(i.getCount());
    }

    public void clearList() {
        mDatabase.delete(ItemTable.NAME, null, null);
    }
}

项目添加逻辑

public void addItem(Item item) {
    mAccountant.addItem(item);
    mAdapter.notifyItemInserted(mAccountant.getListFromSQL().size() - 1);
    mAdapter.notifyDataSetChanged();
    mChangeButton.setText(mAccountant.getChange());
}

2 个答案:

答案 0 :(得分:0)

那么基本问题甚至与RecyclerView无关。 首先让我们看看如何解决你的问题然后解释错误。

更改此

private List<Item> mItemList;

到这个

private final List<Item> mItemList;

然后代替像mItemList = getListFromSQL();这样的任何作业写下这个

mItemList.clear();
mItemList.addAll(getListFromSQL());

现在解释您的代码无效的原因。问题在于,当您将dataSource(即mItemList)分配给某个新值时,您正在更改对它的引用(这是一个java基本的东西),以便您的RecyclerView不知道任何关于它的信息,它是自己的dataSource,你只在构造函数中分配一次仍然是相同的旧的,没有改变,因此你的notifyDataSetChanged调用什么都不做。

使用RecyclerViewListView时的一般建议确保您将dataSource定义为final

答案 1 :(得分:0)

这种情况正在发生,因为您没有将该项添加到您的Adpater列表中。在您的适配器中创建一个方法,并从您的Accountant类中调用此方法。

private class ItemAdapter extends RecyclerView.Adapter<ItemHolder> {


     public void addItem(Item item) {
         mItemList.add(item); ///Add the item to your arrayList and then notify
         notifyItemInserted(mItemList.size());

}

在Adapter中添加单个项目时,请不要调用notifyDataSetChanged()方法,因为它会通知整个列表。而只使用notifyItemInserted()方法。 另一种想法是确保在通知适配器时它必须来自UI线程。

当您添加项目时,只需从您的Accountant类中调用此适配器addItem()方法。

public void addItem(Item item) {  ///This method is from Accountant Class
    mAccountant.addItem(item);
    mAdapter.addItem(item); // Call the addItem() from Adapter class
    mChangeButton.setText(mAccountant.getChange());

}

希望它能奏效......