我正在开发colour wheel app以获得乐趣。版本0.5具有由四个片段组成的调色板,一个用于色轮上的每个可能的颜色目标。然后根据色轮的模式隐藏或显示片段的UI元素。 “单色”模式只需要其中一个片段,其中“Accented Anaogic”需要全部四个片段。这可以找到,因为片段是作为onCreate()
方法的一部分构建和显示的,之后永远不会被触及。
对于改进布局的下一个版本,我设计了四个“包含”XML布局文件,一个只使用一个片段实例,一个使用两个,依此类推。主XML布局文件现在有FrameLayout
作为更改模式时替换相应“包含”XML布局文件的点。
以下是执行更改的代码片段:
private void changeLayout(int layoutID) {
FragmentManager fMgr = getFragmentManager();
FragmentTransaction transaction = fMgr.beginTransaction();
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
FrameLayout frame = (FrameLayout) findViewById(R.id.paletteContainer);
frame.removeAllViews();
View view = inflater.inflate(layoutID, frame, false);
frame.addView(view);
transaction.commit();
pFrag = (SwatchFragment.Primary) fMgr.findFragmentById(R.id.base);
a1Frag = (SwatchFragment.FirstAlternate) fMgr.findFragmentById(R.id.alternate1);
a2Frag = (SwatchFragment.SecondAlternate) fMgr.findFragmentById(R.id.alternate2);
cFrag = (SwatchFragment.Complementary) fMgr.findFragmentById(R.id.complementary);
}
下面给出了例外,因为一个或多个片段正在被重用。那么替换包含片段的部分UI的正确方法是什么?
E/WheelActivityandroid.view.InflateException: Binary XML file line #11: Error inflating class Navigation item selected: pos=1, id=0x00000001
android.view.InflateException: Binary XML file line #11: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) ~[na:0.0]
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) ~[na:0.0]
at android.view.LayoutInflater.inflate(LayoutInflater.java:489) ~[na:0.0]
at android.view.LayoutInflater.inflate(LayoutInflater.java:396) ~[na:0.0]
at org.dobbo.colour.activity.WheelActivity.changeLayout(WheelActivity.java:321) ~[na:0.0]
at org.dobbo.colour.activity.WheelActivity.setMode(WheelActivity.java:307) ~[na:0.0]
at org.dobbo.colour.activity.WheelActivity.onNavigationItemSelected(WheelActivity.java:181) ~[na:0.0]
at com.android.internal.widget.ActionBarView$1.onItemSelected(ActionBarView.java:148) ~[na:0.0]
at android.widget.AdapterView.fireOnSelected(AdapterView.java:892) ~[na:0.0]
at android.widget.AdapterView.access$200(AdapterView.java:49) ~[na:0.0]
at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:860) ~[na:0.0]
at android.os.Handler.handleCallback(Handler.java:725) ~[na:0.0]
at android.os.Handler.dispatchMessage(Handler.java:92) ~[na:0.0]
at android.os.Looper.loop(Looper.java:137) ~[na:0.0]
at android.app.ActivityThread.main(ActivityThread.java:5039) ~[na:0.0]
at java.lang.reflect.Method.invokeNative(Native Method) ~[na:0.0]
at java.lang.reflect.Method.invoke(Method.java:511) ~[na:0.0]
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) ~[na:0.0]
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) ~[na:0.0]
at dalvik.system.NativeStart.main(Native Method) ~[na:0.0]
Caused by: java.lang.IllegalArgumentException: Binary XML file line #11: Duplicate id 0x7f0a000b, tag null, or parent id 0x7f0a0010 with anoth
er fragment for org.dobbo.colour.fragment.SwatchFragment$Primary
at android.app.Activity.onCreateView(Activity.java:4722) ~[na:0.0]
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680) ~[na:0.0]
...
答案 0 :(得分:0)
下面给出了例外,因为一个或多个片段是 被重用
是的,异常来自于新布局的膨胀,该布局具有相同ID(最有可能)的片段作为已在布局中的片段。为避免这种情况,您有几个选项,例如:
您可以使用FragmentManager
查找当前存在的片段,并在使用片段对新布局进行充气之前将其从布局中删除。例如,如果您当前只有一个片段的布局,并且您想要使用两个片段来扩充布局,那么您将首先删除两个布局中存在的片段:
getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.fragment1)).commit();
getSupportFragmentManager().executePendingTransactions();
mContainer.removeAllViews();
// inflate thew new layout
但如果我在你的情况下我不会使用它(主要是因为你搞乱了静态碎片,你不应该这样做)。现在,我不知道你将如何放置这些片段,但它会更有意义(并且可以避免将来与其他片段相关的问题),以便拥有一个可以容纳占位符容器的主布局(简单{ {1}})对于每个片段(所有片段都将在FrameLayouts
方法中创建,因此每次用户更改布局时都要避免重新安排它们)。这样,您在运行时所需要做的就是隐藏所需的片段,并在必要时修改包装器容器的参数。如果活动将面临配置破坏(例如旋转手机时),您还可以获得免费的片段管理(维护片段状态也很容易)。