我很难找到加快数据加载到RecyclerView
的解决方案。从服务器数据库加载数据并填充该行。每行都有一些EditTexts
,用户可以在其中输入一些值。在OnBindViewHolder
中,使用文本观察器捕获用户输入的每个值,然后计算总计并在父视图的页脚中实时显示。(RecyclerView
之外)此外,在OnBindViewHolder
内,调用一个方法来更新数据库中的table
,并输入和捕获这些值。
因此,基本上,当每一行绑定时,DB和UI都会更新。当数据负载很大时,recyclerView
的加载速度非常慢。我尝试过将数据库更新移动到一个单独的线程,使用async task
来更新数据库。但没有任何效果。我该怎么办?
适配器的OnBindViewHolder代码显示在下面。
public void onBindViewHolder(final MyViewHolder holder, @SuppressLint("RecyclerView") final int position, List<Object> payload) {
//onBindViewHolder(holder,position);
holder.ref = position;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
onBind = true;
// data passed from getAllData method aka all from TempInvoice
SalesInvoiceModel siModel = salesInvoice.get(position);
holder.code.setText(siModel.getCode());
holder.product.setText(siModel.getProduct());
holder.batchNum.setText(siModel.getBatchNumber());
try {
Date date = simpleDateFormat.parse(siModel.getExpiryDate());
holder.expiry.setText(date.toString());
} catch (Exception ex) {
holder.expiry.setText("Error");
}
holder.expiry.setText(siModel.getExpiryDate());
if (siModel.getDiscountRate() > 0) {
holder.unitprice.setText(siModel.getRetailPrice() + "");
} else {
holder.unitprice.setText(siModel.getUnitPrice() + "");
}
holder.stock.setText(siModel.getStock() + "");
holder.lineval.setText(siModel.getLineValue() + "");
if (payload == null || payload.size() == 0) {
holder.shelf.setText(siModel.getShelf() + "");
holder.request.setText(siModel.getRequest() + "");
holder.order.setText(siModel.getOrder() + "");
holder.free.setText(siModel.getFree() + "");
holder.discount.setText(siModel.getDiscountRate() + "");
} else {
for (Object editText : payload) {
//String val = (String)payload.get(0);
String val = (String) editText;
switch (val) {
case SHELF:
if (lostFocus) {
holder.shelf.setText(salesInvoice.get(position).getShelf() + "");
}
break;
case REQUEST:
if (lostFocus) {
holder.request.setText(salesInvoice.get(position).getRequest() + "");
}
break;
case ORDER:
if (lostFocus) {
holder.order.setText(salesInvoice.get(position).getOrder() + "");
}
break;
case FREE:
if (lostFocus) {
holder.free.setText(salesInvoice.get(position).getFree() + "");
}
break;
case DISCOUNT:
if (lostFocus) {
holder.discount.setText(salesInvoice.get(position).getDiscountRate() + "");
}
break;
case LINEVAL:
holder.lineval.setText(salesInvoice.get(position).getLineValue() + "");
break;
default:
onBindViewHolder(holder, position);
break;
}
}
}
//ADD TEXT WATCHERS
holder.shelf.setOnFocusChangeListener(new FocusChangeListener());
holder.shelf.addTextChangedListener(new GenericTextWatcher() {
@Override
public void afterTextChanged(String s) {
int pos = holder.ref;
if (!onBind) {
if (!s.equals("")) {
notifyItemChanged(pos, SHELF);
Log.d(TAG, "inside text change typed shelf_" + s);
salesInvoice.get(pos).setShelf(Integer.parseInt(s + ""));
} else {
salesInvoice.get(pos).setShelf(0);
}
lastUpdatedRow = pos;
}
}
});
holder.request.setOnFocusChangeListener(new FocusChangeListener());
holder.request.addTextChangedListener(new GenericTextWatcher() {
@Override
public void afterTextChanged(String s) {
boolean valHasChanged = false;
boolean freeHasChanged = false;
int pos = holder.ref;
if (!onBind) {
if (!(s.equals(""))) {
int val = Integer.parseInt((s));
int stock = salesInvoice.get(pos).getStock();
// if stock does not have the particular product
if (val > stock) {
val = stock;
valHasChanged = true;
}
salesInvoice.get(pos).setRequest(val);
if (!refresh) salesInvoice.get(pos).setOrder(val);
if (salesInvoice.get(pos).getFree() + salesInvoice.get(pos).getOrder() > salesInvoice.get(pos).getStock()) {
salesInvoice.get(pos).setFree(0);
freeHasChanged = true;
}
} else {
salesInvoice.get(pos).setRequest(0);
}
notifyItemChanged(pos, ORDER);
if (valHasChanged) {
notifyItemChanged(pos, REQUEST);
}
if (freeHasChanged) {
notifyItemChanged(pos, FREE);
}
lastUpdatedRow = pos;
}
}
});
holder.order.setOnFocusChangeListener(new FocusChangeListener());
holder.order.addTextChangedListener(new GenericTextWatcher() {
@Override
public void afterTextChanged(String s) {
boolean valHasChanged = false;
boolean freeHasChanged = false;
int pos = holder.ref;
if (!onBind) {
if (!(s.equals(""))) {
int val = Integer.parseInt(s);
int stock = salesInvoice.get(pos).getStock();
if (val > stock) {
val = stock;
valHasChanged = true;
}
salesInvoice.get(pos).setOrder(val);//make sure we set returnQty before
//checking the total of returnQty and free against stock
if (salesInvoice.get(pos).getOrder() + salesInvoice.get(pos).getFree() > salesInvoice.get(pos).getStock()) {
salesInvoice.get(pos).setFree(0);
freeHasChanged = true;
}
} else {
salesInvoice.get(pos).setOrder(0);
}
if (valHasChanged) {
notifyItemChanged(pos, ORDER);//notify the adapter that value changed and refresh the view mentioned by the string
}
if (freeHasChanged) notifyItemChanged(pos, FREE);
notifyItemChanged(pos, LINEVAL);
lastUpdatedRow = pos;
}
}
});
holder.free.setOnFocusChangeListener(new FocusChangeListener());
holder.free.addTextChangedListener(new GenericTextWatcher() {
@Override
public void afterTextChanged(String s) {
boolean valChanged = false;
int pos = holder.ref;
if (!onBind) {
if ((!s.equals("")) && (!(s.equals("0")))) {
int val = Integer.parseInt(s);
salesInvoice.get(pos).setFree(val);
holder.discount.setEnabled(false);
if (salesInvoice.get(pos).getOrder() + salesInvoice.get(pos).getFree() > salesInvoice.get(pos).getStock()) {
salesInvoice.get(pos).setFree(0);
valChanged = true;
holder.discount.setEnabled(true);
}
} else {
salesInvoice.get(pos).setFree(0);
holder.discount.setEnabled(true);
}
notifyItemChanged(pos, LINEVAL);
if (valChanged) notifyItemChanged(pos, FREE);
holder.setCursor(FREE);
lastUpdatedRow = pos;
}
}
});
holder.discount.setOnFocusChangeListener(new FocusChangeListener());
holder.discount.addTextChangedListener(new GenericTextWatcher() {
@Override
public void afterTextChanged(String s) {
int pos = holder.ref;
if (!(s.equals(salesInvoice.get(pos).getDiscountRate() + ""))) {
if ((!s.equals("")) && (!(s.equals("0"))) && (!(s.equals("0.0"))) && (!(s.equals("0.")))) {
Double rate = Double.parseDouble(s.toString().trim());
Log.i(" RAte ", rate + "");
salesInvoice.get(pos).setDiscountRate(rate);
holder.free.setEnabled(false);
} else {
salesInvoice.get(pos).setDiscountRate(0.0);
holder.free.setEnabled(true);
}
if (!onBind) {
notifyItemChanged(pos, LINEVAL);
lastUpdatedRow = pos;
}
}
}
});
if (position % 2 == 0) {
holder.setColor(Color.LTGRAY);
} else {
holder.setColor(Color.GRAY);
}
onBind = false;
notifyUpdate(); //calling to update the UI
Log.d("ASY", "before db call");
DBAdapterAsync dbAdapter = new DBAdapterAsync(getContextForAdapter);
dbAdapter.execute(salesInvoice.get(holder.ref));
Log.d("ASY", "after db call");
}
//async task class for DB Update
@SuppressLint("StaticFieldLeak")
private class DBAdapterAsync extends AsyncTask<SalesInvoiceModel, Void, String> {
private SQLiteDatabase db;
private DBHelper dbHelper;
DBAdapterAsync(Context context) {
this.dbHelper = new DBHelper(context);
Log.d("ASY", "inside constructor");
}
@Override
protected void onPreExecute() {
try {
db = dbHelper.getWritableDatabase();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
dbHelper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected String doInBackground(SalesInvoiceModel... models) {
SalesInvoiceModel model = models[0];
Log.d(TAG, "inside updateInvoiceData_");
Log.d(TAG, "shelf_" + model.getShelf());
Log.d(TAG, "order_" + model.getOrder());
Log.d(TAG, "free_" + model.getFree());
String sql = "UPDATE temp_invoice SET" +
" Shelf=" + model.getShelf() + " , Request=" + model.getRequest()
+ " , OrderQty=" + model.getOrder() + " , Free=" + model.getFree()
+ " , Disc=" + model.getDiscountRate() + " , LineVal=" + model.getLineValue()
+ ", RetailPriceLineVal=" + model.getRetailLineVal()
+ " WHERE _id=" + model.getId();
db.execSQL(sql);
Log.d(TAG, "DB method finished,");
Log.d("ASY", "after do in background");
return null;
}
}