5

içine böyle hiyerarşi sahip bir uygulama var.Android FragmentTab konak ve fragmanlar Fragments

Uygulama her şey başladığında görünür ve iyi görünüyor. İlk sekmeden başka bir sekmeye ve tekrar geri döndüğümde, sekme 1'in görünümlerini yeniden oluşturmaya çalışırken istisnalar açarım. İlk Yüklemede

  • şişirme ayırıcı görünümü iki çocuk fragmanları parçası yöneticisi eklenecek neden olur:

    biraz daha derin kazmak, bu şey bu.

  • ilk sekmeden uzağa geçiş Açık
  • , bu görünüm yok edilir ama o çocuk fragmanları, görünüm şişirilmiş yeniden ilk sekmesine tekrar geçtikten On parçası yöneticisi
  • bırakılan ve edilir var eski çocuk fragmanları hala beri yeni alt fragmanları

(Ben Mono kullanıyorum) parçası yöneticisinden çocuk parçalarını kaldırarak bunu çalıştık ve şimdi (enflasyondan) örneklenen zaman parçası yöneticisinde bir istisna atılır ben istisnasız sekmeleri değiştirebilir.

  1. doğru şekilde yukarıda bunu mi:
    public override void OnDestroyView() 
    { 
        var ft = FragmentManager.BeginTransaction(); 
        ft.Remove(FragmentManager.FindFragmentById(Resource.Id.ListFragment)); 
        ft.Remove(FragmentManager.FindFragmentById(Resource.Id.ContentFragment)); 
        ft.Commit(); 
    
        base.OnDestroyView(); 
    } 
    

    Bu yüzden bir kaç soru var?
  2. Değilse, nasıl yapmalıyım?
  3. Her iki durumda da, kaydetme durumu durumu tüm bunlar için nasıl bağlanır, böylece sekmeleri değiştirirken görünüm durumunu kaybetmemeliyim?

cevap

2

Mono bunu yapmak, ama başka bir parçasına çocuk parçalarını nasıl ekleneceğini değil eminim, sen Activity ait FragmentManager kullanamaz. Bunun yerine, barındırma Fragment ait ChildFragmentManager kullanmak zorunda: Activity ait

http://developer.android.com/reference/android/app/Fragment.html#getChildFragmentManager() http://developer.android.com/reference/android/support/v4/app/Fragment.html#getChildFragmentManager()

ana FragmentManager sekmelerinizi işler.
tab1'un ChildFragmentManager'u, bölünmüş görünümleri işler.

+0

Tamam, bu umut verici görünüyor. Enflavana, ebeveyn bölüm yerine çocuk parça yöneticisi kullanmasını nasıl söyleyebilirim? –

+0

Alt parçanın içindeki alt parçayı, alt parçanın kodunu ChildFragmentManager'ı kullanarak çocuklarını eklemek için eklersiniz. Sonra (çocuk) parçanızın onCreateView geri çağırma yöntemini sağlayan aşağıdakileri sağlar: https://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle). –

+0

Mono'da çocuk parçalarıyla nasıl başa çıkılacağını görmek için muhtemelen daha fazla googling/stackoverding yapmalısınız. Sana yardım edemem (Java kullanıyorum). –

2

Tamam, sonunda bu anladım: Yukarıda önerildiği gibi, birinci şöyle, programlama yoluyla yapılacak parça oluşturulmasını değiştirdi ve onları çocuk fragmanı yöneticisine katmıştı

:

public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance) 
{ 
    var view = inflater.Inflate(Resource.Layout.MyView, viewGroup, false); 

    // Add fragments to the child fragment manager 
    // DONT DO THIS, SEE BELOW 
    var tx = ChildFragmentManager.BeginTransaction(); 
    tx.Add(Resource.Id.lhs_fragment_frame, new LhsFragment()); 
    tx.Add(Resource.Id.rhs_fragment_frame, new RhsFragment()); 
    tx.Commit(); 

    return view; 
} 

Beklendiği gibi, sekmeleri her değiştirdiğimde, fazladan bir LHS/RhsFragment örneği oluşturulacaktı, ancak eski LHS/RhsFragment'in OnCreateView öğesinin de çağrılacağını fark ettim. Böylece her sekme anahtarından sonra, OnCreateView'a bir tane daha çağrı yapılacaktı. Sekmeleri 10 kez değiştirin = OnCreateView'a 11 çağrı. Bu açıkça yanlıştır.

FragmentTabHost için kaynak koduna bakıldığında, sekmeleri değiştirirken sekmenin içerik parçasını basitçe ayırdığını ve yeniden eklediğini görebiliyorum. Ebeveyn Fragmanının ChildFragmentManager'ı, ebeveyn fragmanları yeniden eklendiğinde çocuk parçalarını etrafında tutuyor ve otomatik olarak kendi görüşlerini yeniden yaratıyor gibi görünüyor.

Yani, OnCreate için parçaların oluşturulmasını taşındı ve biz kaydedilen durumdan yüklenmemesi konum yalnızca:

public override void OnCreate(Bundle savedInstanceState) 
{ 
    base.OnCreate(savedInstanceState); 

    if (savedInstanceState == null) 
    { 
     var tx = ChildFragmentManager.BeginTransaction(); 
     tx.Add(Resource.Id.lhs_fragment_frame, new LhsFragment()); 
     tx.Add(Resource.Id.rhs_fragment_frame, new RhsFragment()); 
     tx.Commit(); 
    } 
} 


public override View OnCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstance) 
{ 
    // Don't instatiate child fragments here 

    return inflater.Inflate(Resource.Layout.MyView, viewGroup, false); 
} 

Bu ek görüşlerin oluşturulmasını sabit ve anahtarlama sekmesi temelde şimdi çalıştı.

Bir sonraki soru, görüntü durumunu kaydetme ve geri yükleme idi. Çocuk parçalarında o anda seçili olan öğeyi kaydetmem ve geri yüklemem gerekiyor. Başlangıçta bu sorun sekmeleri geçiş yaparken sekme konak OnSaveInstanceState çağrı olmamasıdır (bu çocuk veridiliminin OnCreateView olan)

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) 
{ 
    var view = inflater.Inflate(Resource.Layout.CentresList, container, false); 

    // ... other code ommitted ... 

    // DONT DO THIS, SEE BELOW 
    if (savedInstance != null) 
    { 
     // Restore selection 
     _selection = savedInstance.GetString(KEY_SELECTION); 
    } 
    else 
    { 
     // Select first item 
     _selection =_items[0]; 
    } 

    return view; 
} 

böyle bir şey vardı. Daha ziyade çocuk parçası canlı tutulur ve _selection değişkeni sadece yalnız bırakılabilir.

Yani OnCreate seçimi yönetmek için kod taşındı:
public override void OnCreate(Bundle savedInstance) 
{ 
    base.OnCreate(savedInstance); 

    if (savedInstance != null) 
    { 
     // Restore Selection 
     _selection = savedInstance.GetString(BK_SELECTION); 
    } 
    else 
    { 
     // Select first item 
     _selection = _items[0]; 
    } 
} 

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) 
{ 
    // Don't restore/init _selection here 

    return inflater.Inflate(Resource.Layout.CentresList, container, false); 
} 

Şimdi tüm sekmeleri anahtarlama ve Yön değişikliğiyle hem mükemmel çalışıyor gibi görünüyor.

İlgili konular