8

Mam przeglądarkę, z kilkoma fragmentami oczywiście. Każdy z tych fragmentów ma CoordinatorLayout jako rodzic.Android: Wiele przekąsek w osobnych Fragmentach (ViewPager)

Pokazuję coś przekąskowego. Problem polega na tym, że jeśli Fragment A pokazuje pasek z przekąskami, jest w porządku, ale jeśli sąsiadujący fragment B pokazuje również pasek z przekąskami, pasek zakąsek w fragmencie A automatycznie się ukrywa.

Ponieważ sąsiednie fragmenty sąsiadujące ze stroną są wstępnie załadowane, jest to widoczny problem. Jakiekolwiek obejście? Czy robię to źle?

+0

Hi KalpitJain! Czy znalazłeś odpowiedź? Mam ten sam problem. – vijay

+0

Ma 2 lata, nie pamiętam dokładnie. Wydaje mi się, że rozwiązaniem było utrzymanie wiadomości, która ma być wyświetlana w pasku adresu w każdym fragmencie - i pokazywanie jej, ilekroć ten konkretny fragment staje się widoczny dla użytkownika (i innych) – TheKalpit

Odpowiedz

2

Można użyć setUserVisibleHint(boolean isVisible) zaktualizować widoczności fragment (na przykład na swoim ViewPager onPageSelected), a następniegetUserVisibleHint() na fragmencie pokazać bistrem tylko wtedy, gdy fragment jest widoczny.

Powiedzmy, że masz Fragmenty A, B & C

Fragment A jest widoczny i tak jest bistrem Jeśli Fragment B lub C próby otwarcia Snackbar, getUserVisibleHint() zwróci false, a oni wont bałagan z Fragment A Snackbar.

Obs. Zachowaj ostrożność przy użyciu FragmentStatePagerAdapter, ponieważ możesz pobrać NPE, przechowując odniesienia do Fragments i wywołując setUserVisibleHint() na tych odniesieniach.

Edytuj: Nie potrzebujesz setUserVisibleHint(), ponieważ jest już wywoływana przez system.

2

Istnieje kilka problemów z bistrem w wielu fragmentów w ViewPager

1) W przypadku snack bar Pokazany na Fragment A (widzialnym) i Fragment B (nie pokazano), tak Snackbar nie jest widoczny.

2) Jeśli użyję kombinacji @Override setUserVisibleHint i getUserVisibleHint() do inteligentnego pokazywania i ukrywania paska nawigacyjnego w zależności od widoczności fragmentu, działa on tylko za pierwszym razem. Po tym, wywołanie snackbar.show() nie pokazuje już paska z przekąskami (chyba że ponownie utworzę pasek zakąsek).

co następuje moja proponowane rozwiązanie (testowane z v23.1.1):

public class SnackbarManager { 
    private static final String TAG = SnackbarManager.class.getName(); 

    private Snackbar snackbar; 
    private Create instance; 
    // private boolean isMultiSnackbar; 

    public interface Create { 
     Snackbar create(); 
    } 

    public SnackbarManager(Create instance) { 
     // why not pass in snackbar? coz snackbar.show will fail after 1st show (it multiple snackbar), thus need to recreate it 
     snackbar = instance.create(); 
     this.instance = instance; 
    } 

    public void show(Fragment fragment) { 
     if (fragment.getUserVisibleHint()) { 
      snackbar.show(); 
     } 
    } 

    public void onSetUserVisibleHint(boolean isVisible) { 
     if (isVisible) { 
      if (snackbar == null) { 
       snackbar = instance.create(); 
      } 
      snackbar.show(); 
      Log.d(TAG, "showSnackbar="+snackbar.isShown()); 
      // if snackbar.isShown()=false, if means multiple snackbar exist (might or might not be in same fragment) 
      /* 
      boolean isMultiSnackbar = !snackbar.isShown(); 
      // the following is inaccurate when I manually dismiss one of the snackbar 
      // even when isShown()=true, the snackbar is not shown 
      if (isMultiSnackbar) { 
       snackbar = null; 
       snackbar = instance.create(); 
       snackbar.show(); 
      } 
      */ 
      } 
      else { 
       Log.d(TAG, "dismissSnackbar"); 
       snackbar.dismiss(); 
       // subsequent show will fail, make sure to recreate next 
       snackbar = null; 
      } 
     } 
    } 
} 

public class TestFragment extends Fragment { 
    private SnackbarManager snackbarManager; 

    @Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 
     if (snackbarManager != null) 
      snackbarManager.onSetUserVisibleHint(isVisibleToUser); 
    } 

    public void showSnackbar() { 
     snackbarManager = new SnackbarManager(new SnackbarManager.Create() { 
      @Override 
      public Snackbar create() { 
       Snackbar snackbar = Snackbar.make(snackbarLayout, "Create your first moment ;)", Snackbar.LENGTH_INDEFINITE); 
       snackbar.setAction("Create", new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
         snackbarManager = null; 
        } 
       }); 
       // enable following if not Snackbar.LENGTH_INDEFINITE 
       /* 
       snackbar.setCallback(new Snackbar.Callback() { 
        @Override 
        public void onDismissed(Snackbar snackbar, int event) { 
         super.onDismissed(snackbar, event); 
         snackbarManager = null; 
        } 
       }) 
       */ 
       return snackbar; 
      } 
     }); 
     snackbarManager.show(this); 
    } 
}