数据绑定、TabLayout 和“找不到片段 ID 的视图”

Data binding, TabLayout and “No view found for id for fragment”

在我的 Android 应用程序中,我有一个带有 RecyclerView 的 Activity,当用户单击一个项目时,我调用另一个 Activity,它有一个包含 2 个片段的 TabLayout,每个选项卡用于一组由用户填写的字段。

当我不使用数据绑定时,一切都很好,但是当我更改代码以使用数据绑定时,出现此错误消息:

  • FragmentManager: No view found for id 0x7f0c0072 (mypackage:id/container) for fragment ContatosFormFragment2 [...]
  • FragmentManager: Activity state:
  • AndroidRuntime: FATAL EXCEPTION: main
  • java.lang.IllegalArgumentException: No view found for id 0x7f0c0072 (mypackage:id/container) for fragment ContatosFormFragment2 [...] '.

奇怪的是,如果我不包含 ContatosFormFragment1(所以我只有一个选项卡),ContatosFormFragment2 会起作用... 此外,如果我更改选项卡顺序,首先包括 ContatosFormFragment2,然后是 ContatosFormFragment1,则错误消息为 'No view found [...] for fragment ContatosFormFragment1'

注意:如果你能专注于主要问题,我会非常感激,我的意思是,不要担心变量名、封装、代码风格等。 .这是一个初始代码,将在工作中改进。

下面有数据绑定和没有数据绑定的代码:

我的Activity,数据绑定没有变化

public class ContatosFormActivity extends AppCompatActivity {
    public User contato;
    private SectionsPagerAdapter mSectionsPagerAdapter;
    private ViewPager mViewPager;
    TextView tNome, tTipo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_contatos_form);
    Utils.initToolbar(this,false);

    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    mViewPager = (ViewPager) findViewById(R.id.container);
    setupViewPager(mViewPager);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);
    Cursor cursor = (new DbController(getBaseContext())).carregaContatoById(getIntent().getIntExtra("contatoId", -1));
    contato = new User(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.NOME)));
    contato.setTipoPessoa(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.TIPO_PESSOA)));
}

private void setupViewPager(ViewPager viewPager) {
    SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new ContatosFormFragment1(), "Principal");
    adapter.addFragment(new ContatosFormFragment2(), "Histórico");
    viewPager.setAdapter(adapter);
}

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }
    /* constructor + getItem + getCount + getPageTitle ...*/
}}

没有数据绑定的代码

public class ContatosFormFragment1 extends Fragment{
    private EditText inputName;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);
        inputName = (EditText) view.findViewById(R.id.editText);
        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        inputName.setText(contatosFormActivity.contato.getNome());

        return view;
    }
}

public class ContatosFormFragment2 extends Fragment{
    private EditText inputName;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);
        inputTipoPessoa = (EditText) view.findViewById(R.id.tipo_pessoa);
        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        inputTipoPessoa.setText(contatosFormActivity.contato.getTipoPessoa());
        return view;
    }
}

fragment_contatos_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/input_layout_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editText"
                android:layout_gravity="center_horizontal"
                android:elegantTextHeight="false"
                android:hint="Nome"/>
        </android.support.design.widget.TextInputLayout>

</LinearLayout>

fragment_contatos_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/input_layout_tipoPessoa"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/tipo_pessoa"
                android:layout_gravity="center_horizontal"
                android:elegantTextHeight="false"
                android:hint="Tipo de Pessoa"/>
        </android.support.design.widget.TextInputLayout>

</LinearLayout>

带数据绑定的代码

public class ContatosFormFragment1 extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);

        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        FragmentContatosTab1Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab1);
        binding.setContato(contatosFormActivity.contato);

        return view;
    }
}

public class ContatosFormFragment2 extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);

        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        FragmentContatosTab2Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab2);
        binding.setContato(contatosFormActivity.contato);

        return view;
    }
}

fragment_contatos_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/input_layout_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editText"
                android:layout_gravity="center_horizontal"
                android:text="@{contato.nome}"
                android:elegantTextHeight="false"
                android:hint="Nome"/>
        </android.support.design.widget.TextInputLayout>

    </LinearLayout>
</layout>

fragment_contatos_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/input_layout_tipoPessoa"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/tipo_pessoa"
                android:layout_gravity="center_horizontal"
                android:text="@{contato.tipoPessoa}"
                android:elegantTextHeight="false"
                android:hint="Tipo de Pessoa"/>
        </android.support.design.widget.TextInputLayout>

    </LinearLayout>
</layout>

我解决了更改为:

public class ContatosFormFragment1 extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        FragmentContatosTab1Binding binding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_contatos_tab1, container, false);
        View view = binding.getRoot();
        binding.setContato(contatosFormActivity.contato);

        return view;
    }
}

public class ContatosFormFragment2 extends Fragment{

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
        FragmentContatosTab2Binding binding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_contatos_tab2, container, false);
        View view = binding.getRoot();
        binding.setContato(contatosFormActivity.contato);

        return view;
    }
}