Создать фрагмент,Создать фрагмент

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

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

Настройте свою среду

Фрагменты требуют зависимости от библиотеки фрагментов AndroidX . Вам необходимо добавить репозиторий Google Maven в файл settings.gradle вашего проекта, чтобы включить эту зависимость.

классный

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        ...
    }
}

Котлин

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        ...
    }
}

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

Groovy

dependencies {
    def fragment_version = "1.8.5"

    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
}

Kotlin

dependencies {
    val fragment_version = "1.8.5"

    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
}

Создать класс фрагмента

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

Котлин

class ExampleFragment : Fragment(R.layout.example_fragment)

Ява

class ExampleFragment extends Fragment {
    public ExampleFragment() {
        super(R.layout.example_fragment);
    }
}

Библиотека Fragment также предоставляет более специализированные базовые классы фрагментов:

DialogFragment
Отображает плавающее диалоговое окно. Использование этого класса для создания диалога является хорошей альтернативой использованию вспомогательных методов диалога в классе Activity , поскольку фрагменты автоматически обрабатывают создание и очистку Dialog . Дополнительные сведения см. в разделе Отображение диалогов с помощью DialogFragment .
PreferenceFragmentCompat
Отображает иерархию объектов Preference в виде списка. Вы можете использовать PreferenceFragmentCompat для создания экрана настроек для вашего приложения.

Добавить фрагмент в действие

Как правило, ваш фрагмент должен быть встроен в AndroidX FragmentActivity , чтобы внести часть пользовательского интерфейса в макет этого действия. FragmentActivity — это базовый класс для AppCompatActivity , поэтому, если вы уже создаете подкласс AppCompatActivity для обеспечения обратной совместимости в своем приложении, вам не нужно менять базовый класс активности.

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

Добавить фрагмент через XML

Чтобы декларативно добавить фрагмент в XML-макет вашего действия, используйте элемент FragmentContainerView .

Вот пример макета активности, содержащий один FragmentContainerView :

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.ExampleFragment" />

Атрибут android:name указывает имя класса Fragment , экземпляр которого требуется создать. Когда макет действия раздувается, создается экземпляр указанного фрагмента, для вновь созданного фрагмента вызывается onInflate() и создается FragmentTransaction для добавления фрагмента в FragmentManager .

Добавить фрагмент программно

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

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

В отличие от подхода XML, атрибут android:name здесь не используется в FragmentContainerView , поэтому автоматически не создается конкретный фрагмент. Вместо этого используется FragmentTransaction для создания экземпляра фрагмента и добавления его в макет действия.

Пока ваша деятельность выполняется, вы можете выполнять транзакции с фрагментами, такие как добавление, удаление или замена фрагмента. В вашем FragmentActivity вы можете получить экземпляр FragmentManager , который можно использовать для создания FragmentTransaction . Затем вы можете создать экземпляр своего фрагмента в методе onCreate() вашей активности с помощью FragmentTransaction.add() , передав идентификатор ViewGroup контейнера в вашем макете и класс фрагмента, который вы хотите добавить, а затем зафиксировать транзакцию, как показано в следующий пример:

Котлин

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState == null) {
            supportFragmentManager.commit {
                setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view)
            }
        }
    }
}

Ява

public class ExampleActivity extends AppCompatActivity {
    public ExampleActivity() {
        super(R.layout.example_activity);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.fragment_container_view, ExampleFragment.class, null)
                .commit();
        }
    }
}

Обратите внимание, что в предыдущем примере транзакция фрагмента создается только в том случае, если savedInstanceState имеет значение null . Это необходимо для того, чтобы фрагмент добавлялся только один раз при первом создании активности. Когда происходит изменение конфигурации и воссоздается действие, savedInstanceState больше не имеет null , и фрагмент не нужно добавлять второй раз, поскольку фрагмент автоматически восстанавливается из savedInstanceState .

Если вашему фрагменту требуются некоторые исходные данные, аргументы можно передать вашему фрагменту, указав Bundle в вызове FragmentTransaction.add() , как показано ниже:

Котлин

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState == null) {
            val bundle = bundleOf("some_int" to 0)
            supportFragmentManager.commit {
                setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view, args = bundle)
            }
        }
    }
}

Ява

public class ExampleActivity extends AppCompatActivity {
    public ExampleActivity() {
        super(R.layout.example_activity);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            Bundle bundle = new Bundle();
            bundle.putInt("some_int", 0);

            getSupportFragmentManager().beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.fragment_container_view, ExampleFragment.class, bundle)
                .commit();
        }
    }
}

Затем аргументы Bundle можно получить из вашего фрагмента, вызвав requireArguments() , а для получения каждого аргумента можно использовать соответствующие методы получения Bundle .

Котлин

class ExampleFragment : Fragment(R.layout.example_fragment) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val someInt = requireArguments().getInt("some_int")
        ...
    }
}

Ява

class ExampleFragment extends Fragment {
    public ExampleFragment() {
        super(R.layout.example_fragment);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        int someInt = requireArguments().getInt("some_int");
        ...
    }
}

См. также

Транзакции фрагментов и FragmentManager более подробно рассмотрены в руководстве по диспетчеру фрагментов .