Im making an activity log and i have a problem where i can't scroll down an Inconsistency error keeps popping up. I have added the notifyDataSetChanged method as well but i still have no luck in fixing the error.
Here is the error that i am getting
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 7(offset:7).state:11 android.support.v7.widget.RecyclerView{edb17ac
This is my Adapter code
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<ListItem> listItems;
private Context context;
public MyAdapter(List<ListItem> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
public MyAdapter(Context applicationContext, List<ListItem> listItems) {
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
ListItem listItem = listItems.get(position);
String key = listItem.getHead();
if (key.equals("LockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.red_gradient));
holder.image1.setImageResource(R.drawable.lockwhite);
holder.image2.setImageResource(R.drawable.lockwhite);
} else if (key.equals("UnlockTime")) {
holder.textViewHead.setText(listItem.getTime());
holder.textViewDesc.setText(listItem.getDesc());
holder.layout.setBackground(ContextCompat.getDrawable(context, R.drawable.green_gradient));
holder.image1.setImageResource(R.drawable.unlockwhite);
holder.image2.setImageResource(R.drawable.unlockwhite);
}
}
@Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView textViewHead;
public TextView textViewDesc;
public RelativeLayout layout;
public ImageView image1;
public ImageView image2;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
layout= (RelativeLayout) itemView.findViewById(R.id.relativelayout);
image1 = itemView.findViewById(R.id.padlock1);
image2 = itemView.findViewById(R.id.padlock2);
}
}
}
This is my Activity
public class ActivityLog extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<ListItem> listItems;
SwipeRefreshLayout swipe;
DatabaseReference database;
LinearLayout lLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycle);
recyclerView.setHasFixedSize(true);
// SharedPreferences preferences=getSharedPreferences(LOCK_PREFS,MODE_PRIVATE);
database = FirebaseDatabase.getInstance().getReference("Activity Log/device321");
swipe = findViewById(R.id.swiper);
listItems = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter.notifyDataSetChanged();
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
swipe.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
database.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersnapshot : dataSnapshot.getChildren()) {
Map<String, String> map = (Map<String, String>) usersnapshot.getValue();
for (Map.Entry<String, String> entry : map.entrySet()) {
listItems.add(new ListItem(entry.getKey(), entry.getValue(),usersnapshot.child("Time").getValue().toString()
));
}
}
recyclerView.setAdapter(new MyAdapter(getApplicationContext(),listItems));
adapter = new MyAdapter(listItems, ActivityLog.this);
recyclerView.setAdapter(adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipe.setRefreshing(false);
}
},2000);
listItems.clear();
}
});
}
}
Any help would be greatly appreciated thank you
You shouldn't remove items from list when you are binding viewholder because you change positions and RecyclerView needs to be recreated. Remove them in your constructor or in any place than your adapter.
public MyAdapter(List<ListItem> listItems, Context context) {
for(int i=0;i<listItems.size(); i++){
if (listItems.get(position).getHead().equals("Time")){
listItems.remove(listItems.get(position));
}
}
this.listItems = listItems;
this.context = context;
}