Замена фрагмента другим фрагментом внутри группы действий


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();

Он отлично работает, когда выполняется как отдельный проект без использования группы действий, все отлично работает в log 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
@ Гай, это может быть любой макет, в который вы хотите загрузить фрагмент.
Субин Себастьян

1
каким должно быть название фрагмента в XML-файле? Я хочу добавить фрагмент динамически и не хочу никакого статического фрагмента.
Раджат Мехра

1
@RajatMehra Если вы хотите динамически добавлять фрагменты, вам вовсе не обязательно указывать фрагмент внутри XML. Вы можете использовать вид контейнера. Пожалуйста, прочитайте ответ снова.
Субин Себастьян

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

35

Пожалуйста, посмотрите этот вопрос

Вы можете заменить только « динамически добавленный фрагмент ».

Итак, если вы хотите добавить динамический фрагмент, посмотрите этот пример.


1
Здравствуй . Я нашел решение, на самом деле я не помещал содержимое фрагмента в макет, вместо этого я использовал другой фрагмент для содержимого предыдущего фрагмента
Lion Heart

Нет, здесь я искал, чтобы заменить весь фрагмент новым фрагментом.
Сана

1
@ Львиное Сердце, не могли бы вы разработать решение, которое вы нашли, пожалуйста?
Намрата,

Ссылка мертва: /
Неон Warge

8

Я разработал идеальный метод управления заменой фрагментов и жизненным циклом .

Он заменяет только текущий фрагмент новым, если он не совпадает и не находится в backstack (в этом случае он выскочит).

Он содержит несколько опций, как будто вы хотите сохранить фрагмент в backstack.

=> Смотрите Гист здесь

Используя это и одно действие, вы можете добавить это в свое действие:

@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/…
Hugo Gresse

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

В kotlin вы можете сделать:

// 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 и AndroidX.
Я использую навигацию как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.