我正在使用此library.
的Recyclerview当我刷新recyclerview并同时滚动应用程序将强制关闭。
public class NewsFeed extends Fragment implements MyDynamicRecyclerView.SwipeRefreshListener, MyDynamicRecyclerView.LoadMoreListener {
MyDynamicRecyclerView myRecyclerview;
NewsFeedAdapter testAdapter;
ArrayList<ProgramModel> modelArrayList;
LinearLayoutManager linearLayoutManager;
Dialog dialog;
int limit;
private boolean firstSwipe;
public NewsFeed() {
// Required empty public constructor
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("NewsFeedFragment", "Destroyed");
if (dialog != null)
dialog.dismiss();
}
@Override
public void onPause() {
super.onPause();
Log.i("NewsFeedFragment", "Paused");
if (dialog != null)
dialog.dismiss();
}
@Override
public void onResume() {
super.onResume();
Log.i("NewsFeedFragment", "Resumed");
firstSwipe = false;
if (checkInternetForNewsFeed() && firstSwipe) {
removeItems();
new FetchBooks(false).execute();
firstSwipe = false;
Log.d("Swipe", "First swipe");
} else if (checkInternetForNewsFeed() && !firstSwipe) {
fetchAllBooksByHeader();
firstSwipe = true;
Log.d("Swipe", "Not first swipe");
} else {
myRecyclerview.showInfoLayout();
}
getActivity().setTitle("Të gjithë");
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("NewsFeedFragment", "Created");
View v = inflater.inflate(R.layout.news_feed_fragment_layout, container, false);
dialog = new Dialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setContentView(R.layout.loading_layout);
myRecyclerview = (MyDynamicRecyclerView) v.findViewById(R.id.myRecyclerview);
modelArrayList = new ArrayList<>();
testAdapter = new NewsFeedAdapter(getActivity().getApplicationContext(), modelArrayList, (AppCompatActivity) getActivity(), this, false);
linearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
myRecyclerview.setScrollContainer(false);
myRecyclerview.setBackgroundColor("#FFFFFF");
myRecyclerview.setSwipeRefresh(true);
myRecyclerview.setColorSchemeColors(Color.RED, Color.YELLOW, Color.BLACK, Color.GREEN, Color.BLUE);
myRecyclerview.setLoadMore(true, linearLayoutManager);
myRecyclerview.setLoadMoreListener(this);
myRecyclerview.setOnRefreshListener(this);
myRecyclerview.setLayoutManager(linearLayoutManager);
myRecyclerview.setItemAnimator(new DefaultItemAnimator());
myRecyclerview.setSimpleDivider(false);
myRecyclerview.setAdapter(testAdapter);
limit = 0;
if (checkInternetForNewsFeed()) {
firstSwipe = false;
fetchAllBooksFromDB();
} else {
firstSwipe = true;
myRecyclerview.showInfoLayout();
}
return v;
}
public void fetchAllBooksByHeader() {
limit = 0;
if (modelArrayList.size() >= 1) {
removeItems();
}
new FetchBooks(true).execute();
testAdapter.notifyDataSetChanged();
}
public void fetchAllBooksFromDB() {
if (modelArrayList.size() >= 1) {
removeItems();
}
new FetchBooks(false).execute();
testAdapter.notifyDataSetChanged();
}
public void addHeader() {
if (modelArrayList.size() == 0)
modelArrayList.add(new ProgramModel());
}
public void addItem(String title, String author, String imageName) {
modelArrayList.add(new ProgramModel(title, author, imageName));
testAdapter.notifyDataSetChanged();
}
public void removeItems() {
modelArrayList.clear();
addHeader();
}
@Override
public void OnRefresh() {
getActivity().setTitle("Të gjithë");
limit = 0;
if (checkInternetForNewsFeed() && firstSwipe) {
removeItems();
new FetchBooks(false).execute();
firstSwipe = false;
Log.d("Swipe", "First swipe");
} else if (checkInternetForNewsFeed() && !firstSwipe) {
removeItems();
new FetchBooks(true).execute();
Log.d("Swipe", "Not first swipe");
} else {
myRecyclerview.showInfoLayout();
}
myRecyclerview.stopSwipeRefresh();
}
private boolean checkInternetForNewsFeed() {
if (new ConnectivityState(getActivity()).isConnected()) {
myRecyclerview.hideInfoLayout();
return true;
} else {
// Fonts for the title and the message of the content
Typeface messageTypeface = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Light.ttf");
Typeface titleTypeface = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Bold.ttf");
// Setting up the content
myRecyclerview.setInfoIcon(R.drawable.warning_icon, "#000000");
myRecyclerview.setInfoTitle("Nuk jeni i lidhur me internet.", 18, Color.GRAY, titleTypeface);
myRecyclerview.setInfoMessage("Rifreskoni edhe njëherë për të kontrolluar aksesin në internet.", 13, Color.GRAY, messageTypeface);
return false;
}
}
@Override
public void OnLoadMore() {
new FetchBooks(true).execute();
MyDynamicToast.informationMessage(AppController.getInstance(), "...");
}
public static void hideLoadingDialogFromBookActivity(Dialog d) {
d.hide();
}
private class FetchBooks extends AsyncTask<Void, Void, Void> {
private boolean reload;
FetchBooks(boolean reload) {
this.reload = reload;
}
@Override
protected void onPreExecute() {
}
@Override
protected Void doInBackground(Void... params) {
getBooksFromDB();
return null;
}
private void getBooksFromDB() {
StringRequest requestBooks = new StringRequest(Request.Method.GET, AppConfig.URL_FETCH_BOOKS, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = limit; i < jsonArray.length(); i++) {
if (i < (limit + 5)) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String imageName = "http://ec2-52-39-232-168.us-west-2.compute.amazonaws.com/files/books/" + jsonObject.getString("cover");
modelArrayList.add(new ProgramModel(jsonObject.getString("title"), jsonObject.getString("author"), imageName));
} else {
break;
}
}
limit += 5;
if (reload) {
testAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
MyDynamicToast.errorMessage(AppController.getInstance(), "" + e.getMessage());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
MyDynamicToast.errorMessage(AppController.getInstance(), "Request did not work!");
}
});
AppController.getInstance().addToRequestQueue(requestBooks);
}
}
}
所以基本上我将onRefreshListener添加到recyclerView并调用“onRefresh”。在这个类中,我创建了一个内部的,它将从特定的URL中获取一些数据,并添加填充了从该URL接收的数据的项目。 当我在滚动时尝试刷新时,它给了我这个:
03-18 16:11:22.855 5970-5970 / com.libraryhf.libraryharryfultz E / AndroidRuntime:FATAL EXCEPTION:main 处理:com.libraryhf.libraryharryfultz,PID:5970 java.lang.IndexOutOfBoundsException:检测到不一致。无效的项目位置4(偏移量:4).state:10 在android.support.v7.widget.RecyclerView $ Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5458) 在android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:270) 在android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:324) 在android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:337) 在android.support.v7.widget.GapWorker.prefetch(GapWorker.java:344) 在android.support.v7.widget.GapWorker.run(GapWorker.java:370) 在android.os.Handler.handleCallback(Handler.java:751) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6724) at java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1520) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我在网上查了一下,发现一些信息声称这是谷歌应该解决的问题。我一直在努力解决这个问题并没有结果。
如果有人能指出我正确的方向,我会非常感激:解决这个问题或至少处理它。非常感谢你!
答案 0 :(得分:1)
在适配器上设置后,不要修改列表。特别是不是来自不同的主题。
在getBooksFromDB
中,您调用modelArrayList.add()
这很可能是导致崩溃的原因,因为您修改了从其他线程支持适配器的列表。
当您调用notifyDataSetChanged
时,会在实际开始修改列表之前调用它,因为修改会在后台进行。
new FetchBooks(false).execute(); // runs in background and modifies list
testAdapter.notifyDataSetChanged(); // executes immediately
如果您需要修改此列表(很可能不需要),您应该立即通知适配器更改,并且必须进行更改关于ui线程。
您还可以使用notifyItem*
方法更新更改的适配器,例如notifyItemRangeInserted
。或者您可以查看DiffUtil来帮助您更新适配器。
处理列表更改的最常用方法是交换支持适配器的整个列表,然后调用notifyDataSetChanged
。
创建新列表,将项目放入其中,然后将新列表传递给适配器。在您的适配器中放置类似......
void setBooks(List<Book> books) {
mBooks = books; // swap the whole list
notifyDataSetChanged(); // notify of change
}
......你不会遇到这个问题。