2012-12-12 20 views
13

Widziałem sporo pytań na temat SO o Fragments i nadal nie mogę się dowiedzieć, czy to, co chcę zrobić, jest możliwe, a bardziej, jeśli mój projekt Wzór jest po prostu wadliwy i potrzebuję przerobić cały proces. Zasadniczo, podobnie jak większość zadawanych pytań, mam ActionBar z NavigationTabs (przy użyciu ActionBarSherlock), a następnie w każdej karcie znajduje się FragingActivity, a następnie FragmentAktywity przesuwają nowe Fragmenty po wybraniu wiersza (próbuję odtworzyć Projekt iOS na Androida i to tylko podstawowa aplikacja oparta na nawigacjach z kilkoma zakładkami, które mogą drążyć konkretne informacje). Kiedy klikam przycisk powrotu w telefonie, poprzedni Fragment jest ładowany, ale Fragment odtwarza się ponownie (więc WebServices są wywoływane ponownie dla każdego widoku) i nie jest to konieczne, ponieważ informacje nie zmienią się w poprzednim widoku, gdy iść wstecz. Więc w zasadzie to, co chcę wymyślić, to jak skonfigurować moje Fragmenty, aby po naciśnięciu przycisku wstecz na telefonie, poprzedni Fragment został właśnie wyciągnięty z wcześniej utworzonych elementów. Poniżej jest mój bieżący kod:Android Fragment, wracając bez odtwarzania/ponownego ładowania Fragment

//This is from my FragmentActivity Class that contains the ActionBar and Tab Selection Control 
    @Override 
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 
    // TODO Auto-generated method stub 
    int selectedTab = tab.getPosition(); 

    if (selectedTab == 0) { 
     SalesMainScreen salesScreen = new SalesMainScreen(); 
     ft.replace(R.id.content, salesScreen); 
    } 
    else if (selectedTab == 1) { 
     ClientMainScreen clientScreen = new ClientMainScreen(); 
     ft.replace(R.id.content, clientScreen); 
    }..... 

    //This is within the ClientMainScreen Fragment Class, which handles moving to the Detail Fragment 
    row.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          //Do something if Row is clicked 
          try{ 
           String selectedClientName = clientObject.getString("ClientName"); 
           String selectedClientID = clientObject.getString("ClientID"); 
           String selectedValue = clientObject.getString("ClientValue"); 
           transaction = getFragmentManager().beginTransaction(); 
           ClientDetailScreen detailScreen = new ClientDetailScreen(); 
           detailScreen.clientID = selectedClientID; 
           detailScreen.clientName = selectedClientName; 
           detailScreen.clientValue = selectedValue; 
           int currentID = ((ViewGroup)getView().getParent()).getId(); 
           transaction.replace(currentID,detailScreen); 
           transaction.addToBackStack(null); 
           transaction.commit(); 

          } 
          catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } 
        });.... 

    //And then this is the Client Detail Fragment, with the method being called to Call the Web Service and create thew (since what is displayed on this screen is dependent on what is found in the Web Service 
      @Override 
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved) { 
    return inflater.inflate(R.layout.clientdetailscreen, group, false); 
} 

@Override 
public void onActivityCreated (Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    //Setup Preferences File Link 
    this.preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 

    //initialize the table object 
    mainTable = (TableLayout)getActivity().findViewById(R.id.mainTable); 

    //setup the detail table 
    setupRelatedClientSection(); 

} 

Ekran Client Szczegóły można następnie drążyć jeszcze raz, przy użyciu tej samej metody co klient ekranu głównego, ale kiedy wrócę z tego nowego ekranu do Szczegółowo Ekran ten seuptRelatedClientSection () Metoda jest wywoływana ponownie, więc cały Fragment jest przebudowywany, gdy naprawdę chcę tylko zapisać zapisaną wersję tego ekranu. Czy to możliwe przy mojej obecnej konfiguracji, czy też podchodziłem do tego w niewłaściwy sposób?

Odpowiedz

7

Wierzę, że szukasz show() i hide().

Myślę, że nadal można dodać je do backstack.

transaction.hide(currentFragment); 
transaction.show(detailScreen); 
transaction.addToBackStack(null); 
transaction.commit(); 

Nie miałem mojego kodu do obejrzenia, ale wierzę, że tak to pójdzie ... Wypróbuj, chyba że ktoś inny ma lepszy sposób. Nie próbowałem backstack z show() hide(), ale wierzę, że to robi zmiany, które zostały wprowadzone przed zatwierdzeniem transakcji i cofnie je, jeśli zostanie naciśnięty przycisk Wstecz. Proszę, wróć do mnie na ten temat, jestem zainteresowany.

Musisz się także upewnić, że fragment szczegółów został utworzony przed wywołaniem tego. Ponieważ opiera się na kliknięciu someitem, powinieneś prawdopodobnie utworzyć fragment szczegółów za każdym razem, gdy klikniesz, aby upewnić się, że został utworzony poprawny fragment szczegółów.

+4

użyłem .add() zamiast .Show(). Z drugiego fragmentu, kiedy nacisnąłem przycisk, przeszedłem do pierwszego fragmentu i nie odświeżałem. – Sri

0

Masz rację, nastąpił szereg poprzednich pytań/dokumentacja na ten temat;)

Dokumentacja na fragmentach, w szczególności odcinek o transakcjach i stanie oszczędzania, poprowadzi cię do odpowiedzi.

http://developer.android.com/guide/components/fragments.html#Transactions

http://developer.android.com/guide/components/activities.html#SavingActivityState

Android - Fragment onActivityResult avoid reloading

Fragmenty mogą mieć wsparcie dla onSaveInstanceState ale nie onRestoreInstanceState, więc jeśli chcesz zapisać odniesienie do widoków tabel, zapisać je do Bundle i można uzyskać dostęp do zapisanego widoku w metodzie onActivityCreated. Możesz również użyć tylnego stosu Fragmentów.

This guide/tutorial zawiera bardzo szczegółowe instrukcje/przykłady na stosie tylnym i stanie zatrzymania fragmentu.

Powodzenia

7

Spróbuj użyć fragementTransaction.add zamiast zastąpić

3

jestem delegowania to odpowiedź dla ludzi, którzy mogą odnosić tę kwestię w przyszłości.

Poniższy kod pokaże, w jaki sposób otworzyć FragmentB z FragmentA i powrócić do FragmentA z FragmentB (bez odświeżania FragmentAA), naciskając przycisk Wstecz.

public class FragmentA extends Fragment{ 

    ... 

    void openFragmentB(){ 

     FragmentManager fragmentManager = 
      getActivity().getSupportFragmentManager(); 
     FragmentB fragmentB = FragmentB.newInstance(); 

     if (fragmentB.isAdded()) { 

      return; 
     } else { 

      fragmentManager. 
       beginTransaction(). 
       add(R.id.mainContainer,fragmentB). 
       addToBackStack(FragmentB.TAG). 
       commit(); 
     } 
    } 
} 

public class FragmentB extends Fragment{ 

    public static final String TAG = 
     FragmentB.class.getSimpleName(); 

    ... 

    public static FragmentB newInstance(){ 

     FragmentB fragmentB = new FragmentB(); 
     return fragmentB; 
    } 

    @Override 
    public void onResume() { 

     super.onResume(); 
     // add this piece of code in onResume method 
     this.getView().setFocusableInTouchMode(true); 
     this.getView().requestFocus(); 
    } 
} 

W swojej główną działalność ręcznym onBackPressed()

class MainActivity extends Activity{ 
    ... 

    @Override 
    public void onBackPressed() { 

     if (getFragmentManager().getBackStackEntryCount() > 0) { 

      getFragmentManager().popBackStack(); 
     } else { 

      super.onBackPressed(); 
     } 
    } 
}