2011-09-28 17 views
8

मैं टैबलेट के लिए एंड्रॉइड ऐप विकसित कर रहा हूं और संगतता लाइब्रेरी का उपयोग कर नहीं कर रहा हूं।IllegalArgumentException: तेजी से स्विचिंग के दौरान आईडी के लिए कोई दृश्य नहीं मिला एक्शनबार टैब

केवल एक गतिविधि है और यह 3 टैब के साथ एक्शनबार का उपयोग करती है। टैबलिस्टर में मैं उस टैब के विशिष्ट लेआउट को लोड करने के लिए setContentView का उपयोग करता हूं, और उसके बाद प्रासंगिक फ्रेम को उनके फ्रेम में जोड़ता हूं। यह लगभग ठीक वैसे ही काम करता है जैसा मैं चाहता हूं, सिवाय इसके कि जब आप टैब के बीच स्विच करते हैं तो ऐप क्रैश हो जाएगा।

मैं अपने डीबगिंग डिवाइस के रूप में सैमसंग गैलेक्सी टैब का उपयोग कर रहा हूं और स्विचिंग टैब वास्तव में तेज़ है। एक सामान्य गति से मैं उनके बीच आगे और पीछे टैप कर सकता हूं और पृष्ठों को तुरंत लोड किया जाता है। समस्या यह है कि जब मैं टैब के बीच हाइपर स्विच करता हूं।

सबसे पहले मैं एक

IllegalStateException: Fragment not added 

के रूप में यहाँ देखा है: http://code.google.com/p/android/issues/detail?id=17029 onTabUnselected में कोशिश/पकड़ ब्लॉक का उपयोग करने सुझाव के बाद, मैं इस मुद्दे के लिए एप्लिकेशन एक छोटे से अधिक मजबूत है, लेकिन वह नेतृत्व बनाया हाथ में:

IllegalArgumentException: No view found for id 0x... for fragment ... 

मैं किसी और को एक ही मुद्दा होने के वेब पर किसी भी अन्य मामले नहीं मिला है, तो मैं चिंतित है कि मैं कुछ ऐसा है जो समर्थित नहीं है कर किया जा सकता है कर रहा हूँ। फिर से, जो मैं करने की कोशिश कर रहा हूं वह एक गतिविधि में 3 अलग-अलग लेआउट का उपयोग करता है - जब आप किसी टैब पर क्लिक करते हैं, तो श्रोता लेआउट बदलने के लिए setContentView को कॉल करेगा, और फिर टुकड़े जोड़ें। यह तब तक खूबसूरती से काम करता है जब तक कि आप टैब के बीच आक्रामक रूप से स्विचिंग शुरू नहीं करते।

मुझे इसके लिए विचार मिला: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html और टैबलिस्टर के बजाय एक टुकड़े के संदर्भ में, मेरे पास एक सरणी है। साथ ही, मैं संलग्नक/डिटेच का उपयोग नहीं कर रहा हूं क्योंकि उनको एपीआई 13 में जोड़ा गया था।

मेरा सिद्धांत यह है कि या तो सेटकंटेंट व्यू ने विचारों को तैयार नहीं किया है, और यही वजह है कि फ्रैगमेंट ट्रांज़ेक्शन उन्हें जोड़ नहीं सकता है, या टुकड़े हैं एक टैब के लिए जोड़ा जा रहा है जब एक और टैब चुना जाता है और सेटकंटेंट व्यू को अन्य दृश्यों के सेट को नष्ट कर दिया जाता है।

मैंने टैब स्विचिंग को धीमा करने के लिए कुछ हैक करने की कोशिश की लेकिन कहीं भी नहीं मिला।

यहाँ मेरी TabListener के लिए कोड है:

private class BTabListener<T extends Fragment> implements ActionBar.TabListener{ 

    private int mLayout; 
    private Fragment[] mFrags; 
    private TabData mTabData; 
    private Activity mAct; 
    private boolean mNoNewFrags; 


    public BTabListener(Activity act, int layout, TabData td, boolean frags){ 
     mLayout = layout; 
     mTabData = td; 
     mAct = act; 
     mNoNewFrags = frags; 

     mFrags = new Fragment[mTabData.fragTags.length]; 
     for(int i=0; i<mFrags.length; i++){ 
      //on an orientation change, this will find the fragments that were recreated by the system 
      mFrags[i] = mAct.getFragmentManager().findFragmentByTag(mTabData.fragTags[i]); 
     } 

    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 

    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     //this gets called _after_ unselected 
     //note: unselected wont have been called after an orientation change! 
     //we also need to watch out because tab 0 always gets selected when adding the tabs 

     //set the view for this tab 
     mAct.setContentView(mLayout); 

     for(int i=0; i<mFrags.length; i++){ 
      //this will be null when the tab is first selected 
      if(mFrags[i]==null){ 
       mFrags[i] = Fragment.instantiate(GUITablet.this, mTabData.classes[i].getName());      
      } 

      //if there was an orientation change when we were on this page, the fragment is already added 
      if(!mNoNewFrags || mDefaultTab!=tab.getPosition()){ 
       ft.add(mTabData.containterIDs[i], mFrags[i], mTabData.fragTags[i]); 
      } 
     } 
     mNoNewFrags = false; 


    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     // this gets called when another tab is selected, before it's onSelected method 

     for(Fragment f : mFrags){ 
      try{ //extra safety measure 
       ft.remove(f); 
      }catch(Exception e){ 
       e.printStackTrace(); 
       System.out.println("unselect couldnt remove"); 
      } 
     } 
    } 

} 

और अंत में, स्टैक ट्रेस: ​​

09-29 01:53:08.200: ERROR/AndroidRuntime(4611): java.lang.IllegalArgumentException: No view found for id 0x7f0b0078 for fragment Fraggle{40ab2230 #2 id=0x7f0b0078 dummy2} 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:729) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:926) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.BackStackRecord.run(BackStackRecord.java:578) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1226) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.FragmentManagerImpl$1.run(FragmentManager.java:374) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.os.Handler.handleCallback(Handler.java:587) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.os.Handler.dispatchMessage(Handler.java:92) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.os.Looper.loop(Looper.java:132) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at android.app.ActivityThread.main(ActivityThread.java:4028) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at java.lang.reflect.Method.invoke(Method.java:491) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) 
09-29 01:53:08.200: ERROR/AndroidRuntime(4611):  at dalvik.system.NativeStart.main(Native Method) 

धन्यवाद !!

+0

दुर्घटनाग्रस्त होने से रोका किसी भी एक मदद कर सकता हूँ मेरे इस त्रुटि से छुटकारा पाने .... [कड़ी] था [1] [1]: http://stackoverflow.com/questions/2540 0641/fragmentmanager-illegalargumentexception-no-view-found-for-frag-for-fragment? Noredirect = 1 –

+0

@SamKazmi, क्या आपने सुझाए गए उत्तरों का प्रयास किया है ...? – hooby3dfx

उत्तर

5

ठीक है, यह चारों ओर एक रास्ता मिल गया:

लेआउट फाइलों में टुकड़े के लिए संदर्भ रखो, और एक आज़माएं/कैच ब्लॉक में onTabSelected में setContentView कॉल को घेर लिया।

अपवाद हैंडलिंग ने इसका ख्याल रखा!

+0

क्या आप बस एक खाली स्क्रीन के साथ खत्म नहीं करते हैं? – CACuzcatlan

+0

मैं एक खाली स्क्रीन के साथ क्यों समाप्त होगा? मुझे लगता है कि त्रुटियां केवल तब होती हैं जब किसी भी चयन के दौरान अचयनित या चयनित में तेजी से स्विचिंग होती है, इसलिए अंतिम चयन हमेशा काम करेगा (कोई अपवाद नहीं)। – hooby3dfx

1

मुझे पता है कि यह थोड़ा पुराना सवाल है, लेकिन मैं वही था और आसपास एक अलग काम ढूंढ रहा था।

विधि ही यहाँ Avoid recreating same view when perform tab switching

लेकिन इस विशिष्ट दुर्घटना के संदर्भ पर वर्णन किया गया है शो कर रही है,/जोड़ने के बजाय छुपाएं/बदलें टुकड़ा पर onCreateView करने के लिए कई तेजी से कॉल बचा जाता है।

मेरे अंतिम कोड कुछ इस तरह समाप्त हो गया:

@Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
if (fragments[tab.getPosition()] == null) { 
    switch(tag.getPosition()){ 
     case 0: fragments[tab.getPosition()] = new // fragment for this position 
     break; 
     // repeat for all the tabs, for each `case` 
    } 
    fragmentTransaction.add(R.id.container, fragments[tab.getPosition()]); 
}else{ 
    fragmentTransaction.show(fragments[tab.getPosition()]); 
} 
} 

@Override 
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { 
if (fragments[tab.getPosition()] != null) 
    fragmentTransaction.hide(fragments[tab.getPosition()]); 
} 
0

एक Google Play क्रैश रिपोर्ट में एक ऐसी ही मामले को देख कर।

java.lang.IllegalStateException: 
    Fragment not added: MessageDisplayFragment{406e28f0 #2 id=0x7f0b0020} 
at android.app.BackStackRecord.hide(BackStackRecord.java:397) 
at org.kman.AquaMail.ui.AccountListActivity$UIMediator_API11_TwoPane. 
    closeMessageDisplay(AccountListActivity.java:2585) 

प्रासंगिक कोड:

AbsMessageFragment fragDisplay = (AbsMessageFragment) 
    mFM.findFragmentById(R.id.fragment_id_message_display); 

if (fragDisplay != null) { 
    FragmentTransaction ft = mFM.beginTransaction(); 
    ft.setTransition(FragmentTransaction.TRANSIT_NONE); 
    ft.show(some other fragment); 
    ft.hide(fragDisplay); 

^^ यह वह जगह है जहां यह

दुर्घटनाओं टुकड़ा निश्चित रूप से वहाँ (यह findFragmentById द्वारा दिया गया था) है, लेकिन छिपाने बुला() के साथ विस्फोट से उड़ा दिया "अवैध स्तर अपवाद: टुकड़ा जोड़ा नहीं गया"

नहीं जोड़ा गया? अगर फ्रेगमेंट बीआईआईडी इसे ढूंढने में सक्षम था तो इसे कैसे जोड़ा नहीं जा सकता है?

सभी FragmentManager कॉल UI थ्रेड से किए जा रहे हैं।

टुकड़ा हटाया जा रहा है (fragDisplay) पहले जोड़ा गया था और मुझे यकीन है कि इसकी फ्रैगमेंट ट्रांज़ेक्शन का काम किया गया था।

0

इसे मेरे टुकड़ों के माध्यम से लूप करके फिक्स्ड किया गया है, उनमें से किसी को भी हटा दिया गया है और फिर नया जोड़ना है। यह भी पहले जांचें कि आप इसे शून्य या मौजूदा खंड के साथ बदलने की कोशिश नहीं कर रहे हैं।

संपादित करें: लगता है कि यह सिर्फ

getChildFragmentManager().executePendingTransactions(); 

कि यह

private void replaceCurrentTabFragment(TabFragment tabFragment){ 

    if (tabFragment == null){ return; } 

    if (tabFragment == getActiveTabFragment()){ return; } 

    FragmentTransaction ft = getChildFragmentManager().beginTransaction(); 

    for (TabFragment fragment : mTabButtons.values()){ 
     if (((Fragment)fragment).isAdded()){ 
      ft.remove((Fragment)fragment); 
     } 
    } 

    ft.add(R.id.fragment_frameLayout, (Fragment) tabFragment); 
    ft.commit(); 
    getChildFragmentManager().executePendingTransactions(); 

} 

private TabFragment getActiveTabFragment(){ 
    return (TabFragment) getChildFragmentManager().findFragmentById(R.id.fragment_frameLayout); 
} 
संबंधित मुद्दे