在片段中使用数据绑定时出现异常:“指定的孩子已经有一个父级。您必须先在子级的父级上调用 removeView()”

Ale*_*lex 6 android android-fragments android-databinding

Android Studio 3.1,Java 1.8

我尝试使用数据绑定:

这里settings.xml布局:

<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>
Run Code Online (Sandbox Code Playgroud)

这里片段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) {
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到错误:

    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)
Run Code Online (Sandbox Code Playgroud)

Luk*_*rog 6

DataBindingUtil.setContentView() 应该用于在 Activity 中进行绑定,因为该方法将为 Activity 设置内容视图(就像您通常使用 setContentView() 方法所做的那样)。这就是为什么您会收到 view(binding.getRoot()) 已附加到父视图的异常。

在您的片段中,使用 DataBindingUtil.inflate() 来扩展布局并创建绑定,而无需实际附加视图(片段稍后会自行完成):

@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();
}
Run Code Online (Sandbox Code Playgroud)