错误膨胀类的片段 – 重复的id / illegalargumentexception?

我试图让一个应用程序,我正在build设从主要活动search条件,返回结果,然后结果是可点击的,使得可以从每个结果中查看一个细节。 我通过使用MainActivity,ResultsActivity和PlaceActivity,然后ListFragmentClickable(它扩展了ListFragment)来做到这一点。 如果手机以纵向模式进行导向,结果列表应该是可见的,只有单击结果才能查看详细信息。 如果手机是横向的,当select一个项目时,细节窗口应该popup到列表的右边。

在运行时,我得到一个错误,读取“错误膨胀类片段”。 我不知道是什么原因造成的,我乐意帮助摆脱它。

我的ListFragmentClickables被我的ResultsActivity调用,在这里:

public class ResultsActivity extends FragmentActivity implements ListFragmentClickable.OnItemSelectedListener{ private ArrayAdapter<String> mAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_results_view); //Receive searchTerm from MainActivity Intent intent = getIntent(); String searchTerm = intent.getStringExtra(MainActivity.SEARCH_TERM); mAdapter = new ArrayAdapter<String>(this, R.layout.item_label_list); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); FactualResponderFragment responder = (FactualResponderFragment) fm.findFragmentByTag("RESTResponder"); if (responder == null) { responder = new FactualResponderFragment(); ft.add(responder, "RESTResponder"); } Bundle bundle = new Bundle(); bundle.putString("search_term", searchTerm); responder.setArguments(bundle); ft.commit(); } public ArrayAdapter<String> getArrayAdapter() { return mAdapter; } @Override //creates a DetailFragment when a list item is selected public void onItemSelected(String link) { DetailFragment fragment = (DetailFragment) getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (fragment != null && fragment.isInLayout()) { fragment.setText(link); } else { Intent intent = new Intent(getApplicationContext(), PlaceActivity.class); intent.putExtra(PlaceActivity.EXTRA_URL, link); startActivity(intent); } } 

}

这里是ListFragmentClickable类:

 public class ListFragmentClickable extends ListFragment{ private OnItemSelectedListener listener; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_results_view, container, false); return view; } @Override public void onListItemClick(ListView l, View v, int position, long id) { updateDetail(); //see bottom } public interface OnItemSelectedListener { public void onItemSelected(String link); } @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof OnItemSelectedListener) { listener = (OnItemSelectedListener) activity; } else { throw new ClassCastException(activity.toString() + " must implemenet ListFragmentClickable.OnItemSelectedListener"); } } public void updateDetail() { // Create fake data String newTime = String.valueOf(System.currentTimeMillis()); // Send data to Activity listener.onItemSelected(newTime); //should direct PlaceActivity!! } } 

这是我的ResultsActivity(activity_results_activity.xml)的布局文件:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <fragment android:id="@+id/fragment_content" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" class="com.example.blobtag2.ListFragmentClickable" ></fragment> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="50dp" android:divider="#b5b5b5" android:dividerHeight="1dp"></ListView> </LinearLayout> 

最后这里是日志:

 03-21 22:32:03.297: E/AndroidRuntime(764): FATAL EXCEPTION: main 03-21 22:32:03.297: E/AndroidRuntime(764): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.blobtag2/com.example.blobtag2.ResultsActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class fragment 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread.access$600(ActivityThread.java:130) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.os.Handler.dispatchMessage(Handler.java:99) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.os.Looper.loop(Looper.java:137) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread.main(ActivityThread.java:4745) 03-21 22:32:03.297: E/AndroidRuntime(764): at java.lang.reflect.Method.invokeNative(Native Method) 03-21 22:32:03.297: E/AndroidRuntime(764): at java.lang.reflect.Method.invoke(Method.java:511) 03-21 22:32:03.297: E/AndroidRuntime(764): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 03-21 22:32:03.297: E/AndroidRuntime(764): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 03-21 22:32:03.297: E/AndroidRuntime(764): at dalvik.system.NativeStart.main(Native Method) 03-21 22:32:03.297: E/AndroidRuntime(764): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class fragment 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 03-21 22:32:03.297: E/AndroidRuntime(764): at com.example.blobtag2.ListFragmentClickable.onCreateView(ListFragmentClickable.java:32) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:846) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1061) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1160) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:272) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 03-21 22:32:03.297: E/AndroidRuntime(764): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.Activity.setContentView(Activity.java:1867) 03-21 22:32:03.297: E/AndroidRuntime(764): at com.example.blobtag2.ResultsActivity.onCreate(ResultsActivity.java:37) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.Activity.performCreate(Activity.java:5008) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 03-21 22:32:03.297: E/AndroidRuntime(764): ... 11 more 03-21 22:32:03.297: E/AndroidRuntime(764): Caused by: java.lang.IllegalArgumentException: Binary XML file line #7: Duplicate id 0x7f070003, tag null, or parent id 0x0 with another fragment for com.example.blobtag2.ListFragmentClickable 03-21 22:32:03.297: E/AndroidRuntime(764): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:277) 03-21 22:32:03.297: E/AndroidRuntime(764): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676) 03-21 22:32:03.297: E/AndroidRuntime(764): ... 30 more 

任何和所有的帮助是极大的,不胜感激。 请让我知道如果还有什么我可以添加?

Solutions Collecting From Web of "错误膨胀类的片段 – 重复的id / illegalargumentexception?"

问题是xml上的片段被加载了两次,第二次被join到FragmentManager中,你会得到一个IllegalArgumentException。 我昨天也遇到了同样的问题。

我的解决scheme,我改变它dynamic重新创build片段,而不是在XML文件中定义它:

改变这个XML文件的一部分:

 <fragment android:id="@+id/fragment_content" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" class="com.example.blobtag2.ListFragmentClickable" ></fragment> 

对此而言:

 <FrameLayout android:id="@+id/fragment_content" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:layout_marginTop="?android:attr/actionBarSize" /> 

然后在onCreate中,哟应该replaceFrameLayout一个新的片段:

 Fragment fragment = new ListFragmentClickable(); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.fragment_content, fragment); ft.commit(); 

然后你有相同的,但是,你不会得到一个重复的ID错误。

在以XML (静态) 定义片段时发生:如果父片段被破坏,则FragmentManager不pipe理子片段。 然后,当XML再次膨胀时,它会中断(“重复的id”错误)。

我绕过这个问题,在父代被销毁的时候手工去掉这个XML代码片段,在父代代码中使用这个代码:

 @Override public void onDestroyView() { FragmentManager fm = getFragmentManager(); Fragment xmlFragment = fm.findFragmentById(R.id.XML_FRAGMENT_ID); if (xmlFragment != null) { fm.beginTransaction().remove(xmlFragment).commit(); } super.onDestroyView(); } 

注意事项XML_FRAGMENT_ID是XML中片段的ID;)


而且,我更喜欢包装XML片段新类 。 它简单的代码,因为你只需要从它扩展你的片段类。 将这个类添加到您的项目中:

 package net.treboada.mytests.fragments; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.util.AttributeSet; public class XmlFragment extends Fragment { @Override public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) { FragmentManager fm = getFragmentManager(); if (fm != null) { fm.beginTransaction().remove(this).commit(); } super.onInflate(activity, attrs, savedInstanceState); } } 

然后,扩展你的XML片段类:

 package net.treboada.mytests.fragments; public class TestXmlFragment01 extends XmlFragment { // ... } 

瞧! 🙂

让我们试试这个。 我得到了同样的问题,我解决了我的问题,使用此代码。

  View root; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (root!= null) { ViewGroup parent = (ViewGroup) root.getParent(); if (parent != null) parent.removeView(root); } try { root= inflater.inflate(R.layout.map_layout, container, false); } catch (InflateException e) { /* map is already there, just return view as it is */ } return root; } 

如果您在这里阅读其他答案感觉他们似乎是正确的,看看这里https://stackoverflow.com/a/19815266/1139784因为它引用文档解释如何不支持(至less在我的情况下,这是很难从这个问题来看是否布局分片嵌套正在发生&#xFF09;

 Note: You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically. 

更多数据在这里,Android 4.0,4.1(<4.2)嵌套片段的最佳实践,而不使用支持库

编辑:另外,如果你正在考虑使用嵌套的片段,并不需要生命周期pipe理,你可以创build一个自定义的视图组(如扩展LinearLayout)。 http://www.vogella.com/tutorials/AndroidCustomViews/article.html

您可以从XmlFragment扩展您的片段(您在XML中加载)。 它处理父FragmentManager并删除自己。

 public class XmlFragment extends BaseFragment { @Override public void onDestroyView() { Fragment parentFragment = getParentFragment(); FragmentManager manager; if (parentFragment != null) { // If parent is another fragment, then this fragment is nested manager = parentFragment.getChildFragmentManager(); } else { // This fragment is placed into activity manager = getActivity().getSupportFragmentManager(); } manager.beginTransaction().remove(this).commitAllowingStateLoss(); super.onDestroyView(); } } 

这条线

 03-21 22:32:03.297: E/AndroidRuntime(764): Caused by: java.lang.IllegalArgumentException: Binary XML file line #7: Duplicate id 0x7f070003, tag null, or parent id 0x0 with another fragment for com.example.blobtag2.ListFragmentClickable 

特别是最后的部分

 Duplicate id 0x7f070003, tag null, or parent id 0x0 with another fragment for com.example.blobtag2.ListFragmentClickable 

告诉你,在你的活动的一生中的某个时刻,你正试图创buildListFragmentClickable的视图,当已经存在的时候。 你需要弄清楚这是如何发生的。