Android получить все view

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

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

— научимся обращаться из кода к View-элементам на экране и менять их свойства

Project name: P0081_ViewById
Build Target: Android 2.3.3
Application name: ViewById
Package name: ru.startandroid.develop.viewbyid
Create Activity: MainActivity

Чтобы обратиться к элементу экрана из кода, нам нужен его ID. Он прописывается либо в Properties, либо в layout-файлах, как вам удобнее. Для ID существует четкий формат — @+id/name, где + означает, что это новый ресурс и он должен добавиться в R.java класс, если он там еще не существует.

Давайте откроем main.xml, для TextView укажем и сохраним

Теперь откроем R.java и видим, что для класса id появилась константа myText. Т.е. чтобы к ней обратиться, надо написать R.id.myText.

Она связана с элементом TextView и мы можем ее использовать, чтобы обратиться к элементу программно. Для этого нам понадобится метод findViewById. Он по ID возвращает View. Давайте напишем вызов этого метода. Напомню, что пока мы пишем наш код в методе onCreate. Это метод, который вызывается при создании Activity. Если вдруг непонятно, куда писать, можно подсмотреть в конец урока, там я выложил код.

Откроем MainActivity.java и после строки с вызовом метода setContentView напишем:

Если View подчеркнуто красным, то скорей всего этот класс не добавлен в секцию import. Нажмите CTRL+SHIFT+O для автоматического обновления импорта.

Теперь myTextView (типа View) – это наш TextView на экране. Но тип View – это предок для TextView (и остальных View-элементов). И он нам не подходит, если мы хотим проделывать операции соответствующие TextView. Поэтому нам необходимо преобразование View в TextView. Изменим наш код на следующий:

Теперь myTextView имеет тип TextView, а результат метода findViewById мы преобразуем из View в TextView. Теперь мы можем применять к myTextView методы класса TextView. Для примера возьмем метод setText. Сейчас отображаемый текст = Hello World, MainActivity!. Мы его программно поменяем на New text in TextView

Сохраняем, запускаем (CTRL+F11) и видим, что текст изменился

Добавим на экран кнопку (Button), текст оставим по умолчанию. Сохраняем — CTRL+SHIFT+S (если не сохранить, то в R.java не появится ID).

Обратите внимание, что у меня совпадает имя объекта и ID

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

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

Мы поменяли параметр Enabled. Теперь на кнопку нельзя нажать. Сохраним, запустим и убедимся.

Добавим CheckBox, По умолчанию галочка не стоит. Давайте поставим ее программно, для этого используется метод setChecked, который меняет параметр Checked.

Запустив приложение видим, что код сработал.

Как видите – все несложно. Используем метод findViewById, чтобы по ID получить объект соответствующий какому-либо View-элементу (Button, TextView, CheckBox) и далее вызываем необходимые методы объектов (setText, setEnabled, setChecked).

В итоге должен получиться такой код:

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

— научимся обрабатывать нажатие кнопки

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

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

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

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

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

Источник

Android | Получить все дочерние элементы ViewGroup

getChildAt(i) получает только прямых потомков ViewGroup , возможно ли получить доступ ко всем потомкам без выполнения вложенных циклов?

7 ответов

Если вы хотите получить все дочерние представления, а также представления внутри дочерних ViewGroups , вы должны сделать это рекурсивно, поскольку в API нет возможности сделать это из коробки.

Это даст вам ArrayList со всеми представлениями в иерархии, которые вы затем можете перебирать.

По сути, этот код вызывает сам себя, если находит другую ViewGroup в иерархии, а затем возвращает ArrayList для добавления в более крупный ArrayList.

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

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

Читайте также:  Igo primo для android 4pda

Пара быстрых тестов (ничего формального) показывают, что эта альтернатива также работает быстрее, хотя, скорее всего, это связано с количеством новых экземпляров ArrayList , создаваемых другим ответом. Кроме того, результаты могут отличаться в зависимости от того, насколько вертикальна / горизонтальна иерархия представлений.

Для тех, кто использует androidx и kotlin

1 — Итерировать через ViewGroup , используя forEach<>

Если вы хотите перебрать все дочерние представления, вы можете использовать предопределенное расширение kotlin forEach в любой ViewGroup. Пример:

yourViewGroup.forEach < childView ->// do something with this childView >

2 — Вернуть список childViews, используя .children.toList в ViewGroup

Чтобы вернуть список Views , вы можете использовать функцию children , чтобы вернуть Sequence , а затем использовать toList() , чтобы преобразовать его в List . Пример:

val yourChildViewsList: List = yourViewGroup.children.toList()

Я рекурсивно реализовал этот метод. Не уверен, что он быстрее, чем у MH, но, по крайней мере, у него нет дубликатов.

Ответ MH включает в себя родительское представление, которое передается методу, поэтому я создал этот вспомогательный метод (который и будет вызван).

Я имею в виду, что если вы вызываете этот метод в TextView (у которого нет дочерних элементов), он возвращает 0 вместо 1.

TL; DR: чтобы подсчитать все дочерние элементы, скопируйте и вставьте оба метода, вызовите getAllChildren ()

Я не знаю, хорошо это или нет. Просто переопределите метод onViewAdded (View child) и просто добавьте представления в List . Дайте ему мысли. By docs. Это полезно при написании настраиваемой группы представлений.

Вызывается, когда к этой ViewGroup добавляется новый дочерний элемент. Переопределения всегда должны вызывать super.onViewAdded.

Вот мое (рекурсивное) решение, которое распечатывает иерархию следующим образом:

Недавно у меня была такая же проблема, и я решил ее с помощью функций расширения Kotlin , например:

Источник

Русские Блоги

Подробное объяснение Android Custom View

Один, пользовательский вид основания

1. Классификация

Есть несколько способов реализовать пользовательский вид:

  • Пользовательский комбинированный элемент управления: несколько элементов управления объединены в новый элемент управления, который удобен для многократного использования
  • Inherit system View control: наследовать от системных элементов управления, таких как TextView, и расширять основные функции системных элементов управления
  • Наследовать представление: не использовать повторно логику управления системой, наследовать представление для определения функции
  • Наследовать систему ViewGroup: наследовать от системных элементов управления, таких как LinearLayout, и расширять основные функции системных элементов управления
  • Наследовать ViewGroup: не повторно использовать логику управления системой, наследовать ViewGroup для определения функции
2. Просмотр процесса рисования

Рисование View в основном завершается тремя функциями measure (), layout (), draw ()

функция эффект Родственные методы
measure() Измерьте ширину и высоту просмотра measure(),setMeasuredDimension(),onMeasure()
layout() Рассчитать положение текущего вида и дополнительного вида layout(),onLayout(),setFrame()
draw() Посмотреть рисунок работы draw(),onDraw()
3. Система координат

В системе координат Android верхний левый угол экрана используется как начало координат, начало координат — это положительная ось оси X вправо, а положительная ось оси Y направлена ​​вниз. Следующее:

В дополнение к системе координат Android есть также система координат View. Внутренние отношения системы координат View показаны на рисунке:

Вид получает свою высоту

Высота просмотра может быть рассчитана из приведенного выше изображения:

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

Посмотреть собственные координаты

Расстояние от View до его родительского элемента управления можно получить следующим способом.

  • getTop (); Получить расстояние от View до верхнего края его родительского макета.
  • getLeft (); Получить расстояние от View слева от его родительского макета.
  • getBottom (); Получить расстояние от View до нижнего края его родительского макета.
  • getRight (); Получить расстояние от View справа от его родительского макета.
4. Конструктор

Унаследуем ли мы системное представление или непосредственно наследуем представление,Все нужно переписать конструктор, есть несколько конструкторов, хотя бы один должен быть переписан, Если мы создадим новый TestView,

5. Пользовательские свойства

Элементы управления системой Android, которые начинаются с android, — это все атрибуты, которые поставляются с системой. Чтобы упростить настройку пользовательских свойств представления, мы также можем настроить значения свойств.
Пользовательские атрибуты Android можно разделить на следующие шаги:

  • Настроить вид
  • Запишите значения / attrs.xml, напишите в нем стилизованные теги и элементы
  • View использует пользовательские атрибуты в файле макета (обратите внимание на пространство имен)
  • Получено TypedArray в конструкторе View
Примеры
  • Файл декларации для пользовательских атрибутов
  • Класс Custom View
  • Используется в файлах макета
Тип значения атрибута

(1). Ссылка: ссылка на идентификатор ресурса

  • Определение свойства:
  • Использование атрибутов:

(2). Цвет: значение цвета

  • Определение свойства:
  • Использование атрибутов:

(3). Логическое значение: логическое значение

  • Определение свойства:
  • Использование атрибутов:

(4). Измерение: значение измерения

  • Определение свойства:
  • Использование атрибутов:

(5). Float: значение с плавающей точкой

  • Определение свойства:
  • Использование атрибутов:

(6). Integer: целочисленное значение

  • Определение свойства:
  • Использование атрибутов:

(7). Строка: строка

  • Определение свойства:
  • Использование атрибутов:
  • Определение свойства:
  • Использование атрибутов:

(9). Enum: значение перечисления

  • Определение свойства:
  • Использование атрибутов:

Примечание. Одновременно может использоваться только один из атрибутов типа перечисления, но не android: ориентация = «горизонтальный | вертикальный»

(10). Flag: побитовое ИЛИ операция

  • Определение свойства:
  • Использование атрибутов:

Примечание. Атрибут типа битовой операции может использовать несколько значений в процессе использования.

(11). Смешанные типы: во время определения атрибута можно указать несколько типов значений

  • Определение свойства:
  • Использование атрибутов:

Во-вторых, процесс рисования View

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

Рисование View в основном завершается тремя функциями measure (), layout (), draw ()

функция эффект Родственные методы
measure() Измерьте ширину и высоту просмотра measure(),setMeasuredDimension(),onMeasure()
layout() Рассчитать положение текущего вида и дополнительного вида layout(),onLayout(),setFrame()
draw() Посмотреть рисунок работы draw(),onDraw()
1、Measure()
MeasureSpec

MeasureSpec — это внутренний класс View, который инкапсулирует размер View. В onMeasure () ширина и высота View будут определяться в соответствии со значением этого MeasureSpec.

Значение MeasureSpec хранится в значении int. Значение int имеет 32 бита, и первые два бита представляют режим, а последние 30 бит представляют размер. Это MeasureSpec = mode + size.

В MeasureSpec есть три режима: НЕУТОЧНО, ТОЧНО и
AT_MOST。

Для View режим и размер MeasureSpec имеют следующие значения:

Режим значение соответствовать
EXACTLY Точный режим, View требуется точное значение, это значение Size в MeasureSpec match_parent
AT_MOST В максимальном режиме размер представления имеет максимальное значение, и представление не может превышать значение размера в MeasureSpec. wrap_content
UNSPECIFIED Без ограничений, просмотр не имеет ограничений по размеру, так как размер должен быть Общая система внутреннего использования
  • Как пользоваться

В View код измерения MeasureSpace выглядит следующим образом:

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

Из исходного кода видно, что режим измерения дочернего представления определяется его собственным LayoutParam и MeasureSpec родительского представления.

onMeasure()

Вход всего процесса измерения находится в методе измерения View. Этот метод вызывает метод onMeasure после инициализации некоторых параметров. Здесь мы в основном анализируем onMeasure.

Исходный код метода onMeasure выглядит следующим образом:

Это очень просто: есть только одна строка кода, и мы проанализируем каждый из трех задействованных методов.

  • setMeasuredDimension (int measureWidth, int measureHeight): этот метод используется для установки ширины и высоты представления, которое часто используется при настройке представления.
  • getDefaultSize (int size, int measureSpec): Этот метод используется для получения ширины и высоты представления по умолчанию в сочетании с исходным кодом.
  • getSuggestedMinimumWidth (): принцип getHeight такой же, как у этого метода, здесь анализируется только этот.

Процесс измерения ViewGroup немного отличается от процесса View, он наследуется от View и не переписывает метод измерения и метод onMeasure для View.

Почему вы не переписали на Measure? В дополнение к измерению его ширины и высоты ViewGroup также необходимо измерить размер каждого подэкрана, и разные методы измерения макета также различны (см. LinearLayout и FrameLayout), поэтому не существует способа для равномерной настройки. Следовательно, он предоставляет методы measureChildren () и measureChild () для измерения вложенного представления, чтобы помочь нам измерить вложенное представление.

Исходный код measureChildren () и measureChild () здесь не будет анализироваться. Общий процесс состоит в том, чтобы обойти все дочерние представления, а затем вызвать метод представления view (), чтобы позволить дочернему представлению измерить его размер. Конкретный процесс измерения также был представлен выше

Процесс измерения будет представлять разные формы из-за разных макетов или разных требований. При его использовании вы должны проанализировать его в соответствии с бизнес-сценарием. Если вы хотите продолжить изучение, вы можете взглянуть на метод onMeasure LinearLayout.

2、 Layout()

Чтобы вычислить позицию, мы должны сначала понять систему координат Android. Мы также представили предыдущий контент.

Процесс layout () используется View для вычисления параметров положения View. Для ViewGroup, помимо измерения своей собственной позиции, необходимо также измерить положение дочернего View.

Метод layout () является входом всего процесса Layout (). Взгляните на эту часть исходного кода:

Из исходного кода мы знаем, что в методе layout () положение самого View было установлено методом setOpticalFrame (l, t, r, b) или setFrame (l, t, r, b), поэтому onLayout (change, l , t, r, b) Метод в основном рассчитывает положение дочернего View по ViewGroup.

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

3、 Draw()

Процесс рисования — это процесс рисования Представления на экране. Запись всего процесса осуществляется в методе рисования () Представления, и комментарии к исходному коду также четко написаны. Весь процесс можно разделить на 6 шагов.

  • При необходимости нарисуйте фон.
  • Необходимо было сохранить текущий холст.
  • Нарисуйте содержимое просмотра.
  • Нарисуй детский вид.
  • При необходимости нарисуйте такие эффекты, как края и тени.
  • Нарисуйте украшения, такие как полосы прокрутки и так далее.

Затем проанализируйте исходный код каждого шага:

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

Три, пользовательские комбинации элементов управления

Пользовательский комбинированный элемент управления предназначен для объединения нескольких элементов управления в новый элемент управления, который в основном решает проблему многократного использования одного и того же типа макета. Например, HeaderView и dailog наверху, мы можем объединить их в новый элемент управления.

Мы используем пользовательский экземпляр HeaderView для понимания использования пользовательских комбинированных элементов управления.

Макет прост: текст заголовка посередине, кнопка «Назад» слева и кнопка «Добавить» справа.

  1. Реализовать метод строительства
  1. Инициализировать интерфейс
  1. Предоставить внешние методы

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

  1. Ссылка на элемент управления в макете

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

Я кратко представил соответствующие знания о пользовательских атрибутах прежде, давайте посмотрим на код между нами

1. Сначала создайте attrs.xml в каталоге значений

Содержание выглядит следующим образом:

Здесь мы определяем три атрибута, текстовое содержимое, цвет и элементы для отображения.

2. Установите в коде Java

3. Сделайте настройки в файле макета

Хорошо, здесь базовое определение всего представления завершено. Весь код YFHeaderView выглядит следующим образом

В-четвертых, наследовать системные элементы управления

Элементы управления системы наследования можно разделить на унаследованные подклассы View (такие как TextVIew и т. Д.) И наследующие подклассы ViewGroup (такие как LinearLayout и т. Д.). В соответствии с различными бизнес-потребностями способ реализации также будет совершенно другим. Вот относительно простая реализация, которая наследуется от View.

Бизнес-требования: установите фон для текста и добавьте горизонтальную линию в середине макета.

Поскольку эта реализация будет повторно использовать логику системы, в большинстве случаев мы хотим повторно использовать процессы onMeaseur и onLayout системы, поэтому нам нужно только переписать метод onDraw. Реализация очень проста.

Для рисования вида вам также необходимо понять использование Paint (), canvas и Path. Если вам неясно, вы можете немного понять его.

Реализация здесь относительно проста, потому что конкретная реализация будет тесно связана с бизнес-средой, вот только ссылка.

Пять, непосредственно наследовать вид

Прямое наследование View будет более сложным, чем в предыдущей реализации. В сценарии использования этого метода нет необходимости повторно использовать логику системного элемента управления. В дополнение к переписыванию onDraw необходимо переписать метод onMeasure.

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

  • Сначала определите метод построения и выполните некоторые операции инициализации
  • Перепишите метод draw, нарисуйте квадрат, обратите внимание, чтобы установить свойство padding.

Прежде чем мы поговорим о процессе измерения View, давайте посмотрим на исходный код этого шага.

В исходном коде View нет различий между двумя режимами AT_MOST и EXACTLY. То есть, View является абсолютно одинаковым в двух режимах wrap_content и match_parent, которые будут match_parent. Очевидно, это отличается от View, который мы обычно используем, поэтому Мы должны переписать метод onMeasure.

  • Переопределить метод onMeasure

Весь пользовательский код View выглядит следующим образом:

Весь процесс примерно такой, есть несколько моментов, которые нужно отметить при непосредственном наследовании View:

1. Обработайте атрибут padding в onDraw.
2. Атрибут wrap_content обрабатывается во время onMeasure.
3. Требуется как минимум один метод построения.

Шесть, наследовать ViewGroup

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

Примеры требований
Реализован скользящий макет, аналогичный Viewpager.

Существует много кодов, и мы объединяем анализ с комментариями.

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

Эта часть кода больше, чтобы облегчить чтение, комментарии делаются в коде.
После этого в XML-код вводится пользовательское представление

Ну, вы можете бежать, чтобы увидеть эффект.

Источник

Читайте также:  Лед уведомления для андроид
Оцените статью