Заміна фрагмента іншим фрагментом всередині групи активності


137

У мене є фрагмент всередині групової діяльності, і я хочу замінити його іншим фрагментом:

FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
SectionDescriptionFragment bdf = new SectionDescriptionFragment();
ft.replace(R.id.book_description_fragment, bdf);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();

Це прекрасно працює, коли він робиться як окремий проект, не використовуючи групу активності, кожна річ прекрасно працює в журналі cat, оскільки контроль надходить у getview (), але ніякого перегляду не видно, навіть не виникає жодного винятку, я хочу, щоб фрагмент деталі книги замінити фрагментом деталі розділу.

Xml фрагмент деталі книги має ідентифікатор book_description_fragment, а xml для фрагмента опису розділу має ідентифікатор section_description_fragment.

Вищевказаний код знаходиться в методі onClick елемента, я хочу, щоб, коли користувач торкається елемента в горизонтальному перегляді прокрутки, тоді фрагмент змінюється.

Відповіді:


250

Фрагменти, які жорстко закодовані в XML, неможливо замінити. Якщо вам потрібно замінити фрагмент на інший, слід, перш за все, додати їх динамічно.

Примітка: R.id.fragment_container - це макет або контейнер на ваш вибір у тій діяльності, до якої ви доводите фрагмент.

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

8
що таке R.id.fragment_container в цьому випадку?
Хлопець

4
@Guy, Це може бути будь-який макет, на який ви хочете завантажити фрагмент.
Субін Себастьян

1
якою має бути назва фрагмента у файлі xml? Я хочу додати фрагмент динамічно і не хочу статичного фрагмента.
Раджат Мехра

1
@RajatMehra Якщо ви хочете додати фрагменти динамічно, вам зовсім не потрібно вказувати фрагмент всередині XML. Можна використовувати перегляд контейнера. Будь ласка, прочитайте відповідь ще раз.
Субін Себастьян

4
@Ahmed Причина полягає в тому, що за архітектурою система замінює кожен тег <fragment> представленням (групою), наданим відповідними фрагментами ' onCreateView(). Таким чином, як ви можете припустити, будь-яке посилання на фрагмент фактично втрачається на рівні перегляду. Таким чином, ви в основному не можете замінити фрагмент, але, скоріше, ви можете вручну видалити представлення, які зараз є у контейнері, і замість цього поставити фрагмент, якщо потрібно.
Субін Себастьян

35

Будь ласка, дивіться це питання

Можна замінити лише " динамічно доданий фрагмент ".

Отже, якщо ви хочете додати динамічний фрагмент, дивіться цей приклад.


1
Привіт . Я виявив рішення, насправді я не розміщував вміст фрагмента в макеті, а використовував інший фрагмент для вмісту попереднього фрагмента
Серце Лева

Ні, тут я шукав замінити весь фрагмент новим фрагментом.
Сана

1
@ Lion Heart, Ви можете, будь ласка, розробити рішення, яке ви знайшли?
Намратха

Посилання мертве: /
Неонова війна

8

Я створив суть із ідеальним методом управління заміною фрагментів та життєвим циклом .

Він лише замінить поточний фрагмент новим, якщо він не той самий і якщо він не знаходиться в задніх куточках (у цьому випадку він виведе його).

Він містить кілька варіантів, як якщо ви хочете, щоб фрагмент був збережений у задніх куточках.

=> Дивіться історію тут

Використовуючи цю та одну активність, ви можете додати це до своєї діяльності:

@Override
public void onBackPressed() {
    int fragments = getSupportFragmentManager().getBackStackEntryCount();
    if (fragments == 1) {
            finish();
            return;
    }

    super.onBackPressed();
}

1
@ RémiP посилання працює як очікувалося. Ви можете перевірити це, що може бути краще IMO github.com/HugoGresse/Anecdote/blob/master/app/src/main/java/io/…
Уго

8

Використовуйте наведений нижче код на android.support.v4

FragmentTransaction ft1 = getFragmentManager().beginTransaction();
WebViewFragment w1 = new WebViewFragment();
w1.init(linkData.getLink());
ft1.addToBackStack(linkData.getName());
ft1.replace(R.id.listFragment, w1);
ft1.commit();

4

Використовуйте цей код за допомогою v4

 ExampleFragment newFragment = new ExampleFragment();     
 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
 // Replace whatever is in the fragment_container view with this fragment,  
 // and add the transaction to the back stack so the user can navigate back   
 transaction.replace(R.id.container, newFragment);
 transaction.addToBackStack(null);  
 // Commit the transaction   
 transaction.commit();

3

сподіваюся, у вас все добре. Коли я почав працювати Android Fragmentsтоді, у мене теж була така ж проблема, тоді я читав про 1- Як переключити фрагмент з іншим. 2- Як додати фрагмент, якщо у Fragment containerнього немає жодного фрагмента.

потім, після деяких досліджень і розробок, я створив функцію, яка допомагає мені в багатьох проектах дотепер, і я все ще використовую цю просту функцію.

public void switchFragment(BaseFragment baseFragment) {
    try {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        if (getSupportFragmentManager().findFragmentById(R.id.home_frame) == null) {
            ft.add(R.id.home_frame, baseFragment);
        } else {
            ft.replace(R.id.home_frame, baseFragment);
        }
        ft.addToBackStack(null);
        ft.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

насолоджуйтесь своїм кодом :)


3

Використовуйте ViewPager. Це для мене робота.

final ViewPager viewPager = (ViewPager) getActivity().findViewById(R.id.vp_pager); 
button = (Button)result.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        viewPager.setCurrentItem(1);
    }
});

1

Ви можете використовувати цей код

((AppCompatActivity) getActivity()).getSupportFragmentManager().beginTransaction().replace(R.id.YourFrameLayout, new YourFragment()).commit();

або Ви можете використовувати цей код

YourFragment fragments=(YourFragment) getSupportFragmentManager().findFragmentById(R.id.FrameLayout);

        if (fragments==null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayout, new Fragment_News()).commit();
        }

0

У котліні ви можете:

// instantiate the new fragment
val fragment: Fragment = ExampleFragment()

val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.book_description_fragment, fragment)
transaction.addToBackStack("transaction_name")
// Commit the transaction
transaction.commit()

0

ви можете використовувати простий код його роботи для транзакцій

Fragment newFragment = new MainCategoryFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame_NavButtom, newFragment);
ft.commit(); 

0

Я динамічно
змінюю фрагмент в однорядковому коді. Він працює в будь-якій версії SDK і Android,
я використовую навігацію якBottomNavigationView

    BottomNavigationView btn_nav;
    FragmentFirst fragmentFirst;
    FragmentSecond fragmentSecond;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        fragmentFirst = new FragmentFirst();
        fragmentSecond = new FragmentSecond ();
        changeFragment(fragmentFirst); // at first time load the fragmentFirst
        btn_nav = findViewById(R.id.bottomNav);
        btn_nav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                switch(menuItem.getItemId()){
                    case R.id.menu_first_frag:
                        changeFragment(fragmentFirst); // change fragmentFirst
                        break;
                    case R.id.menu_second_frag:
                        changeFragment(fragmentSecond); // change fragmentSecond
                        break;
                        default:
                            Toast.makeText(SearchActivity.this, "Click on wrong bottom SORRY!", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }
public void changeFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout_changer, fragment).commit();
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.