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

Рисунок 1. Два фрагмента, отображаемые в различных конфигурациях для той же activity для различных размеров экрана. На большом экране, оба фрагмента находятся бок о бок, но телефоне только один фрагмент занимает экран, поэтому фрагменты должны заменять друг друга во время переходов пользователя.
FragmentManager класс предоставляет методы, которые позволяют добавлять, удалять и заменять фрагменты activity во время выполнения, чтобы создать динамический опыт.
[wpanchor id=»1″]
Добавление фрагмента к activity во время выполнения
Вместо определения фрагментов activity в файле макета, как показано в предыдущем уроке с<fragment> элементами — вы можете добавить фрагмент в activity во время выполнения activity . Это необходимо, если вы планируете изменять фрагменты в течение жизни вашей activity .
Для выполнения транзакции, такой как добавление или удаление фрагмента, необходимо использовать FragmentManager для создания FragmentTransaction, которая обеспечивает API для добавления, удаления, замены и выполнения других операций с фрагментами.
Если ваша деятельность позволяет удалять и заменять фрагменты, вы должны добавить начальный фрагмент(ы) для activity во время вызова onCreate() метода.
Важное правило при работе с фрагментами — особенно теми, которые вы добавляете во время выполнения — это то, что фрагмент должен иметь контейнер View в макете, в котором будет находиться макет фрагмента.
Следующий макет является альтернативой макета, показанного в предыдущем уроке , который показывает только один фрагмент. Для того чтобы заменить один фрагмент другим, макет activity включает в себя пустой FrameLayout , выступающий в роле контейнера фрагментов.
Обратите внимание, что имя файла такое же, как в файле макета из предыдущего урока, но каталог макета не имеет large спецификатора, так этот макет используется, когда экран устройства меньше, чем большой , потому что экран не вмещает оба фрагмента одновременно.
res/layout/news_articles.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />
Внутри вашей activity , вызов getSupportFragmentManager() для получения FragmentManagerиспользует API Библиотеки поддержки. Затем вызовите beginTransaction() для созданияFragmentTransaction и вызовите add() для добавления фрагмента.
Вы можете выполнить несколько операций с фрагментами activity используя тот жеFragmentTransaction. Когда вы будете готовы внести изменения, вы должны вызвать commit().
Например, вот как добавить фрагмент к предыдущему макету:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
HeadlinesFragment firstFragment = new HeadlinesFragment();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}
Поскольку фрагмент был добавлен в FrameLayout контейнер во время выполнения — вместо определения его в макете activity с помощью <fragment> элемента — activity может удалить фрагмент и заменить его другим.
[wpanchor id=»2″]
Замена одного фрагмента другим
Процедура замены фрагмента похожа на добавление, но необходимо вызвать replace() метод вместо add().
Имейте в виду, что при выполнении операции с фрагментами, таких как замена или удаление, очень часто является целесообразным разрешить пользователю переместиться назад и «отменить» изменения. Чтобы позволить пользователю перемещаться назад по операциям с фрагментами, необходимо вызвать addToBackStack() прежде чем вы вызвать commit для FragmentTransaction.
Примечание: Когда вы удаляете или заменяете фрагмент и добавляете эту операцию стек навигации назад, фрагмент, который удаляется, останавливается (но не разрушается). Если пользователь переходит обратно, чтобы восстановить фрагмент, он перезагружается. Если вы недобавляете операцию в стек возврата, то фрагмент разрушается, когда он удален или заменён.
Пример замены одного фрагмента другим:
// Create fragment and give it an argument specifying the article it should show ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); 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.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit();
addToBackStack() метод принимает необязательный строковый параметр, который определяет уникальное имя для операции. Имя не требуется, если вы не планируете выполнять специальные операции с фрагментами, используя FragmentManager.BackStackEntry API.