2011-03-14 20 views
44

Ok, za każdym razem, gdy próbuję zastąpić fragment w mojej aplikacji, dodaje on tylko fragment wewnątrz kontenera, który zawiera drugi fragment, i pozostawia bieżący fragment. Próbowałem wywoływać zamianę i odwoływanie się do widoku zawierającego fragment oraz przez odwoływanie się do samego fragmentu. Żadne z tych zadań nie działa. Mogę dodać fragment do widoku z fragmentem menedżera transakcji, ale nawet jeśli spróbuję go usunąć po jego dodaniu, to nie działa. Każda pomoc będzie doceniona. Oto moje pliki.Duplikacja fragmentów w przypadku transakcji fragmentów

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //Setup the actionabar. Use setDrawableBackground to set a background image for the actionbar. 
    final ActionBar actionbar = getActionBar(); 
    actionbar.setDisplayShowTitleEnabled(false); 
    actionbar.setDisplayUseLogoEnabled(true); 
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    actionbar.addTab(actionbar.newTab().setText(R.string.home_tab_text).setTabListener(this),true); 
    actionbar.addTab(actionbar.newTab().setText(R.string.insert_tab_text).setTabListener(this)); 

    Fragment fragment = new insert_button_frag(); 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.replace(R.id.button_fragment, fragment); 
    transaction.addToBackStack(null); 

    transaction.commit(); 
} 

Oto układ

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:id="@+id/button_fragment_container" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" > 

     <fragment 
      android:name="com.bv.silveredittab.home_button_frag" 
      android:id="@+id/button_fragment" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" /> 

    </LinearLayout> 

    <LinearLayout 
     android:orientation="horizontal" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <fragment 
      android:name="com.bv.silveredittab.quick_insert_frag" 
      android:id="@+id/quick_insert_frag" 
      android:layout_width="350dip" 
      android:layout_height="fill_parent" /> 

     <fragment 
      android:name="com.bv.silveredittab.editor_frag" 
      android:id="@+id/editor_frag" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" /> 

    </LinearLayout> 

</LinearLayout> 

A oto fragment kodu

public class insert_button_frag extends Fragment { 

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

Jak już powiedziałem. Próbowałem odwoływać się do fragmentu nadrzędnego widoku, aby go zastąpić, a sam fragment (według id) i nadal dodaje tylko nowy fragment, wewnątrz widoku zawierającego oryginalny fragment.

+0

Co zawiera plik układu insert_buttons.xml? – Peter

Odpowiedz

33

I rozwiązać to za pomocą zastępczy w moim układzie i następnie dołączenie mojego Fragment do niego w czasie wykonywania.

Podobnie jak Ty, jeśli utworzyłem mój Fragment w moim układzie xml, zawartość pozostanie widoczna po zastąpieniu go innym Fragmentem w czasie wykonywania.

+4

. To, co musiałem zrobić. Trochę opóźniony Kinda? – Shaun

+2

Haha, tak! Błąd lub * Cecha * Zastanawiam się. – Damian

+1

Dokładnie. Wygląda na to, że metoda zamiany jest wtedy bezużyteczna. – Tastybrownies

2

Miałem ten sam problem. Spójrz na ten link: Android Fragment Duplication

Zastanawiam się, czy fakt, że przechodzisz pojemnik do metody inflater.inflate() powoduje, że tworzy nowy fragment wewnątrz starego zamiast zastępowania hurtowego. Dostarczam "null" do moich inflaterów w wersji roboczej.

Oto szczegółowa od wersji mam pracy ...

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    View newFrag = new View(getActivity().getApplicationContext()); 
    newFrag = inflater.inflate(R.id.frag, null); 
    return newFrag; 
} 
+0

Spojrzałem na to, ale nie sądzę, że to naprawdę dotyczy mojej sytuacji. Im nie zapełniam moich fragmentów prognostycznie. Z jakiegoś powodu mój kod nie znajduje istniejącego fragmentu, więc jego nie zastępuje. Nie generuje nawet błędów ani ostrzeżeń. To naprawdę zagmatwane. – Shaun

+0

Przepraszam, że to nie pomogło. Poprawiłem moją odpowiedź na: Nadmuch, ale jeśli to nie pomoże, musiałbym rozwiązać problem z IDE. – Peter

+0

Próbowałem ten return inflater.inflate (R.layout.home_buttons, null, false); ale to nie działało ani – Shaun

18

Problemem jest to linia:

transaction.replace(R.id.button_fragment, fragment); 

replace ma dwie przeciążone formy. W obu przypadkach pierwszym argumentem jest kontenerFragment, który ma zostać zastąpiony, a nie sam Fragment. Tak więc, w przypadku, trzeba zadzwonić

transaction.replace(R.id.button_fragment_container, fragment); 

edit: widzę w swoim pytaniu, że próbował obu. Przetestowałem i zweryfikowałem zachowanie. Wygląda na to, że jest to błąd w API FragmentTransaction.

Edycja2: nie jest to błąd. Po prostu nie można zastąpić fragmentów dodanych statycznie w pliku układu. Możesz tylko zastąpić te dodane programowo (Android: can't replace one fragment with another)

0

Jest to dość mylące, ponieważ pokazuje najpierw, aby zaimplementować w Twoim komputerze kodowany fragment. Ale jeśli naprawdę chcesz zastąpić istniejący fragment nowym, powinieneś go dodać (pierwszy) w czasie wykonywania.

Co official site stan jest

FragmentTransaction wymienić (int containerViewId fragment fragment etykiety łańcuchach)

zastąpić istniejący fragmentu, który został dodany do pojemnika. Jest to zasadniczo takie samo jak wywołanie remove (Fragment) dla wszystkich aktualnie dodanych fragmentów, które zostały dodane z tym samym containerViewId, a następnie add (int, Fragment, String) z tymi samymi argumentami tutaj podanymi.

Powinieneś zauważyć, że mówi, że zastąpić istniejący fragment, który dodano do pojemnika

Więc Twój xml powinien wyglądać someActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    ... 
    tools:context="someActivity"> 

    <ImageView 
     .../> 

    <LinearLayout 
     android:id="@+id/fragment_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" 
     android:gravity="bottom"/> 

</RelativeLayout> 

A niż w swojej działalności, wykonaj w OnCreate()

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     [...] 
     getSupportFragmentManager().beginTransaction() 
       .add(R.id.fragment_container, new FirstFragment).commit(); 

    } 

Niż można łatwo zastąpić fragment swoimi animacjami i zdarzeniem dodać go do tylnego stosu, aby zapisać jego stan.

private SecondFrag getSecondFrag(){ 
    if(secondFrag == null) 
     secondFrag = new SecondFrag() 
    return secondFrag; 
} 

private void openRechargeFragment(){ 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     ft.setCustomAnimations(R.anim.show_frag, R.anim.hide_frag, 
       R.anim.show_frag, R.anim.hide_frag); 
     ft.replace(R.id.fragment_container, getSecondFrag(), "myTAG"); 
     ft.addToBackStack(null); 
     ft.commit(); 
} 
Powiązane problemy