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
toWrapContentLinearLayoutManager
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