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