2012-12-21 39 views
3

我正在開發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

它的例外如下面給出的,因爲這些片段的一個或多個被 被重用

是,異常來自充氣新的佈局,其具有以相同的id片段(最可能)作爲已經在佈局中的碎片。爲避免出現這種情況,您可以使用多種選項,例如:

您可以使用FragmentManager查找當前存在的片段,並在將片段用新片段膨脹之前從佈局中刪除它們。例如,如果您目前有隻是一個片段的佈局和要膨脹與兩個片段的佈局,那麼你會先刪除當前的片段兩種佈局:

getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.fragment1)).commit(); 
getSupportFragmentManager().executePendingTransactions(); 
mContainer.removeAllViews(); 
// inflate thew new layout 

但如果我在你情我不會使用它(主要是因爲你搞亂了靜態片段,你不應該這樣做)。現在,我不知道你將如何放置這些片段,但它會變得更有意義(並且可以在將來避免與其他片段相關的問題)具有容納佔位符容器的主佈局(簡單的FrameLayouts )(所有片段將在onCreate方法中創建,因此每次用戶更改佈局時都避免重新生成它們)。通過這種方式,您在運行時必須隱藏所需的碎片,並在必要時修改包裝容器的參數。如果活動將面臨配置破壞(如旋轉手機),那麼使用此功能,您還可以獲得免費片段管理(保持片段狀態也非常容易)。

+0

我首先要感謝@Luksporg指出片段的靜態性質。他的解決方案建議不適合我的應用程序。我對佈局的看法本質上是動態的,因此碎片不是要走的路。我將這些片段反映到解決我的問題的觀點上。但是,我現在的想法是希望返回到碎片並使用自定義佈局在各種顯示模式之間切換。 – Dobbo

+0

@Dobbo *我對佈局的看法本質上是動態的,因此碎片不是我們要走的路。* - 我認爲你誤解了「碎片」框架的目的。片段不僅僅是(或者)查看包裝器/容器。它們被引入作爲一個可重用的行爲單元,開發人員可以更好地處理它們。如果佈局具有動態性,那麼您可以使用片段,更不用說,與他們一起,您可以在平板電腦等大屏幕上提供更好的用戶體驗。 – Luksprog

+0

@Dobbo我做了一個隨機變化4個佈局的小樣本,這四個佈局中的每一個都包含4個碎片中的一部​​分。你可以在https://gist.github.com/4362865找到它。你也可以看看嵌套的片段。如果這沒有幫助,那麼也許我誤解了你的問題,我會刪除我的答案。 – Luksprog