Fatal Exception: java.lang.IndexOutOfBoundsException Inconsistency detected. Invalid item position 5(offset:5).state:24
This kind of crash happens too much!!!
I get it in Fabric Crashlytics.
Fatal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 5(offset:5).state:41 at android.support.v7.widget.RecyclerView$Recycler.clear(Unknown Source) at android.support.v7.widget.GapWorker.add(Unknown Source) at android.support.v7.widget.GapWorker.add(Unknown Source) at android.support.v7.widget.GapWorker.remove(Unknown Source) at android.support.v7.widget.GapWorker.add(Unknown Source) at android.support.v7.widget.GapWorker.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5930) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
DateList is the Fragment which involve RecyclerView:
public class DateList extends Fragment {
DatesItemAdapter adapter;
List<DateItem2> keyList;
CardView cardView;
double v = 1;
float radius = 1;
ProgressBarCircular mCircular;
SwipeRefreshLayout swipeRefreshLayout;
RecyclerView mRecyclerView;
Animation animSlideUp;
Animation animSlideDown;
Uri.Builder builder;
JsonObjectRequest callToServerRequest;
public DateList() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
callToServer(false);
}
}
);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_date_list, container, false);
((MainActivity) getActivity()).setTitle(getString(R.string.third_page));
((MainActivity) getActivity()).setToolbarVisibility(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
container.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
mCircular = (ProgressBarCircular) view.findViewById(R.id.date_list_progressBar);
animSlideUp = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_up);
animSlideDown = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_down);
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.date_list_swipe_refresh_layout);
mRecyclerView = (RecyclerView) view.findViewById(R.id.date_list_container);
keyList = new ArrayList<>();
adapter = new DatesItemAdapter(keyList, new DatesItemAdapter.DateItemClickListener() {
@Override
public void onClick(View v, int pos) {
if (pos < keyList.size()) {
try {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
linearLayoutManager.scrollToPositionWithOffset(pos, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, getActivity(), view);
((MainActivity) getActivity()).setTitle("Hello " + getActivity().getResources().getString(R.string.date_list_be) + " " + "World");
builder = new Uri.Builder();
builder.scheme("https")
.authority("mydomain.ir")
.appendPath("mywebservices")
.appendPath("myWs");
cardView = new CardView(getActivity());
try {
cardView.setRadius(2);
} catch (Exception e) {
e.printStackTrace();
}
cardView.findViewById(R.id.date_list_item_card_view);
radius = cardView.getRadius();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
try {
v = ((cardView.getMaxCardElevation()) * 1.5) + ((1 - Math.cos(45)) * (radius));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
mRecyclerView.addItemDecoration(new DividerItemDecoration(8, getActivity(), v));
} catch (Exception e) {
e.printStackTrace();
}
try {
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
} catch (Exception e) {
e.printStackTrace();
}
mRecyclerView.setItemAnimator(new TchAnimator());
mRecyclerView.setAdapter(adapter);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
mRecyclerView.setVisibility(View.GONE);
callToServer(false);
}
});
final ImageView imageView = (ImageView) view.findViewById(R.id.date_list_header_image);
final String url = "https://pic.mydomain.ir/pics/" + getResources().getString(R.string.url) + "photo.jpg";
ImageLoader loader = AppController.getInstance().getImageLoader();
loader.get(url
, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
try {
imageView.setImageBitmap(imageContainer.getBitmap());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onErrorResponse(VolleyError volleyError) {
}
});
return view;
}
public void callToServer(final boolean rTime) {
String url = builder.toString();
if (rTime) {
url = url + "&rTime=1";
} else {
url = url + "&rTime=0";
}
callToServerRequest = new JsonObjectRequest(Request.Method.GET
, url
, null
, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray array = new JSONArray(response.getString("Ticks"));
// Clears list to replace new list items
keyList.clear();
adapter.notifyDataSetChanged();
for (int i = 0; i < array.length(); i++) {
JSONObject obj = new JSONObject(array.get(i).toString());
DateItem2 item = new DateItem2();
item.setAvailable(obj.getString("available"));
item.setType(obj.getString("type"));
item.setUrl(obj.getString("url"));
item.setTime(obj.getString("time"));
item.setDescription(obj.getString("description"));
keyList.add(item);
}
if (rTime) {
mCircular.setVisibility(View.GONE);
}
adapter.notifyDataSetChanged();
mRecyclerView.setVisibility(View.VISIBLE);
swipeRefreshLayout.setRefreshing(false);
} catch (JSONException e) {
e.printStackTrace();
}
if (!rTime) {
callToServer(true);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
if (rTime) {
mCircular.setVisibility(View.GONE);
}
try {
if (ConnectionDetector.IS_CONNECTED(getActivity())) {
if (volleyError.toString().contains("[]") && !rTime) {
callToServer(true);
}
}
} catch (Exception e) {
e.printStackTrace();
}
swipeRefreshLayout.setRefreshing(false);
}
});
AppController.getInstance().addToRequestQueue(callToServerRequest, "DateList" + "callToServerRequest");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
try {
if (getView() != null) {
getView().setFocusableInTouchMode(true);
getView().requestFocus();
}
} catch (Exception e) {
e.printStackTrace();
}
getView().setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
try {
callToServerRequest.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
});
}
}
callToServer (with false input) Clears the keyList at first and then fills it. after a few milliseconds callToServer (with true input) will be called to clear the keyList again and fill with new items. This two events will repeat in each Refresh.
This is the Adapter:
public class DatesItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DateItem2> items;
private Context mContext;
private DateItemClickListener listener;
private Animation animRotate;
private LogAndReg logAndReg;
private View mainView;
public DatesItemAdapter(List<DateItem2> items, DateItemClickListener listener, Context mContext, View v) {
this.items = items;
this.listener = listener;
this.mContext = mContext;
animRotate = AnimationUtils.loadAnimation(mContext, R.anim.rotation);
this.mainView = v;
}
public interface DateItemClickListener {
void onClick(View v, int pos);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
try {
View view = LayoutInflater.from(mContext).inflate(R.layout.date_list_list_item, parent, false);
switch (viewType) {
case 0:
return new GuarantyOpen(view);
case 1:
return new GuarantyClose(view);
case 2:
return new FreeOpenRefresh(view);
case 3:
return new FreeCloseRefresh(view);
case 4:
return new FreeOpen(view);
case 5:
return new FreeClose(view);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof GuarantyOpen) {
final GuarantyOpen h0 = (GuarantyOpen) holder;
h0.time.setText(items.get(h0.getAdapterPosition()).getTime());
h0.type.setText(getModelType(h0.getAdapterPosition()));
if (items.get(h0.getAdapterPosition()).getAvailable().contentEquals("500")) {
h0.available.setText(R.string.is_available);
} else {
h0.available.setText(items.get(h0.getAdapterPosition()).getAvailable());
}
if (items.get(h0.getAdapterPosition()).getDescription().contentEquals("")) {
h0.description.setVisibility(View.GONE);
} else {
h0.description.setText(items.get(h0.getAdapterPosition()).getDescription());
}
h0.url.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
h0.url.setEnabled(true);
Intent intent = new Intent(mContext, Reserve.class);
intent.putExtra("type", items.get(h0.getAdapterPosition()).getType());
intent.putExtra("time", items.get(h0.getAdapterPosition()).getTime());
mContext.startActivity(intent);
}
});
h0.url.setBackgroundResource(R.drawable.button_bg_green_selector);
} else if (holder instanceof GuarantyClose) {
final GuarantyClose h1 = (GuarantyClose) holder;
try {
h1.time.setText(items.get(h1.getAdapterPosition()).getTime());
} catch (Exception e) {
e.printStackTrace();
}
if (items.get(h1.getAdapterPosition()).getAvailable().contentEquals("500")) {
h1.available.setText(R.string.is_available);
} else {
h1.available.setText(items.get(h1.getAdapterPosition()).getAvailable());
}
} else if (holder instanceof FreeOpenRefresh) {
final FreeOpenRefresh h2 = (FreeOpenRefresh) holder;
h2.time.setText(items.get(h2.getAdapterPosition()).getTime());
h2.type.setText(getModelType(h2.getAdapterPosition()));
if (items.get(h2.getAdapterPosition()).getAvailable().contentEquals("500")) {
h2.available.setText(R.string.is_available);
} else {
h2.available.setText(items.get(h2.getAdapterPosition()).getAvailable());
}
if (!((MainActivity) mContext).isLoggedIn()) {
h2.url.setText(R.string.date_adapter_login);
} else {
h2.url.setText(R.string.date_adapter_trans);
}
if (items.get(h2.getAdapterPosition()).getDescription().contentEquals("")) {
h2.description.setVisibility(View.GONE);
} else {
h2.description.setText(items.get(h2.getAdapterPosition()).getDescription());
}
h2.url.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
h2.url.setEnabled(false);
if (!((MainActivity) mContext).isLoggedIn()) {
h2.url.setEnabled(false);
logAndReg = LogAndReg.newInstance();
logAndReg.show(((MainActivity) mContext).getSupportFragmentManager(), "tag");
h2.childLayout.setVisibility(View.GONE);
} else {
h2.url.setEnabled(true);
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://" + items.get(h2.getAdapterPosition()).getUrl()));
mContext.startActivity(i);
}
}
});
} else if (holder instanceof FreeCloseRefresh) {
final FreeCloseRefresh h3 = (FreeCloseRefresh) holder;
h3.time.setText(items.get(h3.getAdapterPosition()).getTime());
if (items.get(h3.getAdapterPosition()).getAvailable().contentEquals("500")) {
h3.available.setText(R.string.is_available);
} else {
h3.available.setText(items.get(h3.getAdapterPosition()).getAvailable());
}
if (!((MainActivity) mContext).isLoggedIn()) {
h3.url.setText(R.string.date_adapter_login);
} else {
h3.url.setText(R.string.date_adapter_trans);
}
} else if (holder instanceof FreeOpen) {
final FreeOpen h4 = (FreeOpen) holder;
h4.time.setText(items.get(h4.getAdapterPosition()).getTime());
h4.available.setText(items.get(h4.getAdapterPosition()).getAvailable());
h4.type.setText(getModelType(h4.getAdapterPosition()));
if (items.get(h4.getAdapterPosition()).getAvailable().contentEquals("500")) {
h4.available.setText(R.string.is_available);
} else {
h4.available.setText(items.get(h4.getAdapterPosition()).getAvailable());
}
if (!((MainActivity) mContext).isLoggedIn()) {
h4.url.setText(R.string.date_adapter_login);
} else {
h4.url.setText(R.string.date_adapter_trans);
}
if (items.get(h4.getAdapterPosition()).getDescription().contentEquals("")) {
h4.description.setVisibility(View.GONE);
} else {
h4.description.setText(items.get(h4.getAdapterPosition()).getDescription());
}
h4.url.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
h4.url.setEnabled(false);
if (!((MainActivity) mContext).isLoggedIn()) {
h4.url.setEnabled(false);
logAndReg = LogAndReg.newInstance();
logAndReg.show(((MainActivity) mContext).getSupportFragmentManager(), "tag");
h4.childLayout.setVisibility(View.GONE);
} else {
h4.url.setEnabled(true);
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://" + items.get(h4.getAdapterPosition()).getUrl()));
mContext.startActivity(i);
}
}
});
} else if (holder instanceof FreeClose) {
final FreeClose h5 = (FreeClose) holder;
h5.time.setText(items.get(h5.getAdapterPosition()).getTime());
if (items.get(h5.getAdapterPosition()).getAvailable().contentEquals("500")) {
h5.available.setText(R.string.is_available);
} else {
h5.available.setText(items.get(h5.getAdapterPosition()).getAvailable());
}
if (!((MainActivity) mContext).isLoggedIn()) {
h5.url.setText(R.string.date_adapter_login);
} else {
h5.url.setText(R.string.date_adapter_trans);
}
}
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public int getItemViewType(int position) {
return items.get(position).getexpandState().getValue();
}
private class GuarantyOpen extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time, available, description, type;
Button url;
LinearLayout parentLayout;
GuarantyOpen(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
description = (TextView) v.findViewById(R.id.date_list_item_text_type);
type = (TextView) v.findViewById(R.id.date_list_item_ticket_type);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
url.setText(R.string.xml_reserve_reservation_btn);
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.GUARANTY_CLOSE);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class GuarantyClose extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time;
TextView available;
Button url;
LinearLayout parentLayout;
RelativeLayout childLayout;
GuarantyClose(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
parentLayout = (LinearLayout) v.findViewById(R.id.date_list_item_parent_layout);
childLayout = (RelativeLayout) v.findViewById(R.id.date_list_item_child_layout);
childLayout.setVisibility(View.GONE);
parentLayout.setBackgroundColor(Color.parseColor("#f3faf4"));
childLayout.setBackgroundColor(Color.parseColor("#c8e6c9"));
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.GUARANTY_OPEN);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class FreeOpenRefresh extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time;
TextView available;
TextView description;
TextView type;
Button url;
LinearLayout parentLayout;
RelativeLayout childLayout;
FreeOpenRefresh(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
description = (TextView) v.findViewById(R.id.date_list_item_text_type);
type = (TextView) v.findViewById(R.id.date_list_item_ticket_type);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
parentLayout = (LinearLayout) v.findViewById(R.id.date_list_item_parent_layout);
childLayout = (RelativeLayout) v.findViewById(R.id.date_list_item_child_layout);
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.date_list_item_btn_refresh) {
try {
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_REFRESH_OPEN);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_REFRESH_CLOSE);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private class FreeCloseRefresh extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time;
TextView available;
Button url;
LinearLayout parentLayout;
RelativeLayout childLayout;
FreeCloseRefresh(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
parentLayout = (LinearLayout) v.findViewById(R.id.date_list_item_parent_layout);
childLayout = (RelativeLayout) v.findViewById(R.id.date_list_item_child_layout);
childLayout.setVisibility(View.GONE);
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.date_list_item_btn_refresh) {
try {
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_REFRESH_CLOSE);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_REFRESH_OPEN);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private class FreeOpen extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time;
TextView available;
TextView description;
TextView type;
Button url;
LinearLayout parentLayout;
RelativeLayout childLayout;
FreeOpen(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
description = (TextView) v.findViewById(R.id.date_list_item_text_type);
type = (TextView) v.findViewById(R.id.date_list_item_ticket_type);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
parentLayout = (LinearLayout) v.findViewById(R.id.date_list_item_parent_layout);
childLayout = (RelativeLayout) v.findViewById(R.id.date_list_item_child_layout);
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_CLOSER);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class FreeClose extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView time;
TextView available;
Button url;
LinearLayout parentLayout;
RelativeLayout childLayout;
FreeClose(View v) {
super(v);
time = (TextView) v.findViewById(R.id.date_list_item_text_time);
available = (TextView) v.findViewById(R.id.date_list_item_text_available);
url = (Button) v.findViewById(R.id.date_list_item_btn_open_url);
parentLayout = (LinearLayout) v.findViewById(R.id.date_list_item_parent_layout);
childLayout = (RelativeLayout) v.findViewById(R.id.date_list_item_child_layout);
childLayout.setVisibility(View.GONE);
parentLayout.setOnClickListener(this);
}
@Override
public void onClick(View view) {
try {
listener.onClick(view, getAdapterPosition());
items.get(getAdapterPosition()).setexpandState(DateItemStatus.FREE_OPEN);
onBindViewHolder(this, getAdapterPosition());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String getModelType(int position) {
String tType;
String type = items.get(position).getType();
switch (type) {
case "bclass":
...
break;
case "normal":
...
break;
case "phone":
...
break;
case "phone-bclass":
...
break;
}
return tType;
}
}
I tried some other solution like THIS and THIS and THIS, but they didn't solve my problem. I think my problem is different with the others because I clear my List in every call.
I couldn't find out what is the problem, at all!!!