410013796724260
• Webmoney
R335386147728
Z369087728698
Вернуться к «Разработчикам Android»
Фрагменты в AndroidВключение в Android-приложение нескольких активностей (activity) не всегда может быть оправданным. Так, если для смартфонов с небольшими экранами использование разных Activity выглядит довольно неплохо, то на больших экранах (планшетах, телевизорах) окна Activity могут занимать небольшую часть экрана. Именно поэтому и появилась концепция фрагментов (Fragment). Fragment имеет небольшое схожество с Activity; у фрагмента есть свой жизненный цикл, во многом совпадающий с жизненным циклом активности. Пожалуй, это и есть единственное сходство с активностью. С жизненным циклом фрагмента можно познакомиться здесь. Фрагменты не являются заменой активности, поскольку они не могут существовать сами по себе. Фрагменты можно создать только внутри активностей. В составе активности имеется специальный менеджер фрагментов FragmentManager, который может контролировать все фрагменты и управлять ими. Т.е. фрагменты являются строительным материалом для разработки интерфейса приложения : можно по некоторому событию добавить в интерфейс новый фрагмент, удалить ненужный фрагмент или заменить один фрагмент на другой. Каждая activity может иметь несколько фрагментов. Фрагменты появились в Android начиная с версии API 11, позволяя разработчикам разрабатывать более гибкие пользовательские интерфейсы под устройства с разными размерами экранов, как это представлено на следующем рисунке. ![]() Плюсы по сравнению с использованием activity видны сразу :
Таким образом, фрагменты облегчают построение адаптивного интерфейса из «шаблонов», которые можно динамически отобразить на экране устройства, скрыть или заменить другим фрагментом. AndroidX Fragment LibraryПервоначально для старых устройств, в целях совместимости приложений, была создана специальная библиотека. Длительное время сосуществовали два класса Fragment для старых и для новых устройств, у которых названия методов и классов были очень похожи. При разработке нового и поддержке существующего приложения это приводило к путанице; в одном проекте смешивались два разных несовместимых класса. Спустя некоторое время от такого разделения фрагментов решили отказаться; класс для новых устройств признали deprecated, а класс из библиотеки поддержки старых устройств вошёл в состав библиотеки AndroidX. В настоящее время, чтобы использовать все функциональные возможности фрагментов, необходимо в проекте подключить AndroidX Fragment Library, которая располагается в отдельной библиотеке. Подключение библиотеки выполняется в файле модуля/проекта build.gradle (см. пример). ... dependencies { implementation "androidx.fragment:fragment:1.4.1" ... } Включение фрагмента в активностьВключить фрагмент в активность можно как статически, так и динамически. При статическом размещении фрагмента необходимо в шаблоне интерфейса активности (main_activity.xml) использовать тег <fragment>, при динамическом – контейнер <FrameLayout>. В следующем примере представлены секции статического и динамического включения фрагментов в интефейс активности. При статическом подключени фрагмента необходимо указать класс (android:name) и интерфейсный шаблон (tools:layout). С примером статического и динамического включения фрагментов в активность Вы можете познакомиться здесь. <fragment android:id="@+id/fragment1" android:name="com.example.FragmentExample1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" tools:layout="@layout/fragment_example1"> </fragment> <FrameLayout android:id="@+id/fragment2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"> </FrameLayout> Создание фрагментаКласс фрагмента должен наследовать androidx.fragment.app.Fragment. Существует подклассы фрагментов : ListFragment, DialogFragment, PreferenceFragment, WebViewFragment. В следующем скрипте представлен пример описания класса фрагмента. class FragmentExample extends Fragment { public FragmentExample() { super(R.layout.fragment_example); } } Фрагмент – это не картинка в интерфейсе, а набор необходимых компонентов для отображения некоторого контента и реализации заданной бизнес-логики. Как было отмечено выше, фрагмент также, как и активность, имеет свой жизненный цикл, на определенных этапах которого фрагмент может взаимодействовать с активностью и с другими фрагментами. В следующем примере представлен класс фрагмента с двумя методами жизненного цикла, которые вызываются системой. В методе onAttach фрагмент определяет «родительскую» активность (activity). В методе onCreateView класс фрагмента подключает к своей кнопке (определена в шаблоне) обработчик события onClick. import androidx.fragment.app.Fragment; import androidx.appcompat.app.AppCompatActivity; class FragmentExample extends Fragment { @Override public void onAttach(Context context) { super.onAttach(context); AppCompatActivity activity = null; if (context instanceof AppCompatActivity) { activity = (AppCompatActivity) context; } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = null; Button btn = null; view = inflater.inflate(R.layout.fragment1, null); button = (Button) view.findViewById(R.id.button); btn.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { // ... } }); return view; } }
Примечание FragmentManager, FragmentTransactionКласс android.app.FragmentManager предназначен для выполнения таких операций, как добавление, удаление и замену фрагментов, а также добавления этих операций (иначе называемых транзакциями) в стек (back stack). Чтобы внутри активности получить реализацию FragmentManager необходимо использовать метод getSupportFragmentManager(). Внутри фрагмента менеджер можно получить либо методом getChildFragmentManager() для дочерних объектов, либо методом getParentFragmentManager() родительской активности. Для непосредственного выполнения операций с фрагментами менджер FragmentManager использует android.app.FragmentTransaction. Ниже представлен код размещения фрагмента в интерфейсе активности. В примере параметр R.id.fragmentContainer определяет контейнер фрагмента типа FragmentLayout. Для добавления фрагмента в контейнер активности был использован метод add класса FragmentTransaction. Fragment1 fragment1 = ...; FragmentManager fragmentMgr ; FragmentTransaction fragmentTrans; fragmentMgr = getSupportFragmentManager(); fragmentTrans = fragmentMgr.beginTransaction(); fragmentTrans.add(R.id.fragmentContainer, fragment1); fragmentTrans.commit(); Чтобы удалить фрагмент из активности необходимо использовать метод remove(fragment). Ну, а если нужно заменить один фрагмент на другой необходимо использовать метод replace(container, fragment), как это представлено в следующем примере. Fragment2 fragment2 = ...; fragmentMgr = getSupportFragmentManager(); fragmentTrans = fragmentMgr.beginTransaction(); fragmentTrans.replace(R.id.fragmentContainer, fragment2); fragmentTrans.commit(); Таким образом, методы добавления add и замены replace в качестве параметров получают идентификатор контейнера и реализацию (класс) фрагмента. Метод удаления фрагмента remove(Fragment) – только фрагмент. BackStackКак было отмечено выше система позволяет сохранять манипуляции с фрагментами в BackStack, а кнопкой устройства Назад (стрелка на устройстве <) отменять. Также можно откатить транзакцию программно. Чтобы записать транзакцию в стек необходимо использовать метод addToBackStack. А чтобы вернуть её назад — метод popBackStackImmediate. addToBackStack (String name) fragmentMgr = getSupportFragmentManager(); fragmentTrans = fragmentMgr.beginTransaction(); fragmentTrans.add(R.id.fragmentContainer, fragment1); fragmentTrans.addToBackStack(null); fragmentTrans.commit(); popBackStackImmediate () fragmentMgr = getSupportFragmentManager(); fragmentTrans = fragmentMgr.beginTransaction(); fragmentMgr.popBackStackImmediate(); fragmentTrans.commit(); Более подробно о константах и методах класса FragmentTransaction можно прочитать в документации FragmentTransaction. |