Home > Back-end >  Inconsistency Detected Invalid View Holder Adapter Error
Inconsistency Detected Invalid View Holder Adapter Error

Time:10-13

I made an application running with Firestore for my school project. When i adding first query there is no problem but if i want to add second one and going back to MainActivity i get this error and application dies.

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.caneraltuner.cepanket2, PID: 13240
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionNoteHolder{f9f3667 position=2 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{c64d4da VFED..... ........ 0,0-1080,1584 #7f0801de app:id/recycler_view}, adapter:com.caneraltuner.cepanket2.NoteAdapter@2549b6d, layout:androidx.recyclerview.widget.LinearLayoutManager@8af93a2, context:com.caneraltuner.cepanket2.MainActivity@c95bf4d
    at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:6156)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6339)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4255)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4010)
    at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:2028)
    at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:417)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
    at android.view.Choreographer.doCallbacks(Choreographer.java:796)
    at android.view.Choreographer.doFrame(Choreographer.java:727)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
    I/Process: Sending signal. PID: 13240 SIG: 9

Code in MainActivity:

package com.caneraltuner.cepanket2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;

public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference notebookRef = db.collection("Cevaplar");
private NoteAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FloatingActionButton button = findViewById(R.id.button_add_note);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(MainActivity.this, NewNoteActivity.class));
        }
    });
    setUpRecyclerView();
}

private void setUpRecyclerView() {
    Query query = notebookRef.orderBy("priority", Query.Direction.DESCENDING);
    FirestoreRecyclerOptions<Note> options = new FirestoreRecyclerOptions.Builder<Note>()
            .setQuery(query, Note.class)
            .build();
    adapter = new NoteAdapter(options);
    RecyclerView recyclerView = findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);

    new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
            adapter.deleteItem(viewHolder.getAdapterPosition());
        }
    }).attachToRecyclerView(recyclerView);
}

@Override
protected void onStart() {
    super.onStart();
    adapter.startListening();
}

@Override
protected void onStop() {
    super.onStop();
    adapter.stopListening();
}
}

Code in NewNoteActivity:

package com.caneraltuner.cepanket2;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;

public class NewNoteActivity extends AppCompatActivity {

private RadioButton radioButton, radioButton2, radioButton3, radioButton4, radioButton5, radioButton6,
        radioButton7, radioButton8, radioButton9, radioButton10, radioButton11, radioButton12;
String cevap1, cevap2, cevap3, cevap4;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_note);

    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
    setTitle("Yeni Anket Yap");

    radioButton = findViewById(R.id.radioButton);
    radioButton2 = findViewById(R.id.radioButton2);
    radioButton3 = findViewById(R.id.radioButton3);
    radioButton4 = findViewById(R.id.radioButton4);
    radioButton5 = findViewById(R.id.radioButton5);
    radioButton6 = findViewById(R.id.radioButton6);
    radioButton7 = findViewById(R.id.radioButton7);
    radioButton8 = findViewById(R.id.radioButton8);
    radioButton9 = findViewById(R.id.radioButton9);
    radioButton10 = findViewById(R.id.radioButton10);
    radioButton11 = findViewById(R.id.radioButton11);
    radioButton12 = findViewById(R.id.radioButton12);
}

public void onRadioButtonClicked(View view) {
    //RadioButton tıklama kontrolü
    boolean kontrol = ((RadioButton) view).isChecked();

    // Hangi RadioButton'ın tıklandığının kontrolü
    switch (view.getId()) {
        case R.id.radioButton:
            if (kontrol)
                cevap1 = radioButton.getText().toString();
            break;
        case R.id.radioButton2:
            if (kontrol)
                cevap1 = radioButton2.getText().toString();
            break;
        case R.id.radioButton3:
            if (kontrol)
                cevap1 = radioButton3.getText().toString();
            break;
        case R.id.radioButton4:
            if (kontrol)
                cevap2 = radioButton4.getText().toString();
            break;
        case R.id.radioButton5:
            if (kontrol)
                cevap2 = radioButton5.getText().toString();
            break;
        case R.id.radioButton6:
            if (kontrol)
                cevap2 = radioButton6.getText().toString();
            break;
        case R.id.radioButton7:
            if (kontrol)
                cevap3 = radioButton7.getText().toString();
            break;
        case R.id.radioButton8:
            if (kontrol)
                cevap3 = radioButton8.getText().toString();
            break;
        case R.id.radioButton9:
            if (kontrol)
                cevap3 = radioButton9.getText().toString();
            break;
        case R.id.radioButton10:
            if (kontrol)
                cevap4 = radioButton10.getText().toString();
            break;
        case R.id.radioButton11:
            if(kontrol)
                cevap4 = radioButton11.getText().toString();
        case R.id.radioButton12:
            if(kontrol)
                cevap4 = radioButton12.getText().toString();
            break;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.new_note_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    switch (item.getItemId()) {
        case R.id.save_note:
            saveNote();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

private void saveNote() {
    String title = "Anket";
    int priority = 1;
    if (cevap1.equals("") || cevap2.equals("") || cevap3.equals("") || cevap4.equals("")) {
        Toast.makeText(this, "Lütfen tüm cevapları eksiksiz seçin", Toast.LENGTH_SHORT).show();
        return;
    }

    CollectionReference reference = FirebaseFirestore.getInstance().collection("Cevaplar");
    reference.add(new Note(title, cevap1, cevap2, cevap3, cevap4, priority));
    Toast.makeText(this, "Cevaplar kaydedildi", Toast.LENGTH_SHORT).show();
    finish();
}

}

CodePudding user response:

I solved my problem. The problem happens in MainActivity, it is caused by RecyclerView Data that has been modified in different thread. checking all data access and wrapping LinearLayoutManager would be considered as a solution.

I wrote the code gave by @sakiM at first answer: RecyclerView and java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder in Samsung devices Here is the code:

public class WrapContentLinearLayoutManager extends LinearLayoutManager {
    public WrapContentLinearLayoutManager(Context context) {
        super(context);
    }

    public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            super.onLayoutChildren(recycler, state);
        } catch (IndexOutOfBoundsException e) {
            Log.e("TAG", "meet a IOOBE in RecyclerView");
        }
    }
}
  • Then i matched my RecyclerView to WrapContentLinearLayoutManager

Here is the code:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

Thank you all, have a nice day

  • Related