我有一个活动,在那些活动中,我有一个带有适配器的RecyclerView,它将基于AsyncTask onPostExecute加载。
这是代码。
public class AntamAddEditDetailBagsQueueIncomingActivity extends AppCompatActivity {
public static final String EXTRA_ID = "com.tsurumaru.dzil.clientwarehouse.EXTRA_ID";
RecyclerView recyclerView;
BagLotNumberAdapter bagLotNumberAdapter;
ArrayList<BagLotNumberModel> bagLotNumbers = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_antam_add_edit_detail_bags_queue_incoming);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
Intent intent = getIntent();
long id = intent.getLongExtra(EXTRA_ID, -1);
setTitle("Edit Bags " + intent.getLongExtra(EXTRA_ID, -1));
recyclerView = findViewById(R.id.recyclerViewAntamIncomingScanQR);
// Default is emtpy
bagLotNumberAdapter = new BagLotNumberAdapter(this, bagLotNumbers);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(bagLotNumberAdapter);
ItemTouchHelper itemTouchHelper = new
ItemTouchHelper(new SwipeToDeleteBagLotNumberCallback(bagLotNumberAdapter));
itemTouchHelper.attachToRecyclerView(recyclerView);
// Run on Asynctask
QueueIncomingRepository queueIncomingRepository = new QueueIncomingRepository(this, id);
queueIncomingRepository.getAllJoinBag();
}
}
本地仓库
public class QueueIncomingRepository {
private Context context
private Long idQueueIncoming;
public QueueIncomingRepository(Context context, Long id) {
AppDatabase database = AppDatabase.getInstance(context);
queueIncomingDao = database.queueIncomingDao();
this.context = context;
this.idQueueIncoming = id;
}
// Asynctask
public void getAllJoinBag() {
new SelectWithBagsAsyncTask(context, queueIncomingDao).execute(idQueueIncoming);
}
// Inner Class
private static class SelectWithBagsAsyncTask extends AsyncTask<Long, Void, List<QueueIncomingDao.QueueIncoming>> {
private String TAG = "SelectBagAsync";
private QueueIncomingDao queueIncomingDao;
private Context context;
private SelectWithBagsAsyncTask(Context context, QueueIncomingDao queueIncomingDao) {
this.queueIncomingDao = queueIncomingDao;
this.context = context;
}
@Override
protected List<QueueIncomingDao.QueueIncoming> doInBackground(Long... longs) {
return queueIncomingDao.getAllJoinBag(longs[0]);
}
@Override
protected void onPostExecute(List<QueueIncomingDao.QueueIncoming> queueIncomings) {
super.onPostExecute(queueIncomings);
ArrayList<BagLotNumberModel> bagLotNumbers = new ArrayList<>();
for (QueueIncomingDao.QueueIncoming queueIncoming : queueIncomings) {
if (queueIncoming.getId() != null) {
bagLotNumbers.add(new BagLotNumberModel(
queueIncoming.getId(),
queueIncoming.getBagNumber(),
queueIncoming.getLotNumber(),
queueIncoming.getConsigneeName(),
queueIncoming.getAllocationConsignee(),
queueIncoming.getNettWeight(),
queueIncoming.getGrossWeight()
));
}
}
if (!bagLotNumbers.isEmpty()) {
RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
BagLotNumberAdapter bagLotNumberAdapter = new BagLotNumberAdapter(context, bagLotNumbers);
recyclerView.setAdapter(bagLotNumberAdapter);
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
// Update adapter
bagLotNumberAdapter.notifyDataSetChanged();
}
});
}
}
}
}
一切正确,但问题出在滑动删除上。
当AsyncTask中的
bagLotNumberAdapter.notifyDataSetChanged();
时,UI Thread中的Recylerview已更新,但是为什么大小仍为0?java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.tsurumaru.dzil.clientwarehouse.adapters.antam.incoming.BagLotNumberAdapter.deleteItem(BagLotNumberAdapter.java:103)
at com.tsurumaru.dzil.clientwarehouse.adapters.antam.incoming.SwipeToDeleteBagLotNumberCallback.onSwiped(SwipeToDeleteBagLotNumberCallback.java:38)
at android.support.v7.widget.helper.ItemTouchHelper$4.run(ItemTouchHelper.java:712)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
任何帮助,它表示赞赏。
最佳答案
您正在async任务的onPostExecute()方法中创建一个新适配器,而ItemTouchHelper仍引用在onCreate()方法中创建的先前适配器,这里:
onCreate() {
...
bagLotNumberAdapter = new BagLotNumberAdapter(this, bagLotNumbers);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(bagLotNumberAdapter);
ItemTouchHelper itemTouchHelper = new
ItemTouchHelper(new SwipeToDeleteBagLotNumberCallback(bagLotNumberAdapter));
itemTouchHelper.attachToRecyclerView(recyclerView);
...
}
并且,在您的onPostExecute()方法中:
onPostExecute() {
...
RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
BagLotNumberAdapter bagLotNumberAdapter = new BagLotNumberAdapter(context, bagLotNumbers);
recyclerView.setAdapter(bagLotNumberAdapter);
...
}
无需在onPostExecute()中创建新的适配器,而是在适配器类中定义一个类似于setData()的方法,该方法将一个旧数据替换为一个:
pubilc void setData(List newData){
this.list = newData
}
因此,您的onPostExecute()方法现在变为:
onPostExecute() {
...
RecyclerView recyclerView = ((Activity) context).findViewById(R.id.recyclerViewAntamIncomingScanQR);
BagLotNumberAdapter bagLotNumberAdapter = (BagLotNumberAdapter )recyclerView.getAdapter();
bagLotNumberAdapter.setData(bagLotNumbers);
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
// Update adapter
bagLotNumberAdapter.notifyDataSetChanged();
}
});
...
}
关于java - 使用AsyncTask成功更新RecyclerView,但Activity/UI线程中的Arraylist大小不变,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56490818/