Как заменить фрагмент активности из самого фрагмента? - программирование
Подтвердить что ты не робот

Как заменить фрагмент активности из самого фрагмента?

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

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

Возможно ли это? Если да, то как это сделать?

4b9b3361

Ответ 1

На самом деле легко вызвать операцию для замены фрагмента.

Вам нужно нажать getActivity():

((MyActivity) getActivity())

Затем вы можете вызывать методы из MyActivity, например:

((MyActivity) getActivity()).replaceFragments(Object... params);

Конечно, это предполагает, что у вас есть метод replaceFragments() в вашей деятельности, который обрабатывает процесс замены фрагмента.

Изменить: @ismailarilik добавил возможный код replaceFragments в этом коде с первым комментарием ниже, который был написан @silva96:

Код replaceFragments может быть:

public void replaceFragments(Class fragmentClass) {
    Fragment fragment = null;
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment)
            .commit();
}

Ответ 2

из официальных документов:

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

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

// Commit the transaction
transaction.commit();

В этом примере newFragment заменяет любой фрагмент (если он есть) в настоящее время в контейнере макета, идентифицированном идентификатором R.id.fragment_container. Вызывая addToBackStack(), замененный фрагмент сохраняется в фоновом стеке, поэтому пользователь может отменить транзакцию и вернуть предыдущий фрагмент, нажав кнопку "Назад".

Поведение, которое вы описали, именно то, что предназначены для фрагментов. Пожалуйста, ознакомьтесь с официальным руководством для полного понимания фрагментов, которые помогут вам решить все ваши вопросы.

http://developer.android.com/guide/components/fragments.html

Ответ 3

Обратите внимание, что фрагмент должен НЕ напрямую заменять себя или любые другие фрагменты. Фрагменты должны быть отдельными объектами. Какой фрагмент должен сделать, так это сообщить родительской активности о том, что произошло какое-то событие. Но это опять же НЕ фрагментная работа, чтобы решить, что с этим делать! Это должно быть действием, чтобы принять решение о замене фрагмента на телефоне, но, то есть добавлении другого в существующий на планшетах. Таким образом, вы в основном делаете что-то не так по дизайну.

И, как уже упоминалось ранее, ваша работа должна использовать FragmentManager ( "родной" или из библиотеки совместимости) для выполнения задания (например, replace() или add() или remove()):

http://developer.android.com/guide/components/fragments.html

Ответ 4

Так же, как сказал Марсин, у вас не должно быть фрагмента, начинающегося с другого фрагмента или активности. Лучший способ справиться с этой ситуацией - создать реализацию обратного вызова для основного действия для обработки запросов, таких как запуск нового фрагмента. Здесь - отличный пример в руководстве разработчика Android.

Ответ 5

Есть способ, который работает; Просто (во фрагменте) сделайте следующее:

getFragmentManager().beginTransaction()
.add(R.id. container_of_this_frag, new MyNewFragment())
.remove(this)
.commit();

Ответ 6

При использовании вложенных фрагментов мы не хотим, чтобы каждая внутренняя замена фрагмента уходила во внешнюю большую часть деятельности. Может быть полезен механизм, позволяющий фрагменту уведомлять своего родителя о том, что он хочет перейти на другой фрагмент.

Вот мой код на Kotlin, я думаю, что это легко перевести на Java.

interface FragmentNavigator {
    fun navigateTo(fragment: Fragment)
}

class NavigableFragment: Fragment() {
    var navigator: FragmentNavigator? = null
    override fun onDetach() {
        super.onDetach()
        navigator = null
    }
}

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

navigator?.navigateTo(anotherFragment)

Внешние действия или фрагменты должны реализовывать FragmentNavigator и переопределять navigateTo.

override fun navigateTo(fragment: Fragment) {
    supportFragmentManager.beginTransaction().replace(view_id, fragment).commit()
}

//Use childFragmentManager instead of supportFragmentManager a fragment

Наконец, во внешних действиях или фрагментах переопределите onAttachFragment

override fun onAttachFragment(fragment: Fragment?) {
    super.onAttachFragment(fragment)
    if(fragment is NavigableFragment) {
        fragment.navigator = this
    }
}