19

मैं 2.x और 3.0 डिवाइस लक्ष्यीकरण एक एंड्रॉइड एप्लिकेशन विकसित कर रहा हूं और इस प्रकार मैं compatibilty API का उपयोग कर रहा हूं। मैं एंड्रॉइड 2.0 पर परीक्षण कर रहा हूं।टुकड़े और अभिविन्यास परिवर्तन को बदलना

मैं एक दूसरे के साथ एक प्रदर्शित टुकड़े को प्रतिस्थापित करने की कोशिश कर रहा हूं (खोज परिणामों के साथ खोज फ़ॉर्म) और दूसरा (परिणाम) खंड प्रदर्शित होने पर मुझे अभिविन्यास परिवर्तन पर एक क्रैश का सामना करना पड़ रहा है।

मूल रूप से, मैं एक गतिविधि है कि

<fragment class="org.prevoz.android.search.SearchFormFragment" 
       android:id = "@+id/search_form_fragment" 
       android:layout_width = "fill_parent" 
       android:layout_height = "fill_parent" /> 

पहले टुकड़ा (SearchFormFragment) एक डिफ़ॉल्ट के रूप में प्रदर्शित किया जाता है के रूप में एक टुकड़ा लेआउट एक्सएमएल में परिभाषित शामिल है। उपयोगकर्ता एक "खोज" बटन टैप करता है, मैं SearchResultsFragment है, जो एक AsyncTask चलाता है के साथ SearchFormFragment की जगह

// Show the search results fragment 
SearchResultsFragment newSearch = new SearchResultsFragment(from, to, when); 
newSearch.setRetainInstance(true); 

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); 
transaction.replace(R.id.search_form_fragment, newSearch);  
transaction.addToBackStack(null); 
transaction.commit(); 
हालांकि

, साथ जब SearchFormFragment प्रदर्शित किया जाता है और अभिविन्यास बदल गया है (यही कारण है कि मैं इसे बनाए रखना चाहते है), मेरी

ERROR/AndroidRuntime(334): FATAL EXCEPTION: main 
ERROR/AndroidRuntime(334): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.prevoz.android/org.prevoz.android.search.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.access$2400(ActivityThread.java:125) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) 
ERROR/AndroidRuntime(334):  at android.os.Handler.dispatchMessage(Handler.java:99) 
ERROR/AndroidRuntime(334):  at android.os.Looper.loop(Looper.java:123) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
ERROR/AndroidRuntime(334):  at java.lang.reflect.Method.invokeNative(Native Method) 
ERROR/AndroidRuntime(334):  at java.lang.reflect.Method.invoke(Method.java:521) 
ERROR/AndroidRuntime(334):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
ERROR/AndroidRuntime(334):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
ERROR/AndroidRuntime(334):  at dalvik.system.NativeStart.main(Native Method) 
ERROR/AndroidRuntime(334): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582) 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:407) 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
ERROR/AndroidRuntime(334):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198) 
ERROR/AndroidRuntime(334):  at android.app.Activity.setContentView(Activity.java:1647) 
ERROR/AndroidRuntime(334):  at org.prevoz.android.search.MainActivity.onCreate(MainActivity.java:40) 
ERROR/AndroidRuntime(334):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
ERROR/AndroidRuntime(334):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
ERROR/AndroidRuntime(334):  ... 12 more 
ERROR/AndroidRuntime(334): Caused by: java.lang.IllegalStateException: Fragment org.prevoz.android.search.SearchFormFragment did not create a view. 
ERROR/AndroidRuntime(334):  at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:281) 
ERROR/AndroidRuntime(334):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558) 
ERROR/AndroidRuntime(334):  ... 21 more 
WARN/ActivityManager(59): Force finishing activity org.prevoz.android/.search.MainActivity 

SearchFormFragment से प्रासंगिक onCreateView कोड के साथ अनुप्रयोग क्रैश कहा जाता हो जाता है और मैं एक मान्य दृश्य लौट:

@Override 
public View onCreateView(LayoutInflater inflater, 
         ViewGroup container, 
         Bundle savedInstanceState) 
{  
    View newView = inflater.inflate(R.layout.search_form_frag, container, false); 
    return newView; 
} 

क्रैश केवल तब होता है जब SearchResultsFragment दिखाया गया है, तो डिफ़ॉल्ट SearchFormFragment प्रदर्शित होने पर परिवर्तन ठीक काम करता है।

तो मैं अभिविन्यास परिवर्तन के माध्यम से दूसरा खंड राज्य कैसे बनाए रखूं? एपीआई और राज्य परिवर्तनों पर दस्तावेज वास्तव में कमी है।

उत्तर

28

XML में SearchFormFragment न बनाएं। इसके बजाय एक खाली FrameLayout है जिसे आप Activity.onCreate() में बैक स्टैक में जोड़ने के बिना पॉप्युलेट करते हैं। इस प्रकार Activity एक्सएमएल में निर्दिष्ट एक को जोड़ने की कोशिश करने के बजाय मौजूदा Fragment रखेगा।

इसके अलावा, AsyncLoader का उपयोग कर, एक बेहतर दृष्टिकोण हो सकता है http://code.google.com/p/android/issues/detail?id=14944

+0

मैंने अपनी समस्या को हल करने के लिए लोडर का उपयोग किया है, जो काम करता है। धन्यवाद। – Mavrik

+0

आपने मेरा दिन बनाया :) – Oli

4

देखने के कई घंटों के लिए इस के साथ संघर्ष कर के बाद, मैं अंत में यह मिल गया। समस्या सेटअप में नहीं है या जिस तरह से हम फ्रैगमेंट क्लास को कॉल करते हैं। इसे स्क्रीन पर प्रदर्शित होने वाले गलत संदेश के साथ करना है। यदि आपके पास अपने Ftagment क्लास में आपके ऑनक्रेट व्यू() में एक कंटेनर को शून्य करने की जांच है, तो आपको कंटेनर के बजाय "खंड को बढ़ाने में असमर्थ" संदेश मिलेगा, नल संदेश है। तो, अपने onCreateView() में शून्य कंटेनर की जांच न करें। तो सुनिश्चित करें कि आपके onCreateView (बनाने) इस तरह दिखता है:

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return(inflater.inflate(R.layout.title_layout, container, false)); 
    } 

और यह पसंद नहीं:

@Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     if(container == null){ 
      return null;         
     } 
     return(inflater.inflate(R.layout.title_layout, container, false)); 
    } 
+0

आपको 'onCreateView()' में दिए गए कंटेनर के साथ 'Inflator.inflate' का उपयोग नहीं करना चाहिए, माता-पिता को 'onCreateView()' के पूरा होने के बाद स्वचालित रूप से जोड़ा गया है। इसके बजाय आपको कंटेनर पैरामीटर के रूप में 'शून्य' गुजरना चाहिए। – Graeme

+0

यह counterintuitive है। तब 'कंटेनर' का बिंदु क्या है? – Cheezmeister

+0

@Graeme 'false' का अंतिम पैरामीटर का अर्थ है कि आप वास्तव में कंटेनर में फुले हुए दृश्य को संलग्न नहीं करते हैं, और कंटेनर पास हो जाता है ताकि सही' लेआउटपाम का उपयोग फुले हुए दृश्य के लिए किया जा सके। –

4

संदर्भ कारणों के लिए: हम अपने टुकड़ा करने के लिए एक android:id जोड़कर एक बहुत समान समस्या को हल करने में सक्षम थे एक्सएमएल में बनाया गया।

नोट::

दुर्घटना मुक्त रोटेशन समर्थन करने के लिए यह बहुत महत्वपूर्ण पूर्व शर्त केवल mentioned as a side-note in the documentation है प्रत्येक टुकड़ा एक अद्वितीय पहचानकर्ता है कि सिस्टम उपयोग टुकड़ा अगर गतिविधि पुनरारंभ बहाल करने के लिए कर सकते हैं की आवश्यकता है (और जो आप लेनदेन करने के लिए टुकड़े को पकड़ने के लिए उपयोग कर सकते हैं, जैसे इसे हटाएं)।

+0

यह एकमात्र सही जवाब है। – mkuech