Error using the RecyclerView: The specified child already has a parent

前端 未结 6 468
眼角桃花
眼角桃花 2020-12-08 13:16

I am trying to create a listView with a new RecyvlerView Adapter. I have followed the exact guide present on android developer resources. But this is giving me a strange err

相关标签:
6条回答
  • 2020-12-08 13:27

    It happens too if you scroll really fast your recyclerview. My case was inserting/moving/... items with DiffUtils and calling TransitionManager.beginDelayedTransition(view) on the root layout (and so, the recyclerview) somewhere in my code before the end of recyclerview animations

    0 讨论(0)
  • 2020-12-08 13:30

    when inflating you shouldn't attach the view to its parent. you wrote:

    View v = inflater.inflate(R.layout.my_text_view, parent, true);
    

    which should be :

    View v = inflater.inflate(R.layout.my_text_view, parent, false);
    
    0 讨论(0)
  • 2020-12-08 13:32

    For those wondering how to implement custom Transitions & excludeChildren method. Here's my approach looks like so far.

    In Kotlin: TransitionHelpers.kt

    // single child
    private fun useAutoTransition(childView: View, 
                                   excludeChildView: Boolean = true
    ) = AutoTransition().apply {
        excludeChildren(childView, excludeChildView)
        // apply any other method you need here
    }
    
    private fun useAutoTransition(@IdRes childViewId: Int, 
                                   excludeChildView: Boolean = true
    ) = AutoTransition().apply {
        excludeChildren(childViewId, excludeChildView)
        // apply any other method you need here
    }
    
    // multiple child
    fun useAutoTransitions(excludeChildView: Boolean, @IdRes vararg childViewIds: Int) {
            val auto = AutoTransition();
    
            for (id in childViewIds) {
               auto.excludeChildren(id, excludeChildView)
            }
    
            return auto;
        }
    
    fun useAutoTransitions(excludeChildView: Boolean, vararg childViews: View) {
            val auto = AutoTransition();
    
            for (view in childViews) {
               auto.excludeChildren(view, excludeChildView)
            }
    
            return auto;
        }
    

    In Java: TransitionHelpers.java

    I'm using android-retrostream to support Android API below 24, and still using Java 8 lambda & java.util.* -> java9.util.*

    import java9.util.stream.Stream;
    
        public static AutoTransition useAutoTransition(View childView, boolean excludeChildView) {
            AutoTransition auto = new AutoTransition();
            auto.excludeChildren(childView, excludeChildView);
    
            return auto;
        }
    
        public static AutoTransition useAutoTransition(@IdRes int childViewId, boolean excludeChildView) {
            AutoTransition auto = new AutoTransition();
            auto.excludeChildren(childViewId, excludeChildView);
    
            return auto;
        }
    
        public static AutoTransition useAutoTransitions(final boolean excludeChildView, @IdRes Integer... childViewIds) {
            final AutoTransition auto = new AutoTransition();
    
            Stream<Integer> ids = Stream.of(childViewIds);
            ids.forEach(id -> auto.excludeChildren(id, excludeChildView));
    
            return auto;
        }
    
        public static AutoTransition useAutoTransitions(final boolean excludeChildView, View... childViews) {
            final AutoTransition auto = new AutoTransition();
    
            Stream<View> views = Stream.of(childViews);
            views.forEach(view -> auto.excludeChildren(view, excludeChildView));
    
            return auto;
        }
    

    ThatFragment.kt

    // I'm using KTX Syntethic here
    import kotlinx.android.synthetic.main.activity_transitions.layoutParent
    import kotlinx.android.synthetic.main.activity_transitions.recyclerViewChild
    
    // Let's implemented it on TransitionManager
    override protected fun onCreate(savedInstanceState: Bundle) {
      // single RecyclerView child using View class
      TransitionManager.beginDelayedTransition(layoutParent, useAutoTransition(recyclerViewChild, true))
    
      // single RecyclerView child using @IdRes
      TransitionManager.beginDelayedTransition(layoutParent, useAutoTransition(R.id.rv_1, true))
    
      // multiple RecyclerView child                         
      TransitionManager.beginDelayedTransition(layoutParent, useAutoTransitions(true, R.id.rv_child_1, R.id.rv_child_2, R.id.rv_child_n))
    }
    

    Hopefully, it's easy to understand!

    Thanks for:

    • @victor Transitions problems when scrolling too fast
    • @westy92 Providing the workaround & implement custom Transitions

    References:

    • Animate all the things (Transitions)
    • Implementing excludeChildren see here
    • Beautiful animation with ConstraintLayout & TransitionManager
    0 讨论(0)
  • 2020-12-08 13:33

    Maybe it's a little bit late, but I had the same problem (recyclerview-v7:26.1.0) and the reason was that I tried to scroll (by scrollToPosition() method) the list in a position that was currently visible. After I added a check of position before scrolling (scroll only in the invisible position) the issue was resolved

    0 讨论(0)
  • 2020-12-08 13:38
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="80dp">
    
    <TextView
        android:id="@+id/item_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/darker_gray"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        android:textSize="22dp" />
    
    </RelativeLayout>
    

    RelativeLayout this is parent of your TextView with id item_title. Then when RecyclerView is trying to add TextView that has parent it throw exception.

    Try this code:

    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                       int viewType) {
            // create a new view
            Log.d(TAG, "onCreateViewHolder");
            RelativeLayout v = (RelativeLayout)LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item, parent, false);
            // set the view's size, margins, paddings and layout parameters
            View view = v.findViewById(R.id.text1);
            v.removeView(view);
            ViewHolder vh = new ViewHolder(view);
            return vh;
        }
    
    0 讨论(0)
  • 2020-12-08 13:44

    I solved it by removing `TransitionManager.beginDelayedTransition();

    0 讨论(0)
提交回复
热议问题