метод класса fragment для проверки того что фрагмент виден пользователю

Фрагменты

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Существует два основных подхода в использовании фрагментов.

Первый способ основан на замещении родительского контейнера. Создаётся стандартная разметка и в том месте, где будут использоваться фрагменты, размещается контейнер, например, FrameLayout. В коде контейнер замещается фрагментом. При использовании подобного сценария в разметке не используется тег fragment, так как его нельзя менять динамически. Также вам придётся обновлять ActionBar, если он зависит от фрагмента. Здесь показан такой пример.

Второй подход является наиболее гибким и в целом предпочтительным способом использования фрагментов. Активность проверяет в каком режиме (свои размеры) он запущен и использует разную разметку из ресурсов. Графически это выглядит следующим образом.

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Основные классы

Сами фрагменты наследуются от androidx.fragment.app.Fragment. Существует подклассы фрагментов: ListFragment, DialogFragment, PreferenceFragment, WebViewFragment и др. Не исключено, что число классов будет увеличиваться, например, появился ещё один класс MapFragment.

Как в любом офисе, спецманагер не делает работу своими руками, а использует помощников. Например, для транзакций (добавление, удаление, замена) используется класс-помощник android.app.FragmentTransaction.

Для сравнения приведу названия классов из библиотеки совместимости:

Как видите, разница в одном классе, который я привёл первым. Он используется вместо стандартного Activity, чтобы система поняла, что придётся работать с фрагментами. На данный момент студия создаёт проект на основе ActionBarActivity, который является подклассом FragmentActivity.

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

В 2018 году Гугл объявила фрагменты из пакета androd.app устаревшими. Заменяйте везде на версию из библиотеки совместимости. В 2020 году уже используют пакет androidx.fragment.app.

В версии Support Library 27.1.0 появились новые методы requireActivity() и requireContext(), которые пригодятся при написании кода, когда требуется наличие активности и нужно избежать ошибки на null.

Общий алгоритм работы с фрагментами будет следующим:

У каждого фрагмента должен быть свой класс. Класс наследуется от класса Fragment или схожих классов, о которых говорилось выше. Это похоже на создание новой активности или нового компонента.

Разметку для фрагмента можно создать программно или декларативно через XML.

Создание разметки для фрагмента ничем не отличается от создания разметки для активности. Вот отрывок кода из метода onCreateView():

Глядя на этот код, вы должные понять, что фрагмент использует разметку из файла res/layout/first_fragment.xml, которая содержит кнопку с идентификатором android:id=»@+id/button_first». Здесь также прослеживается сходство с подключением компонентов в активности. Обратите внимание, что перед методом findViewById() используется view, так как этот метод относится к компоненту, а не к активности, как мы обычно делали в программах, когда просто опускали имя активности. Т.е. в нашем случае мы ищем ссылку на кнопку не среди разметки активности, а внутри разметки самого фрагмента.

Нужно помнить, что в методе inflate() последний параметр должен иметь значение false в большинстве случаев.

FragmentManager

Класс FragmentManager имеет два метода, позволяющих найти фрагмент, который связан с активностью:

findFragmentById(int id) Находит фрагмент по идентификатору findFragmentByTag(String tag) Находит фрагмент по заданному тегу

Методы транзакции

Мы уже использовали некоторые методы класса FragmentTransaction. Познакомимся с ними поближе

add() Добавляет фрагмент к активности remove() Удаляет фрагмент из активности replace() Заменяет один фрагмент на другой hide() Прячет фрагмент (делает невидимым на экране) show() Выводит скрытый фрагмент на экран detach() (API 13) Отсоединяет фрагмент от графического интерфейса, но экземпляр класса сохраняется attach() (API 13) Присоединяет фрагмент, который был отсоединён методом detach()

Методы remove(), replace(), detach(), attach() не применимы к статичным фрагментам.

Перед началом транзакции нужно получить экземпляр FragmentTransaction через метод FragmentManager.beginTransaction(). Далее вызываются различные методы для управления фрагментами.

В конце любой транзакции, которая может состоять из цепочки вышеперечисленных методов, следует вызвать метод commit().

Аргументы фрагмента

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

Фрагмент должен иметь только один пустой конструктор без аргументов. Но можно создать статический newInstance с аргументами через метод setArguments().

Доступ к аргументам можно получить в методе onCreate() фрагмента:

Динамически загружаем фрагмент в активность.

Вызываем метод в активности:

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

Управление стеком фрагментов

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

Если вы вызовете метод addToBackStack() при удалении или замещении фрагмента, то будут вызваны методы фрагмента onPause(), onStop(), onDestroyView().

Когда пользователь нажимает на кнопку возврата, то вызываются методы фрагмента onCreateView(), onActivityCreated(), onStart() и onResume().

Рассмотрим пример реагирования на кнопку Back в фрагменте без использования стека. Активность имеет метод onBackPressed(), который реагирует на нажатие кнопки. Мы можем в этом методе сослаться на нужный фрагмент и вызвать метод фрагмента.

Теперь в классе фрагмента прописываем метод с нужным кодом.

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

Интеграция Action Bar/Options Menu

Фрагменты могут добавлять свои элементы в панель действий или меню активности. Сначала вы должны вызвать метод Fragment.setHasOptionsMenu() в методе фрагмента onCreate(). Затем нужно задать настройки для методов фрагмента onCreateOptionsMenu() и onOptionsItemSelected(), а также при необходимости для методов onPrepareOptionsMenu(), onOptionsMenuClosed(), onDestroyOptionsMenu(). Работа методов фрагмента ничем не отличается от аналогичных методов для активности.

В активности, которая содержит фрагмент, данные методы автоматически сработают.

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

Код для активности:

Связь между фрагментом и активностью

Экземпляр фрагмента связан с активностью. Активность может вызывать методы фрагмента через ссылку на объект фрагмента. Доступ к фрагменту можно получить через методы findFragmentById() или findFragmentByTag().

Источник

Немного о Fragment

Добрый день Хабр, в этой статье я хочу рассказать о таком интересном элементе как Fragment, эта статья не научный прорыв, а просто небольшой туториал о использовании этого элемента. Всем, кому интересно узнать, что-то новое, прошу под кат.

Fragment — модульная часть activity, у которой свой жизненный цикл и свои обработчики различных событий. Android добавил фрагменты с API 11, для того, чтобы разработчики могли разрабатывать более гибкие пользовательские интерфейсы на больших экранах, таких как экраны планшетов. Через некоторое время была написана библиотека, которая добавляет поддержку фрагментов в более старые версии.

Основные классы

Есть три основных класса:
android.app.Fragment — от него, собственно говоря. и будут наследоваться наши фрагменты
android.app.FragmentManager — с помощью экземпляра этого класса происходит все взаимодействие между фрагментами
android.app.FragmentTransaction — ну и этот класс, как понятно по названию, нужен для совершения транзакций.
В настоящее время появляются разновидности класса Fragment, для решения определенных задач — ListFragment, PreferenceFragment и др.

Основы работы с fragment’ами

Чтобы создать фрагмент все что нужно это наследовать свой класс от Fragment. Чтобы привязать фрагмент к определенной разметке нужно определить в нем метод onCreateView(). Этот метод возвращает View, которому и принадлежит ваш фрагмент.

Чтобы получить это View из любого места фрагмента достаточно вызвать getView()

Фрагмент мы создали, но хотелось бы поместить его на экран. Для этого нам нужно получить экземпляр FragmentManager и совершить нужную нам транзакцию.
Сначала нужно узнать что мы с фрагментом можем сделать:
add() — добавление фрагмента
remove() — удаление фрагмента
replace() — замена фрагмента
hide() — делает фрагмент невидимым
show() — отображает фрагмент

Так же для того чтобы добавлять наши транзакции в стек, как это происходит по умолчанию с активностями, можно использовать addToBackStack(String), а чтобы вернуть предыдущее состояние стэка нужно вызвать метод popBackStack().

Добавим фрагмент на экран:

Как связать activity и fragment?

Чтобы вызывать методы активити, достаточно получить его экземпляр через метод getActivity()

Для того же чтобы получить доступ к фрагменту, у нас есть ссылка на объект фрагмента, которую мы создали при совершении транзакции

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

Покажу как это делается для второго варианта, так как для android более правильно использовать Parcel для передачи параметров между активностями и фрагментами.

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

Дальше нужно всего лишь получить переданный нами объект в методе onCreateView() нового фрагмента:

UPD. исправил получение объекта obj из getArguments(), спасибо firexel

Анимация фрагментов

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

Чтобы создать свою анимацию добавления и удаления фрагмента? нужно создать два файла в директории res/animator, один из них будет служить для анимации добавления, второй для удаления

Приведу пример одного из них:

Корневым элементом служит objectAnimator, его атрибуты и задают параметры анимации.
Теперь нам нужно вызвать метод setCustomAnimations() с нашими анимациями и при следующей транзакции наши фрагменты оживут.

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

Источник

Как получить отображаемый фрагмент?

Я играю с фрагментами в Android.

Я знаю, что могу изменить фрагмент, используя следующий код:

У меня вопрос в файле Java, как я могу получить отображаемый в данный момент экземпляр фрагмента?

ОТВЕТЫ

Ответ 1

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

. и позже, если вы хотите проверить, является ли фрагмент видимым:

Ответ 2

Я знаю, это старый пост, но раньше у меня тоже были проблемы. Нашел решение, которое должно было сделать это в функции прослушивания onBackStackChanged()

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

Ответ 3

Вот мое решение, которое я считаю удобным для сценариев с низким фрагментом

Ответ 4

Каждый раз, когда вы показываете фрагмент, вы должны поместить его в backstack:

И тогда, когда вам нужно получить текущий фрагмент, вы можете использовать этот метод:

Ответ 5

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

Ответ 6

Ответ 7

Мой метод основан на try/catch следующим образом:

Но может быть лучше.

Ответ 8

Ответ 9

Это немного поздно, но для всех, кто заинтересован: Если вам известен индекс вашего желаемого фрагмента в FragmentManager, просто получите ссылку на него и проверьте функцию isMenuVisible()! здесь:

Если true Его видимый для пользователя и т.д.

Ответ 10

Ответ 11

Вы можете запросить, какой фрагмент загружен в ваш фрейм контента «Деятельности», и получить класс фрагмента или фрагмент «простое имя» (в виде строки).

Ответ 12

Ответ 13

Вдохновленный Тайни, ответьте, вот мои два цента. Небольшое изменение от большинства других реализаций.

Замените «myActivity» на «this», если это ваша текущая деятельность или используйте ссылку на вашу активность.

Ответ 14

Ответ 15

Если попасть сюда и вы используете Kotlin:

Или, если вы хотите более хорошее решение:

Ответ 16

Ответ Sev работает, когда вы нажимаете кнопку «Назад» или иным образом меняете стоп-память.

Я сделал что-то немного другое. У меня есть функция прослушивателя изменений в backstack на базовом фрагменте и его фрагментах, и этот код находится в слушателе:

Ответ 17

Это простой способ получить текущий фрагмент.

Ответ 18

Это работа для меня. Надеюсь, что это кому-то поможет.

Ответ 19

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

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

Следующий метод не работает. Он просто получает фрагмент с тегом. Не тратьте время на этот метод. Я уверен, что он использует его, но для получения самой последней версии того же фрагмента не является одним из них.

Ответ 20

Оформить заказ на это решение. Это помогло мне получить текущий фрагмент.

Ответ 21

Ответ 22

В основной деятельности метод onAttachFragment (фрагмент фрагмента) вызывается, когда к этому активу присоединяется новый фрагмент. В этом методе вы можете получить экземпляр текущего фрагмента. Тем не менее, метод onAttachFragment не вызывается, когда фрагмент выталкивается с задней стороны, т.е. Когда нажата кнопка «Назад», чтобы получить верхний фрагмент поверх стека. Я все еще ищу метод обратного вызова, который запускается в основном действии, когда фрагмент становится видимым внутри действия.

Ответ 23

У меня возникла аналогичная проблема, где я хотел знать, какой фрагмент был последний раз отображен при нажатии клавиши назад. Я использовал очень простое решение, которое сработало для меня. Каждый раз, когда я открываю фрагмент, в методе onCreate() я устанавливаю переменную в моем одиночном элементе (заменим «myFragment» на имя вашего фрагмента)

Переменная объявляется в singleton как

Затем в onBackPressed() я проверяю

Обязательно вызовите super.onBackPressed(); после «возврата», иначе приложение обработает обратный ключ, который в моем случае заставил приложение завершить работу.

Ответ 24

В случае прокручиваемых фрагментов, когда вы используете экземпляр класса ViewPager, предположим, mVeiwPager, вы можете вызвать mViewPager.getCurrentItem() для получения текущего номера int фрагмента.

Ответ 25

Ну, я думаю, это самый прямой ответ на этот вопрос. Надеюсь, это поможет.

Ответ 26

Вот решение Kotlin:

Ответ 27

Если вы используете библиотеку поддержки v13, эта проблема исправлена, и вы должны просто переопределить:

Дело в том, что вы не можете их смешивать, потому что фрагмент не совместим с классом фрагментов версии 4.

Если вы этого не сделали, и вы используете библиотеку поддержки V4, переопределите метод setPrimaryItem для вашего FragmentStatePagerAdapter.

Я использовал это, чтобы обновить заголовок Actionbat в больших списках.

Ответ 28

Возможно, самый простой способ:

Это сработало для меня

Ответ 29

Использование шины событий (например Otto, EventBus или RxJava Bus) особенно удобно в этих ситуациях.

Хотя этот подход не обязательно передает вам видимый в данный момент фрагмент как объект (хотя это тоже можно сделать, но это приводит к более длинной цепочке вызовов), он позволяет выполнять действия над видимым в данный момент фрагментом (который обычно то, что вы хотите знать, в настоящее время видимый фрагмент).

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

Ответ 30

чтобы первый активный фрагмент использовал 0 в качестве индекса

Источник

Полный список

— используем фрагменты
— разбираемся в их lifecycle

Фрагменты – одно из главных новшеств Android 3. Можно рассматривать их как мини-Activity, которые располагаются в основном Activity и имеют свой lifecycle, немного отличающийся от обычного Activity. В этом уроке разместим пару фрагментов в Activity и разберемся в lifecycle-методах.

В 4-й версии фрагменты никуда не делись, а AVD для 3-й версии какие-то совсем суровые и тяжелые, поэтому для разработки и тестирования будем использовать версию Android 4.1 (API 16). Если у вас нет такой версии в списке доступных, то открывайте Window > Android SDK Manager и скачивайте ее там.

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Project name: P1041_FragmentLifecycle
Build Target: Android 4.1
Application name: FragmentLifecycle
Package name: ru.startandroid.develop.p1041fragmentlifecycle
Create Activity: MainActivity

В strings.xml добавим пару строк:

Создадим пару фрагментов. Для этого нам необходимо создать для них layout-файлы и классы с предком android.app.Fragment.

Создаем layout-файлы, как обычно.

Фрагменты будут содержать TextView с текстом, и мы сделали цветной фон для наглядности.

Теперь классы. Если Activity наследует android.app.Activity, то фрагменты наследуют android.app.Fragment.

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Заполняем код. Fragment1.java:

В обоих фрагментах просто выводим в лог вызовы всех lifecycle-методов. Чуть дальше рассмотрим эти методы подробнее.

В методе onCreateView система спрашивает у нас, что ей отображать внутри фрагмента. Мы сообщаем системе, что хотим видеть во фрагменте содержимое соответствующего layout-файла. Для этого мы сами создаем View с помощью inflater и отдаем его системе. Т.е. по смыслу это аналог метода setContentView, который мы вызываем в Activity. Только здесь нам приходится самим создавать View, а не просто передавать идентификатор layout-файла.

Все (layout и классы) для фрагментов готово. Можем поместить их в основной layout-файл Activity. Открываем main.xml, делаем корневым горизонтальный LinearLayout и помещаем в него пару элементов Fragment (вкладка Layouts). При этом появится диалог, в котором надо будет указать какой класс используется для фрагмента.

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Указываем для первого класс Fragment1, а для второго Fragment2.

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

В MainActivity.java также добавляем запись в лог всех lifecycle методов:

Все сохраняем. Далее, я сначала запустил эмулятор через AVD, повернул его в горизонтальную ориентацию, затем запустил приложение. Но, в принципе, можно все делать и в вертикальной ориентации. Скрин будет чуть другой, а логи те же.

метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть фото метод класса fragment для проверки того что фрагмент виден пользователю. Смотреть картинку метод класса fragment для проверки того что фрагмент виден пользователю. Картинка про метод класса fragment для проверки того что фрагмент виден пользователю. Фото метод класса fragment для проверки того что фрагмент виден пользователю

Все как и заказывали. В горизонтальном LinearLayout размещены пара фрагментов. Содержимое фрагментов взято из layout-файлов fragment1 и fragment2.

Fragment1 onAttach
Fragment1 onCreate
Fragment1 onCreateView
Fragment2 onAttach
Fragment2 onCreate
Fragment2 onCreateView
MainActivity onCreate
Fragment1 onActivityCreated
Fragment2 onActivityCreated
MainActivity onStart
Fragment1 onStart
Fragment2 onStart
MainActivity onResume
Fragment1 onResume
Fragment2 onResume

Первым делом для фрагментов вызываются методы:

onAttach – фрагмент прикреплен к Activity и получает ссылку на него. В дальнейшем мы всегда можем получить ссылку на Activity, вызвав метод getActivity().

onCreateView – здесь вы создаете View, который будет содержимым фрагмента, и отдаете его системе

Далее срабатывают метод Activity – onCreate, после него метод фрагментов onActivityCreated – сообщает фрагменту о том, что Activity создано и можно работать с UI-элементами

Далее метод Activity – onStart, после него onStart – аналогичен методу Activity, фрагмент виден пользователю

Жмем кнопку назад – закрываем приложение:

Fragment1 onPause
Fragment2 onPause
MainActivity onPause
Fragment1 onStop
Fragment2 onStop
MainActivity onStop
Fragment1 onDestroyView
Fragment1 onDestroy
Fragment1 onDetach
Fragment2 onDestroyView
Fragment2 onDestroy
Fragment2 onDetach
MainActivity onDestroy

Сначала для фрагментов и Activity вызываются методы onPause и onStop. Это значит, что фрагменты и Activity более недоступны для взаимодействия, а потом не видны пользователю.

Затем для фрагментов вызываются три метода по уничтожению:

onDestroyView – сообщает нам, что View, которое мы создавали в onCreateView, более недоступно

onDestroy – аналог метода onDestroy у Activity

onDetach – фрагмент отсоединен от Activity

И в конце вызывается метод onDestroy для Activity.

Т.е. основные lifecycle методы схожи для Activity и фрагмента. Но есть и некоторые различия, связанные с привязкой фрагмента к Activity.

Фрагменты, так же как и Activity могут сохранять данные при своем пересоздании, например при смене экрана. Для записи используется метод onSaveInstanceState. А прочесть данные можно из Bundle в методах onCreate, onCreateView или onActivityCreated.

А чтобы при пересоздании сохранить сам объект класса Fragment, используйте метод setRetainInstance. Если передать в него true, то при пересоздании фрагмента не будут вызваны методы onDestroy и onCreate, и не будет создан новый экземпляр класса Fragment.

На следующем уроке:

— динамически работаем с фрагментами

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *