2017-02-14 11 views
5

Mam 5 fragmentów, z których dwa to Fragmenty list zawierające niektóre dane (kosztowne ładowanie), a reszta z nich nie ma nic ważnego.Zarządzanie transakcjami fragmentów, w których nie chcesz utracić danych dla niektórych fragmentów.

Moim celem jest ustalenie sposobu zarządzania transakcjami, tak aby tylko jeden fragment listy pozostał w pamięci (przez cały czas), a po ponownym naciśnięciu powinien powrócić do fragmentu listy. To jest kod częściowy, który obsługuje to dla fragmentów, ale problem polega na tym, że gdy wciśniesz, nie rozładowuję bieżącego fragmentu, raczej wczytaj Fragment główny bez usuwania bieżącego fragmentu.

WorkFlow: Fragment główny (Fragment zadania) zostaje załadowany na początku, po czym można wczytać dowolny fragment. jeśli główny fragment jest aktualny i zaznaczony jest fragment grupy, a następnie usuń główny fragment, w przeciwnym razie, jeśli zostanie wybrany jakikolwiek inny fragment, zachowaj (ukryj) główny fragment i załaduj nowy fragment

Uwaga: Jest używany z szufladą nawigacji, gdzie 1 fragment jest załadowany na początku:

public class FragmentController { 

    private static final String TAG_MAIN = "main"; //Expensive 
    private static final String TAG_GROUP = "group"; //Expensive 
    private static final String TAG_PROFILE = "profile"; //Cheap 
    private static final String TAG_CREATE_TASK = "create_task"; //Cheap 
    private static final String TAG_CREATE_GROUP = "create_group";//Cheap 
    private static final String TAG_SETTINGS = "settings"; //Cheap 

    private android.support.v4.app.FragmentManager fragmentManager; 


    @IdRes private int container; 

    public FragmentController(android.support.v4.app.FragmentManager fragmentManager, @IdRes int container) { 
     this.fragmentManager = fragmentManager; 
     this.container = container; 
    } 

    public void showMainFragment() { 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     if (containsMainFragment()) { 
      if (!isMainCurrent()) { 
       transaction 
         .show(getMainFragment()) 
         .commit(); 
      } 
     } else { 
      transaction 
        .replace(container, getMainFragment(), TAG_MAIN) 
        .commit(); 
     } 
    } 

    public void showGroupFragment() { 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     if (containsGroupFragment()) { 
      if (!isGroupCurrent()) { 
       transaction 
         .show(getGroupFragment()) 
         .commit(); 
      } 
     } else { 
      transaction 
        .replace(container, getGroupFragment(), TAG_GROUP) 
        .commit(); 
     } 
    } 

    public void showProfileFragment() { 
     showLightFragment(ProfileFragment.newInstance(), TAG_PROFILE); 
    } 

    public void showCreateTaskFragment() { 
     showLightFragment(CreateTaskFragment.newInstance(), TAG_CREATE_TASK); 
    } 

    public void showCreateGroupFragment() { 
     showLightFragment(CreateGroupFragment.newInstance(), TAG_CREATE_GROUP); 
    } 

    public void showSettingsFragment() { 
     showLightFragment(SettingsFragment.newInstance(), TAG_SETTINGS); 
    } 

    private void showLightFragment(Fragment fragmentInstance, String tag) { 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 
     Fragment fragment = getCurrentFragment(); 
     if (containsListFragment() && (isMainCurrent() || isGroupCurrent())) { 
      assert fragment != null; 
      transaction = transaction 
          .hide(fragment) 
          .add(container, fragmentInstance, tag) 
          .addToBackStack(tag); 
     } else { 
      transaction = transaction 
          .remove(fragment) 
          .add(container, fragmentInstance, tag); 
     } 
     if(isCreateTaskFragment(fragment)){ 

      transaction = transaction 
        .addToBackStack(tag); 
     } 
     transaction.commit(); 
    } 

    private boolean containsListFragment() { 
     return getFragmentByTag(TAG_MAIN) != null || getFragmentByTag(TAG_GROUP) != null; 
    } 

    private boolean containsMainFragment() { 
     return getFragmentByTag(TAG_MAIN) != null; 
    } 

    private boolean containsGroupFragment() { 
     return getFragmentByTag(TAG_GROUP) != null; 
    } 

    private Fragment getMainFragment() { 
     Fragment fragment = getFragmentByTag(TAG_MAIN); 
     if (fragment == null) { 
      fragment = TasksFragment.newInstance(); 
     } 
     return fragment; 
    } 

    private Fragment getGroupFragment() { 
     Fragment fragment = getFragmentByTag(TAG_GROUP); 
     if (fragment == null) { 
      fragment = GroupTasksFragment.newInstance(); 
     } 
     return fragment; 
    } 

    private Fragment getFragmentByTag(String tag) { 
     return fragmentManager.findFragmentByTag(tag); 
    } 

    private Fragment getCurrentFragment() { 
     return fragmentManager.findFragmentById(container); 
    } 

    private boolean isMainCurrent() { return isCurrent(TAG_MAIN); } 

    private boolean isGroupCurrent() { 
     return isCurrent(TAG_GROUP); 
    } 

    private boolean isCurrent(String tag) { 
     Fragment fragment = getCurrentFragment(); 
     return fragment != null && fragment.getTag() != null && fragment.getTag().equals(tag); 
    } 

    private boolean isCreateTaskFragment(Fragment fragment){ 
     return fragment!=null && fragment.getTag()!=null && fragment.getTag().equals(TAG_CREATE_TASK); 
    } 

} 
+0

Czy próbowałeś debugować aplikację? Podejrzewam problem w twoim algorytmie showMainFragment. Możesz monitorować stos fragmentów w studiu android podczas debugowania aplikacji. – jdesesquelles

+0

@jdesesquelles Mam, ale problem jest nieco związany z backstack robi to, co ma zrobić, ale nie odłącza View of previous none backstack added fragment –

+0

Trudno powiedzieć. Jeśli możesz udostępnić swój kod, przyjrzę mu się. Możesz znaleźć inspirację tutaj: https://github.com/SimonVT/cathode. Przykład w zarządzaniu fragmentami. – jdesesquelles

Odpowiedz

0

dobrze tkwi problem, ale skończyło się na wymianie CreateTaskFragment (który był problem) z działalności.

1

Nie powinieneś dodawać/usuwać całego fragmentu samodzielnie, czyli mam na myśli. Używasz już backstack. Możesz tylko dodać/ukryć (na wypadek, gdybyś musiał zachować poprzedni fragment) lub zamienić. Następnie aktywność zrobi wszystko dla ciebie z

@Override 
public void onBackPressed() { 
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) { 
     getSupportFragmentManager().popBackStack(); 
    } else { 
     super.onBackPressed(); 
    } 
} 

Zobacz szczegóły tutaj: Performing Fragment Transactions

+0

Pomóż mi pomóc ... Jeśli mógłbyś podać mi swoją nazwę użytkownika github, dodam cię do repozytorium? –

Powiązane problemy