新手到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());
}
答案 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
调用什么都不做。
使用RecyclerView
或ListView
时的一般建议确保您将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());
}
希望它能奏效......