10

Ниже мой код для элемента просмотра нижней навигации выбранФрагмент воссозданы по пункту Вид снизу навигации выбран

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
@Override 
public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
    Fragment fragment = null; 
    switch (item.getItemId()) { 
     case R.id.action_one: 
      // Switch to page one 
      fragment = FragmentA.newInstance(); 
      break; 
     case R.id.action_two: 
      // Switch to page two 
      fragment = FragmentB.newInstance(); 
      break; 
     case R.id.action_three: 
      // Switch to page three 
      fragment = FragmentC.newInstance(); 
      break; 
    } 
    getSupportFragmentManager().beginTransaction().replace(R.id.container,fragment,"TAG").commit(); 
    return true; 
} 
}); 

Теперь моя проблема воссоздан каждый фрагмент времени и не хотите фрагмента быть воссозданы каждый раз, когда я также пробовал добавлять addToBackStack (null), но в этом случае на кнопку «Назад» продолжает выскакивать фрагменты из стека, которые я не хочу.

Есть ли способ отображения фрагментов на нижней панели навигации, выбранной без повторного создания фрагмента

+0

Чтобы избежать этого, я создать карту: 'Map <ИНТ, Fragment>' и каждый фрагмент имеет статический идентификатор. Я создаю весь фрагмент в 'onCreate'' Activity'. Но это не рекомендуется. Вы можете добавить фрагмент в 'backstack' с помощью уникального тега, например' Fragment.class.getSimpleName() ', а затем найти его с помощью' findFragmentByTag' и передать его снова. Не забудьте добавить каждый «Фрагмент» один раз в «backstack» –

+0

Привет, Рафаэль, как я уже сказал, я не хочу добавлять его к стоп-кадрам, так как он мешает при нажатии на задний экран. – apk

+0

Для этого вы можете переопределить 'onBackPressed()' в вашей «Деятельности». Комментарий 'super.onBackPressed()' –

ответ

6

Попробуйте это:

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
       @Override 
       public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
        Fragment fragment = null; 
        Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container); 
        switch (item.getItemId()) { 
         case R.id.action_one: 
          // Switch to page one 
          if (!(currentFragment instanceof FragmentA)) { 
           fragment = FragmentA.newInstance(); 
          } 
          break; 
         case R.id.action_two: 
          // Switch to page two 
          if (!(currentFragment instanceof FragmentB)) { 
           fragment = FragmentB.newInstance(); 
          } 
          break; 
         case R.id.action_three: 
          // Switch to page three 
          if (!(currentFragment instanceof FragmentC)) { 
           fragment = FragmentC.newInstance(); 
          } 
          break; 
        } 
        getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment, "TAG").commit(); 
        return true; 
       } 
      }); 

Это будет получить текущий фрагмент в вашем container и если вы снова нажмите на этот фрагмент, который не будет добавлять фрагмент.

+0

Как я могу перенаправить на домашнюю страницу, когда я нажимаю кнопку «Назад» ... пожалуйста, помогите мне sir –

+0

Вы можете «переопределить» fucntion 'onBackPressed' on ваша главная «Деятельность». –

+2

В вашем коде, если первый FragmentA загружен, После щелчка на втором, чем второй фрагмент, после этого, если пользователь нажмет на firstFragment, то также будет воссоздан. –

-1

setOnNavigationItemReselectedListener будет лучшим решением для этой

9

С библиотекой поддержки v26 вы можете сделать это

FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction(); 
    Fragment fragment = mFragmentManager.findFragmentByTag(tag); 
    if (fragment == null) { 
     fragment = new YourFragment(); 
     fragmentTransaction.add(container.getId(), fragment, tag); 
    } else { 
     fragmentTransaction.attach(fragment); 
    } 

    Fragment curFrag = mFragmentManager.getPrimaryNavigationFragment(); 
    if (curFrag != null) { 
     fragmentTransaction.detach(curFrag); 
    } 

    fragmentTransaction.setPrimaryNavigationFragment(fragment); 
    fragmentTransaction.setReorderingAllowed(true); 
    fragmentTransaction.commitNowAllowingStateLoss(); 
+1

Для получения полного примера вы можете посмотреть этот git repo https://github.com/okaybroda/FragmentStateManager – Viven

+0

Вы бы сказали, что это лучший способ обработки навигации между тремя пунктами назначения, когда вы хотите сохранить позиции состояния/списка и т. Д., Когда двигаясь вперед и назад? Существуют ли какие-либо предостережения для использования этого метода? Возможные утечки памяти или что-то, что нужно знать? Я не 100% -ный звук на жизненном цикле довольно давно – Burkely91

+0

Было бы лучше сделать это или как-то восстановить состояние экземпляра, это то, что я действительно хочу знать, я думаю! – Burkely91

2

Будьте осторожны при использовании replace. Даже если предоставить фрагмент, который уже существует в памяти, replace перезапустит жизненный цикл фрагмента. Чтобы избежать перезапуска, методы объекта транзакции включают add, show и hide, которые могут быть использованы для отображения правильного фрагмента без его перезапуска.

private fun switchFragment(index: Int) { 
    val transaction = supportFragmentManager.beginTransaction() 
    val tag = fragments[index].tag 

    // if the fragment has not yet been added to the container, add it first 
    if (supportFragmentManager.findFragmentByTag(tag) == null) { 
     transaction.add(R.id.container, fragments[index], tag) 
    } 

    transaction.hide(fragments[navigationBar.currentTabPosition]) 
    transaction.show(fragments[index]) 
    transaction.commit() 
} 
+1

Вы использовали несколько путаную формулировку там, чтобы уточнить: replace не перезапускает жизненный цикл фрагментов, поскольку он добавлен в пользовательский интерфейс - он завершает прикрепленный фрагмент, а затем добавляет новый фрагмент, который мы можем только предположить, был ранее уничтожен если удалено или оно добавляется в первый раз. Таким образом, он, несомненно, будет начинаться с да, но не потому, что замена вынуждает его. По существу replace = remove (oldFrag), затем добавьте (newFrag). – Burkely91

+0

Что такое 'currentTabPosition'? 'android.support.design.widget.BottomNavigationView', похоже, не обладает этим свойством. –

1

Использование setOnNavigationItemReselectedListener так:

private BottomNavigationView.OnNavigationItemReselectedListener onNavigationItemReselectedListener 
      = new BottomNavigationView.OnNavigationItemReselectedListener() { 

     @Override 
     public void onNavigationItemReselected(@NonNull MenuItem item) { 
      Toast.makeText(MainActivity.this, "Reselected", Toast.LENGTH_SHORT).show(); 
     } 
    }; 

и вызвать его с помощью:

navigation.setOnNavigationItemReselectedListener(onNavigationItemReselectedListener);