Parça değiştirilmiyor ama öncekinin üzerine yerleştiriliyor


105

Aktivite:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();

transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();

FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();

Görünümdeki kod:

<fragment
    android:id="@+id/Fragment1"
    android:name="com.landa.fragment.Fragment1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/include1" /> 

Sorun şu ki, içerik gerçekten değiştirilmiyor - üste konuluyor (bu yüzden üst üste biniyor).

Geri tıkladığımda, ilk parça düzgün bir şekilde gösteriliyor (ikincisi olmadan), ancak başlangıçta her ikisi de görünüyor (sadece sonuncunun görünmesini istiyorum).

Burada neyi özlüyorum?


Benim durumumda sorun, konteyner görünümünün uygun kimliğini kullanmadığım, yani doğru containerViewId( replaceyöntemde) geçemediğim gerçeğinden kaynaklanıyordu .
nbro

Yanıtlar:


145

Burada iki şeyi yanlış yapıyorsunuz:

  1. Bir xmldüzen dosyasına statik olarak yerleştirilmiş bir parçayı değiştiremezsiniz . Düzende bir kap (örneğin a FrameLayout) oluşturmalı ve ardından parçayı kullanarak programlı olarak eklemelisiniz FragmentTransaction.

  2. FragmentTransaction.replacebirinci parametre olarak parçanın kimliğini değil, parçayı içeren kabın kimliğini bekler. Bu nedenle, ilk bağımsız değişkeni, ilk parçayı eklediğiniz kabın kimliği olarak iletmelisiniz.

Daha fazla ayrıntı için bu bağlantıya başvurabilirsiniz .


17
FrameLayoutKap olarak kullanmak , kullanmaktan daha iyidir LinearLayout.
Marcel Bro

3
Activity'de boş bir FrameLayout kullanmak benim de sorunumu çözdü
Subtle Fox

1
Bunu yaparak çalışıyor. Ama sonra uygulamamı başlatıp hemen geri düğmesine bastığımda, uygulamadan çıkmak yerine parçanın boş olduğu bir duruma geliyorum?
MasterScrat

@MasterScrat addTobackStack(..)İşleminizi ilk kez yaparken atlayın . Bu, boş FrameLayout kabını arka yığına yerleştirmekten kaçınacaktır. Yine de eklediğiniz parçaya geri dönebileceksiniz.
Alex Meuer

İşte açıklamanızı gösteren harika bir video. youtube.com/watch?v=EbcdMxAIr54
SQL ve Java Öğrenicisi

32

Benzer bir sorun yaşadım ama sorunum iki farklı Fragment yöneticisi kullanmamdı: Biri gönderen getSupportFragmentManager()diğeri kimden getFragmentManager(). İle bir parça ekledikten SupportFragmentManagersonra parçayı ile değiştirmeyi denersem, parça FragmentManagersadece üste eklenirdi. Kodu değiştirmem gerekiyordu, böylece aynısı FragmentManagerkullanılacaktı ve bu sorunla ilgileniyordu.


17

Android geliştirici sitesi, FrameLayoutparçaları çalışma zamanında dinamik olarak yüklemek için a kullanımını önerir . Xml dosyanızdaki parçayı sabit kodladınız. Bu nedenle, bu bağlantıda belirtildiği gibi çalışma zamanında kaldırılamaz:

http://developer.android.com/training/basics/fragments/creating.html

bu bağlantı, programınız aracılığıyla nasıl parça ekleneceğini gösterir:

http://developer.android.com/training/basics/fragments/fragment-ui.html


7

Aynı sorunu yaşadım ve tüm cevapları gördüm, ama hiçbiri hatamı içermiyordu! Mevcut parçayı değiştirmeye çalışmadan önce, konteyner etkinliğinin xml'sindeki varsayılan parçayı şu şekilde gösteriyordum:

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="....ShopFragment"
        android:id="@+id/fragment"
        tools:layout="@layout/fragment_shop" />
</FrameLayout>

bundan sonra ben geçiyordu rağmen FrameLayouthiç fragmentTransaction.replace()ama tam sorunu vardı. bir öncekinin üstünde ikinci parçayı gösteriyordu.

Sorun, parçanın xml'den kaldırılması onCreate()ve programın başlangıcında varsayılan önizleme için kapsayıcı etkinliği yönteminde programlı olarak gösterilmesiyle çözüldü :

    fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment());
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

ve kapsayıcı etkinliği xml:

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

4

Parçaları değiştirmeden önce backStack'i temizleyebilirsiniz:

    FragmentManager fm = getActivity().getSupportFragmentManager();

    for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
        fm.popBackStack();
    }

    // replace your fragments

sorun, parçayı kendi xml düzen dosyasında bildirmiş olmasıdır. Bu nedenle çalışma zamanında kaldırılamaz / değiştirilemez.
Poonam Anthony

bu benim için işe yaradı, arka yığını temizlemeden bir parçayı değiştirmeye çalışmak, en son arka istif girişini başka herhangi bir parçanın üstünde bırakıyor gibiydi.
speedynomads

3
<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:windowBackground">
//Add fragment here
</FrameLayout>

android:background="?android:windowBackground">Parçanızın bulunduğu kaba ekleyin . Benim durumumda bir ekledim FrameLayout, bu yardımcı olmalı.


1

Parça kullanmak yerine bir kap kullanın

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hello World!" />

Şimdi MainActivity'de

if(condition)
    getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();                    
else
    getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();

Lütfen parça sınıfınızın 'android.app.Fragment' dosyasını içe aktarması gerektiğini unutmayın. "Support.v4" veya "orijinal" uygulamaları kullandığınızdan ve bunları karıştırmadığınızdan emin olun. Bu sorunu alıyordum çünkü onları karıştırmıştım.


0

Sapan Diwakar'ın cevabına katılıyorum. Ancak bunun nasıl yapılacağına dair bir çözüm buldum.

İlk olarak, aktivitenizde (örn. activity_main), Tüm düzenlere sahip olduğunuz yerde, a FrameLayout. Yüksekliği ve genişliği olmalı match parent. Ayrıca, bir id.

Şimdi, mevcut düzeni değiştirecek olan parçanızda, arayın onPause()ve onResume(). İçindeki tüm iç kapları ilklendirin View. Ve onların set visibilityiçin GONEdeonResume() ve VISIBLEdeonPause() .

NOT : FrameLayoutBu parça ile değiştirdiğiniz değil .

Eğer olduğunu varsayalım ViewPager, TabLayout, ImageViewve özel bir <fragment>yer activity_main.xml. FrameLayoutYukarıda belirtildiği gibi bir ekleyin .

In abcFragment.java, in onClick()function, add addToBackstack(null)in transaction.

Örnek kod:

abcFragment'ın (ve activity_main.xml'de gösterilen her şeyin) yerini alacak olan xyzFragment'da bunu yapın

@Override
    public void onResume() {
        super.onResume();

    // On resume, make everything in activity_main invisible except this fragment.
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.GONE);
    viewPager.setVisibility(View.GONE);
    miniPlayerFragment.setVisibility(View.GONE);
}

@Override
public void onPause() {
    super.onPause();

    // Make everything visible again
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.VISIBLE);
    viewPager.setVisibility(View.VISIBLE);
    miniPlayerFragment.setVisibility(View.VISIBLE);
}

Mutlu kodlamalar!


0

Örtüşen sorunu düzeltmek için FragmentTransaction'dan setTransition yöntemini kullanabilirsiniz.

transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

0

Oncreate'de ()

  BaseFragmentloginpage fragment = new BaseFragmentloginpage();
            android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.frame, fragment);
            fragmentTransaction.isAddToBackStackAllowed();
            fragmentTransaction.commit();

şimdi bu her zaman varsayılan parçanız olacaktır ... xml düzeninde parça eklerseniz her zaman üst üste gelecektir, bu nedenle ilk içeriği parça ile çalışma zamanında ayarlayın


0

bu sorunu çözdükten sonra aynı sorunu yaşadım

  1. Ur parçasını değiştirdiğiniz çerçeve düzenini alın

    <FrameLayout
                    android:id="@+id/fragment_place"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
  2. ve değiştirme kodu

    public void selectFrag(View view) {
    Fragment fr;
    
      if(view == findViewById(R.id.button2))
    {
         fr = new FragmentTwo();
    
     }else {
         fr = new FragmentOne();
     }
     FragmentManager fm = getFragmentManager();
     FragmentTransaction fragmentTransaction = fm.beginTransaction();
     fragmentTransaction.replace(R.id.fragment_place, fr);
     fragmentTransaction.commit();

Eğer bütün bir örnek istiyorsanız, size sadece yorum yazmayı göndereceğim ......


0

Ben de aynı sorunu yaşadım, ancak çerçeve düzenime eklemeye çalıştığım parçanın arka plan rengini değiştirmemiş olmamdı.

Bunu ile yapmayı deneyin layout_heightve şu şekilde layout_widthayarlayın:match_parent


0

Bir zamanlar bu sorunu yaşadım ve bunun android:backgroundxml kodunuzda eksik olan özniteliği yanlışlıkla silmiş olmamdan kaynaklandığını öğrendim . Sanırım bir duvarı boyadığınızda android:background, duvarın olacağı renk ve diğer görünümler bu temel rengin üstüne yerleştirilmiş. Görünümlerinizi konumlandırmadan önce duvarı boyamadığınızda, bunlar o duvarda, sizin durumunuzda, diğer parçanızın üstünde olacak. Bunun size yardımcı olup olmayacağını bilmiyorum, iyi şanslar.


0

Her şeyden önce denedim ve sorunu çözmeye çalıştım ama yine de çözüm bulamadım. Neden benim için çalışmadığını bilmiyorum. Yukarıdaki cevaplara katılıyorum çünkü pek çok kişi buna katılıyor.

Ben sadece cevabı genişletiyorum ve aşağıda benim için çalışan yol var.

Bu özelliği dosyadaki android:clickable="true"üst üst düzene ekledim fragment.xml.

Umarım birisi yardım alır.


0

Sapan Diwakar ve diğerlerine teşekkür ederim. Bu cevap bana yardımcı oldu. Basitçe içinde bir parçası olmayan bir RelativeLayout oluşturdum, RelativeLayout'u bir üst öğe veya grup görünümü olarak kullandım, bu grup görünümünü işlemde değiştirilecek şekilde belirledim ve işe yaradı.

Kod:

getSupportFragmentManager().beginTransaction()
                            .replace(R.id.content_group_view, itemDetailFragment).commit();

XML:

 <RelativeLayout
         android:id="@+id/content_group_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

 </RelativeLayout>

0

Çerçeve düzeni kimliğinizi kontrol edin ve aşağıdaki gibi değiştirin

fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.