RecyclerView ขัดข้องเมื่อ“ มุมมองที่ถูกทิ้งหรือแนบมาอาจไม่สามารถรีไซเคิลได้”


115

ฉันใช้การใช้งานง่าย ๆ ที่RecyclerViewนำมาจากเว็บไซต์ Android โดยใช้ a StaggeredGridLayoutManagerและฉันได้รับข้อผิดพลาดนี้ทำให้แอปของฉันขัดข้อง:

java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true
            at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:3501)
            at android.support.v7.widget.RecyclerView$LayoutManager.scrapOrRecycleView(RecyclerView.java:5355)
            at android.support.v7.widget.RecyclerView$LayoutManager.detachAndScrapAttachedViews(RecyclerView.java:5340)
            at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:572)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1918)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2155)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:14008)
            at android.view.ViewGroup.layout(ViewGroup.java:4373)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:725)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5041)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)  

โดยง่ายฉันหมายความว่ามันเป็นการใช้งานเดียวกันกับที่นำมาจากหน้านี้บนเว็บไซต์ของพวกเขาความแตกต่างเพียงอย่างเดียวคือเค้าโครงรายการกริดของฉันคือImageViewและสองสามTextViewวินาทีดังนั้นฉันจะไม่รบกวนการโพสต์โค้ดของฉันใหม่

มีใครอีกบ้างที่ได้รับข้อผิดพลาดนี้และรู้วิธีจัดการกับมัน?


คุณมีวิธีแก้ปัญหาหรือไม่?
Pratik Butani

คำตอบ:


191

ข้อผิดพลาดนี้เกิดขึ้นหากใน XML ของคุณคุณได้android:animateLayoutChangesตั้งค่าเป็นจริงและคุณเรียกnotifyDataSetChanged()ใช้อะแด็ปเตอร์ของ RecyclerView ในโค้ด Java

ดังนั้นหลีกเลี่ยงการใช้android:animateLayoutChangesกับ RecyclerViews


22
แล้วจะใช้คุณสมบัติ animateLayoutChanges ใน Recyclerview ได้อย่างไร?
dhuma1981

คุณพยายามทำอะไรให้สำเร็จ? แอนิเมชั่นรายการ? หากเป็นเช่นนั้น RecyclerView API รองรับสิ่งนี้โปรดดูเอกสาร: developer.android.com/reference/android/support/v7/widget/…
Kenneth

4
@ dhuma1981 หากตั้งค่าแอนิเมเตอร์รายการผ่าน mRecyclerView.setItemAnimator (DefaultItemAnimator ใหม่ ()); แล้ว animateLayoutChanges ก็ไม่จำเป็นต้องเป็นจริง
Rich Ehmer

RecyclerViewใช้DefaultItemAnimatorโดยค่าเริ่มต้น
Benjamin

-, - ฉันมีปัญหานี้อย่างที่คุณอธิบายไว้
Ninja Coding

52

android:animateLayoutChangesฉันเคยที่จะจัดการกับความผิดพลาดนี้และในกรณีของฉันมันไม่ได้มีอะไรจะทำอย่างไรกับ

สิ่งที่RecyclerViewเรากำลังสร้างมีมุมมองมากกว่าหนึ่งประเภทและบางส่วนก็มีมุมมองอยู่EditTextในนั้น หลังจากนั้นไม่นานเราได้ตรึงปัญหาให้เกี่ยวข้องกับโฟกัส ข้อผิดพลาดนี้เกิดขึ้นขณะรีไซเคิลEditTextและหนึ่งในนั้นถูกโฟกัส

โดยปกติแล้วเราพยายามล้างโฟกัสเมื่อข้อมูลใหม่ถูกผูกไว้กับมุมมองรีไซเคิล แต่ไม่ได้ผลจนกว่าandroid:focusableInTouchMode="true"จะเปิดRecycleViewใช้งาน อันที่จริงนั่นคือการเปลี่ยนแปลงเดียวที่จำเป็นในที่สุดเพื่อให้ปัญหานี้หายไป


2
ยอดเยี่ยมแก้ไขปัญหาที่เกี่ยวข้องกับการโฟกัสหลายจุดที่ฉันมีเมื่อใช้ EditTexts ใน RecyclerView ขอบคุณ!
Rabie Jradi

1
ฉันมี ACET ในมุมมองรีไซเคิลและมันก็พังทลาย โพสต์นี้ช่วยฉันไว้
ไก่วัง

และฉันไม่มีข้อความแก้ไขในรายการฉันมีช่องทำเครื่องหมาย ฉันควรลองandroid:focusableInTouchMode="true"เพราะมันเกิดขึ้นเพียงบางครั้งในบางอุปกรณ์ (ไม่ค่อยมี) และฉันเดาว่ามันไม่เกี่ยวข้องกับปัญหาของฉัน แต่การติดตามสแต็กสำหรับความผิดพลาดนั้นเกือบจะเหมือนกัน
Shivansh

นี่เป็นกรณีของฉัน แต่การตั้งค่าandroid:focusableInTouchMode="true"ไม่ได้ช่วยฉันเลย ดังนั้นฉันจึงเคลียร์โฟกัสในการonViewDetachedFromWindowโทรกลับ public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) { if (holder instanceof ItemViewHolder) { ItemViewHolder item = (ItemViewHolder) holder; if (item.editText.isFocused()) item.editText.clearFocus(); } }
artman

24

ฉันลบandroid:animateLayoutChangesคุณสมบัติออกจากโครงร่างและปัญหาได้รับการแก้ไขแล้ว


ฉันเริ่มได้รับความผิดพลาดนี้เมื่อฉันวางandroid:animateLayoutChangesบน RV ด้วย
Mauker

2
มีการตั้งค่าสถานะนี้บนคอนเทนเนอร์หลัก (Relative Layout) แก้ไขปัญหา
2454z

@ 1911z คุณกำลังบอกว่าคุณมีแฟล็กบนคอนเทนเนอร์หลักและลบออกจากที่นั่นแก้ไขปัญหาได้หรือไม่?
RamPrasadBismil

14

ในบรรดาเหตุผลที่ทุกคนสามารถเผชิญกับปัญหานี้ตรวจสอบว่าคุณได้ตั้งค่าแอตทริบิวต์android:animateLayoutChanges="true"เป็น RecyclerView สิ่งนี้จะทำให้การรีไซเคิลและการใส่รายการ RecyclerView ใหม่ล้มเหลว ลบออกและกำหนดแอตทริบิวต์ให้กับคอนเทนเนอร์หลักของ RecyclerView เช่น LinearLayout / RelativeLayout และคุณจะเห็นว่าปัญหานี้หายไป


ฉันเห็นข้อผิดพลาดนี้แม้ว่าฉันจะตั้งค่าแอตทริบิวต์บนคอนเทนเนอร์หลักของ RV
RamPrasadBismil

@RamPrasadBismil กรุณาโพสต์รหัสของคุณแล้วเราจะดูได้ไหม?
Ram Iyer

12

ฉันใช้เวลาสองวัน แต่ไม่สามารถแก้ไขได้ในที่สุดฉันต้องปิดใช้งานการดึงข้อมูลรายการล่วงหน้า

เมื่อตั้งค่าตัวจัดการเค้าโครงคุณสามารถโทรหา

mGridLayoutManager.setItemPrefetchEnabled(false);

มันทำให้ข้อผิดพลาดหายไปสำหรับฉัน หวังว่าจะเป็นประโยชน์สำหรับใครบางคน


ทำงานให้ฉัน ขอบคุณ
Vicky

1
ฉันกังวลมากเกี่ยวกับผู้ที่ใช้โซลูชันนี้ คุณสูญเสียจำนวนมากในการปิดใช้งานแฟล็กนี้และข้อผิดพลาดยังคงอยู่ในที่อื่น -
Felipe Castilhos

9

ฉันยังพบข้อผิดพลาดเดียวกันเมื่อเลื่อนไปที่RecyclerView: จากนั้นฉันลบanimateLayoutChanges="true"ในไฟล์เลย์เอาต์RecyclerViewจากนั้นทุกอย่างก็ใช้ได้


8

ในขณะที่ใช้ส่วนหัวที่เหนียวของ slimfit ฉันพบข้อผิดพลาดนี้ มันเกิดจากการตั้งค่าตำแหน่งแรกผิด ฉันได้คำตอบที่นี่

public void onBindViewHolder(MainViewHolder holder, int position) {

  final View itemView = holder.itemView;
  final LayoutManager.LayoutParams params = LayoutManager.LayoutParams.from(itemView.getLayoutParams());

  params.setSlm(LinearSLM.ID);
  params.width = ViewGroup.LayoutParams.MATCH_PARENT;
  params.setFirstPosition(item.mSectionFirstPosition);
  itemView.setLayoutParams(params);

}

ตรวจสอบให้แน่ใจว่าคุณได้ส่งค่าที่ถูกต้องสำหรับ mSectionFirstPosition


ยินดีต้อนรับสู่ StackOverflow โปรดให้คำตอบแบบเต็มแทนลิงก์ได้ไหม
slfan

ที่itemนี่คืออะไร?
Bugs เกิดขึ้นใน

เป็นรายการที่จะแสดงในมุมมองผู้รีไซเคิล โดยพื้นฐานแล้วฉันกำลังบันทึกตำแหน่งส่วนแรกกับแต่ละรายการ
Jaspinder Kaur

8

ฉันพบปัญหานี้เมื่อเช้านี้ แต่ฉันไม่ได้เผชิญกับเหตุผลเดียวกับที่กล่าวไว้ข้างต้น

จากการดีบักฉันพบว่ามุมมองรายการใน ViewHolder ของฉันมีmParentและไม่เป็นโมฆะซึ่งในกรณีปกติควรเป็นไม่มี (นั่นคือสิ่งที่บันทึกบอกว่า "มุมมองที่แนบมาอาจไม่สามารถนำกลับมาใช้ใหม่ได้" ฉันคิดว่าหมายความว่าหากมุมมองเด็ก ติดอยู่กับผู้ปกครองแล้วมันจะทำให้เกิดความล้มเหลวในการรีไซเคิลได้อย่างไร)

แต่ฉันไม่ได้แนบมุมมองเด็กทุกครั้งด้วยตนเอง และฉันพบว่ามันเสร็จแล้วเมื่อฉันพยายามขยายมุมมองเด็กใน ViewHolder ของฉันบางอย่างเช่น:

layoutInflater.inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)

และพารามิเตอร์สุดท้ายattachToRootควรเป็นเท็จ

หลังจากเปลี่ยนเป็นfalseฉันได้แก้ไขปัญหาแล้ว

อย่างไรก็ตามฉันเห็นความผิดพลาดนี้เกิดขึ้นเมื่อฉันอัปเกรดไลบรารีการสนับสนุนเป็นเวอร์ชันล่าสุด 25.0.0 เท่านั้น ก่อนหน้านี้ฉันใช้เวอร์ชัน 23.4.0 และฉันไม่เห็นปัญหานี้เกิดขึ้น ฉันเดาว่าน่าจะมีอะไรเปลี่ยนแปลงในไลบรารีการสนับสนุนล่าสุด

หวังว่าจะช่วยได้


6

ในกรณีของฉันมันเกิดขึ้นเนื่องจากฉันTransitionทำงานอยู่เมื่อพยายามปรับขนาด RecyclerView เนื่องจากแป้นพิมพ์ซอฟต์แวร์กำลังจะแสดง

ฉันแก้ไขมันโดยไม่รวม RecyclerView จากTransitionโดยใช้ Transition.excludeTarget(R.id.recyclerview, true);


6

มีสาเหตุหลายประการที่เรียกข้อยกเว้นนี้ ในกรณีของฉันมันเป็นเพราะภาพเคลื่อนไหวที่กำลังทำงานอยู่นั่นเป็นสาเหตุที่ทำให้มุมมองยังคงแนบอยู่และไม่สามารถลบออกจากมุมมองได้ เฉพาะเมื่อภาพเคลื่อนไหวเสร็จสิ้นดังนั้นจึงสามารถลบมุมมองและรีไซเคิลได้

มีแอนิเมชั่นสองประเภทที่อาจส่งผลต่อการรีไซเคิลการดูรีไซเคิล

1) เป็นRecyclerView.ItemAnimator- สิ่งนี้ไม่ควรเป็นปัญหา สิ่งนี้น่าจะปลอดภัยมากที่จะใช้เนื่องจากตรวจสอบสิ่งที่แนบมาและทิ้งมุมมองและจัดการรีไซเคิลอย่างถูกต้อง

2) android:animateLayoutChanges="true"หรือTransitionManager.beginDelayedTransition()หรือ TransitionManager.go () เป็นต้น - แอนิเมชั่นเหล่านี้ทำงานด้วยตัวมันเองและถือรายการเพื่อทำให้เคลื่อนไหว ส่งผลให้มุมมองถูกบังคับให้แนบจนกว่าภาพเคลื่อนไหวจะเสร็จสิ้น Recyclerview ไม่มีความรู้ใด ๆ เกี่ยวกับภาพเคลื่อนไหวเหล่านี้เนื่องจากอยู่นอกขอบเขต ดังนั้นrecyclerviewอาจพยายามรีไซเคิลไอเท็มที่คิดว่าสามารถรีไซเคิลได้อย่างถูกต้อง แต่ปัญหาคือ API เหล่านี้ยังคงยึดการดูจนกว่าจะมีการเคลื่อนไหวเสร็จสิ้น

หากคุณกำลังใช้android:animateLayoutChanges="true"หรือTransitionManager.beginDelayedTransition()หรือ TransitionManager.go () ฯลฯ เพียงแค่ลบRecyclerViewและลูกของมันออกจากภาพเคลื่อนไหว

คุณสามารถทำได้โดยการถือสายTransitionและโทร

Transition.excludeChildren(yourRecyclerView, true)
Transition.excludeTarget(yourRecyclerView, true)

บันทึก:

โปรดทราบว่าสิ่งสำคัญคือต้องใช้Transition.excludeChildren()เพื่อแยกRecyclerviewเด็กทั้งหมดออกจากแอนิเมชั่นไม่ใช่แค่Recyclerviewตัวเอง


ขอบคุณ! TransitionManager.beginDelayedTransition () เป็นสาเหตุของปัญหาในกรณีของฉัน Transition.excludeChildrenคุณสามารถอัปเดตตัวอย่างเช่นรหัสของคุณมีรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการใช้ คุณยกตัวอย่างการเปลี่ยนแปลงวัตถุที่ชอบ: val transition = AutoTransition()โทรกับวัตถุนี้และผ่านมันไปexcludeChildren(recyclerView, true) beginDelayedTransaction() as the second parameter
Danilo Prado

5

ฉันได้รับข้อผิดพลาดนี้เช่นกันทุกครั้งที่มี animateLayoutChanges = "true" ในไฟล์เลย์เอาต์สำหรับ RecyclerView ลบแอตทริบิวต์นี้และข้อผิดพลาดจะหายไป!


โปรดทราบว่าคำถามนี้มาจากปี 2014 และคุณสมบัติอาจเปลี่ยนแปลงไปในตอนนี้
Korashen

2
ยังไม่มีการเปลี่ยนแปลง
Sanjay Kushwah

4

แม้ว่าในกรณีของฉันจะถูกลบออกanimateOnLayoutChangeจาก RecyclerView ที่แก้ไขข้อขัดข้อง แต่ฉันก็ยังต้องการความสามารถในการเคลื่อนไหวการเปลี่ยนแปลงเค้าโครงภายใน viewHolder เพื่อให้สิ่งนี้ใช้งานได้LinearLayout' in the view holder needs theanimateOnLayoutChange 'เป็นจริง แต่ฉันต้องการnotifyItemChangedอะแดปเตอร์ จากนั้นอนุญาตให้ทั้งสองภาพเคลื่อนไหวการเปลี่ยนเลย์เอาต์เริ่มต้น (สำหรับการขยายและการยุบ viewHolder) และยังหลีกเลี่ยงข้อยกเว้นที่ถูกทิ้ง ใช่หลีกเลี่ยงการวาง animateOnLayoutChange บน recylcerView และใช้วิธีการแจ้งเตือนต่างๆเพื่อเปิดใช้งานภาพเคลื่อนไหวเริ่มต้นในการเปลี่ยนแปลงขนาดมุมมอง


ฉันกำลังพยายามทำสิ่งเดียวกันเพื่อทำให้การขยายของรายการเคลื่อนไหว แต่การเรียกใช้ alertItemChanged ในอะแดปเตอร์ทำให้รายการกะพริบหลังจากการเปลี่ยนแปลง (ภาพเคลื่อนไหวใช้งานได้)! คุณจะป้องกันได้อย่างไร?
Flyview

สำหรับกรณีการใช้งานของเราเราได้เปลี่ยนโค้ดที่กำหนดเองของเราโดยใช้ animateOnLayoutChange เพื่อใช้โครงร่างที่ขยายได้ มันทำสิ่งเดียวกันกับที่เราพยายามทำให้สำเร็จ แต่มีความยืดหยุ่นมากกว่า github.com/chuross/expandable-layout
kingargyle

3

ฉันแก้ปัญหานี้โดยการลบparent.addView()ในonCreateViewHolder

นี่คือรหัสของฉัน

public MyViewHolder onCreateViewwHolder(ViewGroup parent, int viewType)  {
    Button addButton = new Button(context);
    //parent.addView(addButton);
    return new MyViewHolder(addButton);
}

ฟังก์ชั่นandroid.support.v7.widget.RecyclerViewRecycler.recyclerViewHolderinternal()ตรวจสอบว่าปุ่มของฉันมีผู้ปกครองอยู่แล้วหรือไม่ ซึ่งถ้าเราเพิ่มปุ่มให้กับ parent ก็จะกำหนดRecyclerViewให้mParentตัวแปรของมันด้วย


ฉันคิดว่ามันเป็นข้อกำหนดใหม่ฉันได้แนบไปกับผู้ปกครองในเวอร์ชัน 24 ของการสนับสนุนของไลบรารีเมื่ออัปเดตเป็น 25 ฉันได้รับความผิดพลาด
Kirill Kulakov

1

ฉันเห็นสิ่งนี้เกิดขึ้นกับฉันเมื่อฉันใช้วัตถุที่กำหนดเองในViewHolderสำหรับRecyclerViewอะแดปเตอร์

ในการแก้ไขปัญหาฉันได้ล้างวัตถุที่กำหนดเองซึ่งในกรณีของฉันคือตัวจับเวลาonViewRecycled(ViewHolder holder)สำหรับอะแดปเตอร์ดังต่อไปนี้:

    public void onViewRecycled(ViewHolder holder) {
        if(holder instanceof  EntityViewHolder) {
            if(((EntityViewHolder)holder).timer != null) {
                ((EntityViewHolder) holder).timer.cancel();
            }
        }
        super.onViewRecycled(holder);
    }

สิ่งนี้แก้ไขข้อบกพร่อง


1
    /**
     * Informs the recycler whether this item can be recycled. Views which are not
     * recyclable will not be reused for other items until setIsRecyclable() is
     * later set to true. Calls to setIsRecyclable() should always be paired (one
     * call to setIsRecyclabe(false) should always be matched with a later call to
     * setIsRecyclable(true)). Pairs of calls may be nested, as the state is internally
     * reference-counted.
     *
     * @param recyclable Whether this item is available to be recycled. Default value
     * is true.
     *
     * @see #isRecyclable()
     */
    public final void setIsRecyclable(boolean recyclable) {
        mIsRecyclableCount = recyclable ? mIsRecyclableCount - 1 : mIsRecyclableCount + 1;
        if (mIsRecyclableCount < 0) {
            mIsRecyclableCount = 0;
            if (DEBUG) {
                throw new RuntimeException("isRecyclable decremented below 0: " +
                        "unmatched pair of setIsRecyable() calls for " + this);
            }
            Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: " +
                    "unmatched pair of setIsRecyable() calls for " + this);
        } else if (!recyclable && mIsRecyclableCount == 1) {
            mFlags |= FLAG_NOT_RECYCLABLE;
        } else if (recyclable && mIsRecyclableCount == 0) {
            mFl`enter code here`ags &= ~FLAG_NOT_RECYCLABLE;
        }
        if (DEBUG) {
            Log.d(TAG, "setIsRecyclable val:" + recyclable + ":" + this);
        }
    }

1

1 remove、: ลบข้อมูลออกจากรายการ

2 notifyDataSetChanged、: informDataSetChanged ();

3 notifyItemRemoved、: แสดงภาพเคลื่อนไหว

4 notifyItemRangeChanged、: ขนาดมุมมองระยะและวาดใหม่viewHolders(onBindViewHolder methods)


ฉันทำเสร็จแล้วnotifyItemRemovedเมื่อลบfooterและแอพขัดข้องเปลี่ยนเป็นnotifyDataSetChangedและตอนนี้ใช้งานได้ดี ขอบคุณ
Siarhei

1

ในกรณีของฉันฉันใช้TransitionManager.beginDelayedTransition()ก่อนที่จะเพิ่มมุมมองที่ด้านบนของ RecyclerView ฉันลบTransitionManager.beginDelayedTransition()และไม่มีความผิดพลาด


1

ฉันแก้ไขปัญหานี้โดยการโทร

setHasStableIds(true);

ในตัวสร้างของอะแด็ปเตอร์และการแทนที่getItemIdในอะแด็ปเตอร์:

@Override
public long getItemId(int position) {
    return position;
}


0

ฉันใช้ com.squareup.picasso.RequestCreator

public void into(android.widget.ImageView target,
             Callback callback)

เพื่อปรับขนาดขนาดของ ImageView แบบไดนามิกหลังจากดาวน์โหลดรูปภาพจากอินเทอร์เน็ตและบันทึกความกว้างและความสูงที่ปรับขนาดแล้วเพื่อรักษาขนาดมุมมอง ฉันได้รับข้อยกเว้นนี้เนื่องจากฉันบันทึกไว้LayoutParamsใน a Mapและใน onBindViewHolder ของฉันฉันดึงมันมาและตั้งค่าเป็นไฟล์ImageView. ฉันแก้ไขสิ่งนี้โดยใช้ImmutablePair<Integer, Integer>เพื่อเก็บเฉพาะขนาดของ ImageView แทนที่จะเป็นสถานะอื่น ๆ และใช้รหัสต่อไปนี้เพื่อกู้คืน

ViewGroup.LayoutParams params = image.getLayoutParams();
params.width = widthAndHeight.getLeft();
params.height = widthAndHeight.getRight();
image.setLayoutParams(params);

0

สำหรับฉันข้อผิดพลาดเดียวกันกับที่เกิดจาก LayoutTransition ใน ViewGroup ระดับที่สูงขึ้น


0

ขอฉันเพิ่มวิธีแก้ไขอื่นที่เป็นไปได้สำหรับปัญหาประเภทนี้ ฉันมีปัญหาเดียวกันกับไลบรารีsuperSlimสำหรับส่วนหัวที่เหนียวในRecyclerView. ฉันเคยMatrixCursorตั้งค่าข้อมูลเป็นRecyclerViewCursorAdapter. สาเหตุของปัญหานี้คือคอลัมน์ ID เท่ากับ0ส่วนหัวทั้งหมด หวังว่าจะช่วยให้ใครบางคนประหยัดเวลาในการดีบั๊กได้สองสามวัน


0

ในกรณีของฉันปัญหาเกิดจากการใช้วิธีนี้ไม่ถูกต้องpublic long getItemId(int position)(แทนที่จากRecyclerView.Adapterวิธีการ)

รหัสเก่าจะได้รับสองรหัสที่แตกต่างกันสำหรับรายการเดียวกัน (ในกรณีของฉันคือรายการส่วนท้าย) หลังจากแก้ไขการใช้งานแล้วปัญหาได้หายไป


0

วิธีแก้ปัญหาหากเหตุผลของ Exception คือสิ่งที่ itemView มีพาเรนต์ ในโค้ดที่คุณมี alertItemRemoved (ตำแหน่ง) ให้ลบ itemView จาก RecyclerView:

View itemView = mRecyclerView.getLayoutManager().findViewByPosition(position);
if (itemView != null && itemView.getParent() != null) {
    ((ViewGroup) itemView.getParent()).removeView(itemView);
}
notifyItemRemoved(position);

0

กรณีแปลก ๆ ที่เกิดขึ้นสำหรับฉันคือฉันมีสมาชิกมุมมองในอะแด็ปเตอร์และฉันขี้เกียจสร้างอินสแตนซ์มุมมองซึ่งไม่จำเป็นต้องทำกับมุมมองรีไซเคิล

นอกจากนี้ยังขัดต่อหลักการมุมมองรีไซเคิลซึ่งในฐานะที่คุณจัดเก็บข้อมูลอ้างอิงถึงมุมมองในกรณีนี้ ฉันยกตัวอย่างสั้น ๆ ด้านล่าง:

// typically we would do this in a grid view adapter:
View v;
// ...
if(v = null){
v = LayoutInflater.inflate ...;
}

// Now with recycle view there is NO need to store a reference to View
// and lazy instantiate. So get rid of your View v member

0

ข้อยกเว้นนี้ไม่ใช่สาเหตุของ

หุ่นยนต์: animateLayoutChanges

หรือ

หุ่นยนต์: focusableInTouchMode

นี้ตอบที่ถูกต้องสุดท้ายคือเพียงเพราะคุณตั้งLayoutParams ผิด

    nameLP = new LinearLayout.LayoutParams(context.getResources().getDisplayMetrics().widthPixels, LinearLayout.LayoutParams.WRAP_CONTENT);
    nameLP2 = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT);

nameLP ก็โอเค nameLP2 เกิดข้อผิดพลาด Bug อยู่ที่นี่

ฉันลองใช้คำตอบทั้งหมดของหน้านี้ เชื่อฉัน.


0

ผมมีปัญหานี้เพราะผมเขียนทับequals()และhashcode()วิธีการViewHolderของRecyclerView.ViewHolder โดยการคำนวณความเท่าเทียมกันของข้อมูลและแฮชโค้ดแล้วตรรกะรีไซเคิลไม่ได้ทำงานและตกผมก็ลบเขียนทับและถาวร

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.