19

2.x ve 3.0 aygıtları hedefleyen bir Android uygulaması geliştiriyorum ve bu nedenle uyumlu API'yi kullanıyorum. Android 2.0'da test ediyorum.Parçaları değiştirme ve yön değiştirme

Görüntülenen bir parçayı başka biriyle değiştirmeye çalışıyorum (arama sonuçlarıyla arama formu) ve ikinci (sonuç) fragmanı görüntülendiğinde yön değiştirme durumunda bir çöküş yaşıyorum.

Temelde,

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

birinci parçası (SearchFormFragment) bir varsayılan olarak görüntülenen şekilde düzeni XML tanımlanan bir fragmanını içeren bir aktiviteye sahiptir. SearchFormFragment görüntülenir ve oryantasyon değiştirildiğinde Ancak

// 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(); 

, kullanıcı bir "arama" tuşuna hafifçe dokunduğunda, bir AsyncTask çalışır SearchResultsFragment ile SearchFormFragment değiştirin (bunu korumak istiyorum bu yüzden), benim

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 alakalı onCreateView kodu ile uygulama çöker denilen olsun ve seni bir geçerli görünümü döndürür:

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

Kilitlenme yalnızca SearchResultsFragment görüntülendiğinde gerçekleşir, varsayılan SearchFormFragment görüntülendiğinde değişiklik düzgün çalışır.

Yönlendirme değişikliği aracılığıyla ikinci parça durumunu nasıl koruyabilirim? API ve durum değişiklikleri ile ilgili belgeler gerçekten eksiktir.

cevap

28

XML'de SearchFormFragment'u oluşturmayın. Bunun yerine boş bir FrameLayout boşluğuna sahip olursunuz, Activity.onCreate() içinde biriktirerek arka yığına eklemezsiniz. Bu şekilde, Activity, XML'de belirtilen birini eklemeyi denemek yerine geçerli Fragment'u koruyacaktır.

Ayrıca AsyncLoader kullanarak, daha iyi bir yaklaşım olabilir saatlerce bununla mücadele sonrasında http://code.google.com/p/android/issues/detail?id=14944

+0

Çalıştığım sorunu çözmek için yükleyicileri kullandım. Teşekkürler. – Mavrik

+0

Günümü benim yaptın :) – Oli

4

görebilirsiniz, nihayet aldım. Sorun, kurulumda veya Fragment sınıfını çağırdığımız şekilde değil. Ekranda görüntülenen yanlış bir mesajla ilgisi var. Ftagment sınıfınızda onCreateView() öğenizde boş olan bir kapsayıcıya ilişkin bir kontrole sahipseniz, kapsayıcıda boş bir ileti yerine "parçayı şişiremez" iletisini alırsınız. Yani, onCreateView() öğenizdeki boş kapsayıcıyı denetlemeyin.

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

ve bu gibi DEĞİL: Yani) emin onCreateView (yapmak şuna benzer referans nedenlerden dolayı

@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

'Infinder.inflate 'öğesini onCreateView()' da verilen kapsayıcıyla birlikte kullanmamalısınız, üst öğe, onCreateView() 'ın tamamlanmasından sonra otomatik olarak eklenir. Bunun yerine konteyner parametresi olarak 'null'ı geçerek şişirmelisiniz. – Graeme

+0

Bu, mantıksız. O zaman konteynerin amacı nedir? – Cheezmeister

+0

@Graeme, false'nin son parametresi, şişirilmiş görünümü gerçekten kapsayıcıya eklemediğiniz anlamına gelir ve kapsayıcı, geçirilen görünüm için sağ LayoutParam işlevi kullanıldığında iletilir. –

4

: Bizim fragmanına bir android:id ekleyerek çok benzer bir sorunu çözmek için başardık XML'de oluşturuldu.

Not:

çarpışma serbest dönüşünü desteklemek için bu çok önemli önkoşulu sadece mentioned as a side-note in the documentation olan her parçası sistemi kullanım etkinliği yeniden başlatılırsa fragman geri benzersiz bir tanımlayıcı gerektirir (ve hangi , gibi işlemleri gerçekleştirmek için parçayı yakalamak için kullanabilirsiniz.

+0

Bu sadece doğru cevap. – mkuech