Android как получить view

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

— рассмотрим взаимодействие между Activity и ее фрагментами

После размещения фрагмента, хотелось бы начать с ним взаимодействовать. Т.е. размещать View-компоненты и работать с ними, обращаться к фрагментам из Activity и наоборот. Попробуем это реализовать.

Для чистоты эксперимента будем работать с двумя фрагментами: статическим и динамическим.

Project name: P1061_FragmentActivity
Build Target: Android 4.1
Application name: FragmentActivity
Package name: ru.startandroid.develop.p1061fragmentactivity
Create Activity: MainActivity

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

Создаем layout и классы для двух фрагментов.

У фрагмента нет привычного для нас метода findViewById для поиска компонентов с экрана. Поэтому вызываем этот метод для View, которое будет содержимым фрагмента. В методе onCreateView мы создаем View и сразу же находим в нем кнопку и ставим ей обработчик. Затем отдаем View системе.

Все аналогично Fragment1.

Настраиваем основное Activity.

Кнопка, компонент fragment, в который помещен Fragment1, и контейнер FrameLayout, в который потом поместим Fragment2.

Обратите внимание на атрибут tools:layout. В нем указан layout-файл, и мы можем на этапе разработки видеть, как будет выглядеть статический фрагмент, когда приложение будет запущено.

Для этого надо нажать правой кнопкой на компоненте fragment, и через пункт Fragment Layout указать нужный layout.

Здесь мы просто добавляем Fragment2 в контейнер.

Все сохраняем, запускаем приложение.

Жмем кнопку Log в первом фрагменте и смотрим лог:

Button click in Fragment1

Жмем Log во втором фрагменте:

Button click in Fragment2

Все ок. Компоненты в фрагментах нашлись и обработчики среагировали на нажатия.

Атрибут onClick, который мы привыкли использовать для кнопки, здесь не прокатит. Указанный в этом атрибуте метод, будет вызван в Activity, а не в фрагменте.

Доступ к фрагменту из Activity

Разберемся, как получить доступ к фрагменту из Activity. Для этого у FragmentManager есть метод findFragmentById, который на вход принимает id компонента fragment (если фрагмент статический) или id контейнера (если динамический).

У нас в main.xml есть кнопка btnFind, вызывающая метод onClick при нажатии. Дорисуем в MainActivity.java метод onClick:

Используем метод findFragmentById. В первом случае на вход передаем id компонента fragment, т.к. Fragment1 у нас размещен именно так. При поиске Fragment2 указываем id контейнера, в который этот фрагмент был помещен. В результате метод findFragmentById возвращает нам объект Fragment.

Далее мы получаем доступ к его View с помощью метода getView, находим в нем TextView и меняем текст.

Все сохраняем, запускаем. Жмем кнопку Find

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

На всякий случай проговорю одну вещь из разряда «Спасибо кэп!». Если посмотреть на код MainActivity, то можно заметить, что работая с frag2 в методе onCreate и с frag2 в методе onClick мы работаем с текущим фрагментом Fragment2. Это так и есть. Оба frag2 в итоге будут ссылаться на один объект. Так что, если вы динамически добавили фрагмент, то у вас уже есть ссылка на него, и искать его через findFragmentById вам уже не надо.

Доступ к Activity из фрагмента

Теперь попробуем из фрагмента поработать с Activity. Для этого фрагмент имеет метод getActivity.

Давайте перепишем обработчик кнопки в первом фрагменте. Будем менять текст кнопки btnFind.

Получаем Activity методом getActivity, ищем в нем кнопку и меняем текст.

Читайте также:  Мобильная разработка под android уроки

Сохраняем, запускаем. Жмем кнопку в первом фрагменте:

Работает. Из фрагмента мы поменяли компонент Activity.

Обработка в Activity события из фрагмента

Рассмотрим механизм, который описан в хелпе: фрагмент генерирует некое событие и ставит Activity обработчиком.

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

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

Тут немного отвлекусь на небольшое лирическое отступление. Модульность, вообще, — очень важная и полезная штука. И ее надо использовать для универсальности, удобности и легкости в понимании работы своих приложений. Но уникальных рецептов, как правильно все организовать, конечно, нет. Каждый делает по-своему. Именно по этим причинам я в своих уроках даю чисто технические вещи про отдельные компоненты и не рассказываю, как организовывать и писать целое приложение. Иначе, форум бы уже ломился от сообщений, что я все делаю не так и надо по-другому, и каждый бы излагал свое видение. И была бы куча споров, где одна сторона говорит, что крокодил зеленый, а другая сторона говорит, что он нифига не зеленый, а длинный ))

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

Описываем интерфейс onSomeEventListener. В нем метод someEvent, который на вход получает строку. Этот интерфейс будет реализовывать Activity.

В методе onAttach мы на вход получаем Activity, к которому присоединен фрагмент. Мы пытаемся привести это Activity к типу интерфейса onSomeEventListener, чтобы можно было вызывать метод someEvent и передать туда строку. Теперь someEventListener ссылается на Activity.

Далее, в onCreateView, в обработчике кнопки мы вызываем метод someEvent и передаем туда текст. Этот метод будет отработан в Activity.

Теперь меняем Activity.

Дописываем интерфейс onSomeEventListener к описанию класса.

onCreate без изменений.

Реализуем метод someEvent. Просто ищем первый фрагмент и вставляем туда текст.

Все сохраняем и запускаем. Жмем кнопку во втором фрагменте:

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

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

— размещаем элементы в ActionBar

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

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

Читайте также:  Android тупит что делать

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

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

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

Источник

Доступ к View внутри фрагмента

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

Доступ к View внутри динамического фрагмента из активности

Рассмотрим пример доступа к компоненту, который находится внутри динамического фрагмента из активности.

Фрагмент может иметь собственную разметку и содержать различные компоненты View: TextView, EditText и т.д. Напрямую из активности обратиться к нужному компоненту и поменять, например, текст в TextView не получится. А как же достучаться до нужного компонента? Рассмотрим простой пример.

Создадим класс фрагмента MyFragment.java:

В методе onCreateView() мы указали ресурс разметки R.layout.fragmentlayout. Давайте создадим разметку для фрагмента.

res/layout/fragmentlayout.xml

В данной разметке нас интересует вторая текстовая метка с идентификатором fragmenttext.

Создадим разметку для основной активности:

Последняя компоновка LinearLayout с идентификатором myfragment является контейнером для фрагмента, который будет его замещать. Напишем код для главной активности:

При запуске программы мы получаем экземпляр класса FragmentTransaction и добавляем фрагмент на экран вместо LinearLayout. Теперь текстовая метка фрагмента доступна для изменения — получаем ссылку на нужный компонент и устанавливаем требуемый текст.

Передача данных между фрагментами

Когда мы заменяем контейнер своим фрагментом, то он становится частью активности и получаем доступ к компонентам стандартным способом, как в примере выше. Если мы используем фрагменты как самостоятельные элементы, то доступ к компонентам происходит немного по-другому. Так как фрагменты не существуют сами по себе, а только внутри активности, то сначала нужно получить доступ к родительской активности через метод getActivity(), а затем уже можно получить доступ к нужному компоненту из фрагмента:

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

res/layout/redfragment.xml

res/layout/bluefragment.xml

В код первого фрагмента добавим только наполнение из разметки:

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

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

Источник

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

В этом уроке мы:

— добавляем компоненты на экран прямо из приложения

На прошлом уроке мы создавали компоненты в методе Activity.onCreate, т.е. при создании приложения. На этом уроке будем создавать уже в работающем приложении. Создавать будем Button-ы, т.к. они наглядней всего отображаются. Будем указывать текст, который будет отображен на кнопке и выравнивание: слева, по центру или справа. Также предусмотрим возможность удаления созданных элементов.

Project name: P0171_DynamicLayout2
Build Target: Android 2.3.3
Application name: DynamicLayout2
Package name: ru.startandroid.develop.dynamiclayout2
Create Activity: MainActivity

Создадим экран, который поможет нам создавать View-компоненты. Открываем main.xml и пишем там следующее:

Рассмотрим подробно экран.

rgGravity – это RadioGroup, с тремя RadioButton (rbLeft, rbCenter, rbRight). Этот компонент мы используем для выбора выравнивания создаваемого компонента
etName – текстовое поле, здесь будем указывать текст, который будет отображаться на созданном компоненте
btnCreate – кнопка, запускающая процесс создания.
btnClear – кнопка, стирающая все, что создали
llMain – вертикальный LinearLayout, в котором будут создаваться компоненты

Читайте также:  Андроид будильник не срабатывает почему иногда

Экран готов, давайте кодить реализацию. Открываем MainActivity.java. Начнем с того, что опишем и найдем все необходимые нам компоненты. Кстати, у нас есть пара кнопок, которые мы будем использовать, значит им нужен обработчик. В качестве обработчика назначим Activity (т.е. необходимо дописать: implements OnClickListener) и создадим пустой пока метод обработки onClick:

Я также создал переменную wrapContent и буду хранить в ней значение LinearLayout.LayoutParams.WRAP_CONTENT. Делаю это только для снижения громоздкости кода.

Теперь опишем процесс создания Button-компонента заполнив метод onClick:

Разберем написанное. Для начала мы проверяем, что была нажата кнопка btnCreate – т.е. кнопка создания. Затем создаем LayoutParams с высотой и шириной по содержанию. Здесь я использовал переменную, про которую писал выше – wrapContent. Иначе получилось бы довольно громоздко.

Далее создаем переменную btnGravity, в которую по умолчанию запишем значение выравнивания LEFT. Для определения, какой RadioButton выделен в данный момент, используем метод getCheckedRadioButtonId – он для RadioGroup возвращает ID «чекнутого» RadioButton-а. Мы его сравниваем с нашими тремя ID и заносим соответствующее значение в переменную btnGravity. Скидываем это значение в gravity у LayoutParams.

Далее создаем кнопку и присваиваем ей текст из etName. Обратите внимание, что недостаточно написать getText, т.к. это не даст текста. Необходимо еще вызвать метод toString. Ну и в конце добавляем созданный Button в наш LinearLayout.

Сохраним все и запустим приложение. Добавим несколько кнопок.

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

Когда вводите текст, снизу появляется клавиатура и закрывает обзор. Чтобы она исчезла, надо нажать кнопку Back (Назад) на эмуляторе или ESC на обычной клавиатуре. Если клавиатура появляется японская с иероглифами, вызовите контекстное меню для поля ввода (долгое нажатие левой кнопкой мыши), нажмите Input method и выберите из списка Android Keyboard.

Осталось нереализованной кнопка Clear, которая призвана удалять все созданное. Для этого нам необходимо дополнить метод onClick, добавим в switch ( v.getId ()) еще один case:

Метод removeAllViews удаляет все дочерние View-компоненты с нашего LinearLayout. С помощью Toast выводим на экран сообщение об успехе. Сохраним, запустим и проверим. Добавляем несколько кнопок, жмем кнопку Clear и наблюдаем результат:

В итоге у нас получилось очень даже динамическое приложение, которое умеет менять само себя.

На форуме задают вопрос: как потом получить доступ к этим созданным компонентам. Тут есть пара простых вариантов.

1) При создании вы можете сами присваивать компонентам ID. Это делается методом setId . И потом по этим ID просто вызываете findViewById.

2) Вы можете сохранять созданные компоненты в свой массив или список. Либо можете воспользоваться методом getChildAt. Вызов этого метода для llMain позволит получить его дочерние компоненты по индексу. Получить кол-во дочерних элементов позволит метод getChildCount.

Полный код урока:

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

— изменяем layout-параметры для уже существующих компонентов экрана

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

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

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

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

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

Источник

Оцените статью