检测到不一致无效视图支架适配器错误

can*_*ner 2 java android firebase android-recyclerview google-cloud-firestore

我为我的学校项目制作了一个与 Firestore 一起运行的应用程序。当我添加第一个查询时没有问题,但如果我想添加第二个查询并返回到MainActivity,我会收到此错误并且应用程序终止。

\n
E/AndroidRuntime: FATAL EXCEPTION: main\nProcess: com.caneraltuner.cepanket2, PID: 13240\njava.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\n    at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:6156)\n    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6339)\n    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)\n    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)\n    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)\n    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)\n    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)\n    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)\n    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4255)\n    at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4010)\n    at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:2028)\n    at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:417)\n    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)\n    at android.view.Choreographer.doCallbacks(Choreographer.java:796)\n    at android.view.Choreographer.doFrame(Choreographer.java:727)\n    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)\n    at android.os.Handler.handleCallback(Handler.java:938)\n    at android.os.Handler.dispatchMessage(Handler.java:99)\n    at android.os.Looper.loop(Looper.java:223)\n    at android.app.ActivityThread.main(ActivityThread.java:7656)\n    at java.lang.reflect.Method.invoke(Native Method)\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)\n    I/Process: Sending signal. PID: 13240 SIG: 9\n
Run Code Online (Sandbox Code Playgroud)\n

MainActivity 中的代码:

\n
package com.caneraltuner.cepanket2;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.ItemTouchHelper;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\n\nimport com.firebase.ui.firestore.FirestoreRecyclerOptions;\nimport com.google.android.material.floatingactionbutton.FloatingActionButton;\nimport com.google.firebase.firestore.CollectionReference;\nimport com.google.firebase.firestore.FirebaseFirestore;\nimport com.google.firebase.firestore.Query;\n\npublic class MainActivity extends AppCompatActivity {\nprivate FirebaseFirestore db = FirebaseFirestore.getInstance();\nprivate CollectionReference notebookRef = db.collection("Cevaplar");\nprivate NoteAdapter adapter;\n\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_main);\n\n    FloatingActionButton button = findViewById(R.id.button_add_note);\n    button.setOnClickListener(new View.OnClickListener() {\n        @Override\n        public void onClick(View view) {\n            startActivity(new Intent(MainActivity.this, NewNoteActivity.class));\n        }\n    });\n    setUpRecyclerView();\n}\n\nprivate void setUpRecyclerView() {\n    Query query = notebookRef.orderBy("priority", Query.Direction.DESCENDING);\n    FirestoreRecyclerOptions<Note> options = new FirestoreRecyclerOptions.Builder<Note>()\n            .setQuery(query, Note.class)\n            .build();\n    adapter = new NoteAdapter(options);\n    RecyclerView recyclerView = findViewById(R.id.recycler_view);\n    recyclerView.setHasFixedSize(true);\n    recyclerView.setLayoutManager(new LinearLayoutManager(this));\n    recyclerView.setAdapter(adapter);\n\n    new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {\n        @Override\n        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {\n            return false;\n        }\n\n        @Override\n        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {\n            adapter.deleteItem(viewHolder.getAdapterPosition());\n        }\n    }).attachToRecyclerView(recyclerView);\n}\n\n@Override\nprotected void onStart() {\n    super.onStart();\n    adapter.startListening();\n}\n\n@Override\nprotected void onStop() {\n    super.onStop();\n    adapter.stopListening();\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

NewNoteActivity中的代码:

\n
package com.caneraltuner.cepanket2;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport android.os.Bundle;\nimport android.view.Menu;\nimport android.view.MenuInflater;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.RadioButton;\nimport android.widget.RadioGroup;\nimport android.widget.Toast;\n\nimport com.firebase.ui.firestore.FirestoreRecyclerOptions;\nimport com.google.firebase.firestore.CollectionReference;\nimport com.google.firebase.firestore.FirebaseFirestore;\nimport com.google.firebase.firestore.Query;\n\npublic class NewNoteActivity extends AppCompatActivity {\n\nprivate RadioButton radioButton, radioButton2, radioButton3, radioButton4, radioButton5, radioButton6,\n        radioButton7, radioButton8, radioButton9, radioButton10, radioButton11, radioButton12;\nString cevap1, cevap2, cevap3, cevap4;\n\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    setContentView(R.layout.activity_new_note);\n\n    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);\n    setTitle("Yeni Anket Yap");\n\n    radioButton = findViewById(R.id.radioButton);\n    radioButton2 = findViewById(R.id.radioButton2);\n    radioButton3 = findViewById(R.id.radioButton3);\n    radioButton4 = findViewById(R.id.radioButton4);\n    radioButton5 = findViewById(R.id.radioButton5);\n    radioButton6 = findViewById(R.id.radioButton6);\n    radioButton7 = findViewById(R.id.radioButton7);\n    radioButton8 = findViewById(R.id.radioButton8);\n    radioButton9 = findViewById(R.id.radioButton9);\n    radioButton10 = findViewById(R.id.radioButton10);\n    radioButton11 = findViewById(R.id.radioButton11);\n    radioButton12 = findViewById(R.id.radioButton12);\n}\n\npublic void onRadioButtonClicked(View view) {\n    //RadioButton t\xc4\xb1klama kontrol\xc3\xbc\n    boolean kontrol = ((RadioButton) view).isChecked();\n\n    // Hangi RadioButton'\xc4\xb1n t\xc4\xb1kland\xc4\xb1\xc4\x9f\xc4\xb1n\xc4\xb1n kontrol\xc3\xbc\n    switch (view.getId()) {\n        case R.id.radioButton:\n            if (kontrol)\n                cevap1 = radioButton.getText().toString();\n            break;\n        case R.id.radioButton2:\n            if (kontrol)\n                cevap1 = radioButton2.getText().toString();\n            break;\n        case R.id.radioButton3:\n            if (kontrol)\n                cevap1 = radioButton3.getText().toString();\n            break;\n        case R.id.radioButton4:\n            if (kontrol)\n                cevap2 = radioButton4.getText().toString();\n            break;\n        case R.id.radioButton5:\n            if (kontrol)\n                cevap2 = radioButton5.getText().toString();\n            break;\n        case R.id.radioButton6:\n            if (kontrol)\n                cevap2 = radioButton6.getText().toString();\n            break;\n        case R.id.radioButton7:\n            if (kontrol)\n                cevap3 = radioButton7.getText().toString();\n            break;\n        case R.id.radioButton8:\n            if (kontrol)\n                cevap3 = radioButton8.getText().toString();\n            break;\n        case R.id.radioButton9:\n            if (kontrol)\n                cevap3 = radioButton9.getText().toString();\n            break;\n        case R.id.radioButton10:\n            if (kontrol)\n                cevap4 = radioButton10.getText().toString();\n            break;\n        case R.id.radioButton11:\n            if(kontrol)\n                cevap4 = radioButton11.getText().toString();\n        case R.id.radioButton12:\n            if(kontrol)\n                cevap4 = radioButton12.getText().toString();\n            break;\n    }\n}\n\n@Override\npublic boolean onCreateOptionsMenu(Menu menu) {\n    MenuInflater menuInflater = getMenuInflater();\n    menuInflater.inflate(R.menu.new_note_menu, menu);\n    return super.onCreateOptionsMenu(menu);\n}\n\n@Override\npublic boolean onOptionsItemSelected(@NonNull MenuItem item) {\n    switch (item.getItemId()) {\n        case R.id.save_note:\n            saveNote();\n            return true;\n        default:\n            return super.onOptionsItemSelected(item);\n    }\n}\n\nprivate void saveNote() {\n    String title = "Anket";\n    int priority = 1;\n    if (cevap1.equals("") || cevap2.equals("") || cevap3.equals("") || cevap4.equals("")) {\n        Toast.makeText(this, "L\xc3\xbctfen t\xc3\xbcm cevaplar\xc4\xb1 eksiksiz se\xc3\xa7in", Toast.LENGTH_SHORT).show();\n        return;\n    }\n\n    CollectionReference reference = FirebaseFirestore.getInstance().collection("Cevaplar");\n    reference.add(new Note(title, cevap1, cevap2, cevap3, cevap4, priority));\n    Toast.makeText(this, "Cevaplar kaydedildi", Toast.LENGTH_SHORT).show();\n    finish();\n}\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

can*_*ner 16

我解决了我的问题。问题发生在MainActivity,它是由RecyclerView在不同线程中修改的数据引起的。检查所有数据访问和包装LinearLayoutManager将被视为解决方案。

我在第一个答案中编写了@sakiM给出的代码:RecyclerView和java.lang.IndexOutOfBoundsException:检测到不一致。三星设备中的视图固定器适配器positionViewHolder无效 这是代码:

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 然后我将我的匹配RecyclerViewWrapContentLinearLayoutManager

这是代码:

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

谢谢大家,祝你有美好的一天

  • 尽管此解决方法解决了原始问题,但不建议以这种方式解决。你只是忽略了异常,这可能会导致RecyclerView的状态不一致,从而导致其他崩溃。 (2认同)