Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception when using data binding in fragment: "The specified child already has a parent. You must call removeView() on the child's parent first"

Android Studio 3.1, java 1.8

I try to use data binding:

Here settings.xml layout:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">    
    <data>    
        <variable
            name="handler"
            type="com.myproject.SettingsFragment" />    
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <android.support.constraint.ConstraintLayout
                    android:id="@+id/contentContainer"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">


                    <android.support.constraint.ConstraintLayout
                        android:id="@+id/contactUsContainer"
                        android:layout_width="match_parent"
                        android:layout_height="50dp"
                        android:onClick="@{handler::onClickContactUs}">

                        <ImageView
                            android:id="@+id/contactUsImageView"
                            android:layout_width="28dp"
                            android:layout_height="28dp"
                            app:srcCompat="@drawable/ic_settings_contacts_us" 

                        <TextView
                            android:id="@+id/contactUsTextView"
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:text="@string/contact_us"/>

                    </android.support.constraint.ConstraintLayout>    

                </android.support.constraint.ConstraintLayout>
            </FrameLayout>
        </ScrollView>
    </android.support.constraint.ConstraintLayout>    
</layout>

Here fragment SettingsFragment.java :

public class SettingsFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        SettingsBinding binding = DataBindingUtil.setContentView(getActivity(), R.layout.settings);
        binding.setHandler(this);
        return binding.getRoot();
    }

    public void onClickContactUs(View view) {
    }
}

But I get error:

    FATAL EXCEPTION: main
    java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
        at android.view.ViewGroup.addViewInner(ViewGroup.java:3337)
        at android.view.ViewGroup.addView(ViewGroup.java:3208)
        at android.view.ViewGroup.addView(ViewGroup.java:3165)
        at android.view.ViewGroup.addView(ViewGroup.java:3145)
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1425)
android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
like image 510
Alex Avatar asked Dec 16 '17 10:12

Alex


1 Answers

DataBindingUtil.setContentView() should be use for binding in an Activity because the method will set the content view for the Activity(like you would normally do with the setContentView() method). This is why you get the exception that the view(binding.getRoot()) is already appended to a parent view.

In your fragment use DataBindingUtil.inflate() to inflate the layout and create the binding without actually appending the view(which the fragment does itself later):

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    SettingsBinding binding = DataBindingUtil.inflate(inflater, R.layout.settings, container, false);
    binding.setHandler(this);
    return binding.getRoot();
}
like image 146
user Avatar answered Oct 29 '22 09:10

user