Как программно добавлять представления в представления
179
Допустим, у меня есть LinearLayoutи я хочу добавить к нему представление в моей программе из кода Java. Какой метод используется для этого? Я не спрашиваю, как это делается в XML, который я знаю, но, скорее, как я могу сделать что-то вроде этого примера кода?
Вызов addViewявляется правильным ответом, но вам нужно сделать немного больше, чтобы заставить его работать.
Если вы создаете представление с помощью конструктора (например, Button myButton = new Button();), вам необходимо вызвать setLayoutParamsвновь созданное представление, передавая экземпляр внутреннего класса LayoutParams родительского представления, прежде чем добавить вновь созданный дочерний элемент в родительское представление.
Например, вы могли бы иметь следующий код в своей onCreate()функции, предполагая, что ваш LinearLayout имеет идентификатор R.id.main:
Важно установить LayoutParams. Каждому представлению требуется как минимум layout_width и параметр layout_height. Также важно получить правильный внутренний класс. Я изо всех сил пытался заставить представления, добавленные в TableRow, отображаться правильно, пока не выяснил, что я не передавал экземпляр TableRow.LayoutParams в setLayoutParams дочернего представления.
Как бы вы создали представление программно, используя файл макета XML, который вы специально написали для этого нового представления?
SK9
9
@ SK9 Вы бы использовали LayoutInflater, который вы можете получить из контекста, обычно текущей деятельности. Что-то вроде: LayoutInflater myInflater = getLayoutInflater; View myView = myInflater.inflate (R.layout.myLayout, parent, false);
Брайан Кули
1
На самом деле getLayoutInflater () происходит из класса Window (не Context), и это удобный метод в Activity.
Брайан Кули
2
В качестве практики кодирования для findViewById приведите к ViewGroup или всегда к наиболее общей форме объекта, чтобы в случае его изменения с LinearLayout на RelativeLayout у вас не было рефакторинга.
Джоэл Тепли
1
Вот некоторые детали: D
Вивек Соланки,
51
для всех, кто еще заинтересован:
лучший способ, который я нашел, - использовать статический метод надувания View.
обратите внимание, что вам нужна ViewGroup, чтобы добавить представление (любой макет, который вы можете придумать)
Итак, в качестве примера предположим, что у вас есть фрагмент, который он просматривает, уже накачан, и вы знаете, что корневое представление является макетом, и вы хотите добавить к нему представление:
View view = getView();// returns base view of the fragmentif(view ==null)return;if(!(view instanceofViewGroup))return;ViewGroup viewGroup =(ViewGroup) view;View popup =View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
Вы также можете написать статический метод, что-то вроде addView(View v){ // your code after get view }этого, которое будет использовать findViewById(int resourceID)или раздутое представление, как ваш inflatedView... просто чтобы расширить ваш пример фрагмента.
zgc7009
22
Это поздно, но это может кому-то помочь :) :) Для добавления вида программно попробуйте как
Идея программной установки ограничений может быть утомительной. Это решение ниже будет работать для любого макета, будь то ограничение, линейное и т. Д. Наилучшим способом было бы установить заполнитель, т.е. FrameLayout с надлежащими ограничениями (или надлежащим размещением в другом макете, например, линейном) в позиции, в которой вы ожидаете программно созданное представление. иметь.
Все, что вам нужно сделать, это раздувать представление программно и в детстве с помощью addChild()метода FrameLayout . Тогда во время выполнения ваш вид будет раздут и помещен в правильное положение. Согласно рекомендациям Android, вы должны добавить только один дочерний элемент в FrameLayout [ссылка] .
Вот как будет выглядеть ваш код, если вы хотите программно создать TextView в определенной позиции:
Шаг 1:
В вашем макете, который будет содержать раздуваемое представление, поместите FrameLayout в правильное положение и присвойте ему идентификатор, скажем, «контейнер».
Шаг 2
Создайте макет с корневым элементом в качестве представления, которое вы хотите раздуть во время выполнения, вызовите файл макета как «textview.xml»:
Кстати, установите параметры макета вашего frameLayout равными wrap_content, иначе макет кадра станет таким же большим, как родительский элемент, т.е. активность, то есть экран телефона.
Если не задано, потому что дочерний вид рамки по умолчанию переходит в левую верхнюю часть макета кадра, поэтому ваш вид просто переместится в левую верхнюю часть экрана.
(Обратите внимание, что установка последнего параметра findViewByIdдля nullи добавление представления путем вызова представления addView()контейнера (frameLayout) - это то же самое, что просто присоединение раздутого представления путем передачи trueтретьего параметра параметра findViewById(). Для получения дополнительной информации см. Это .)
Вы, ребята, также должны убедиться, что при переопределении onLayoutвы должны вызывать super.onLayoutвсе свойства, иначе представление не будет раздутым!
для всех, кто еще заинтересован:
лучший способ, который я нашел, - использовать статический метод надувания View.
где yourViewXML что-то вроде R.layout.myView
обратите внимание, что вам нужна ViewGroup, чтобы добавить представление (любой макет, который вы можете придумать)
Итак, в качестве примера предположим, что у вас есть фрагмент, который он просматривает, уже накачан, и вы знаете, что корневое представление является макетом, и вы хотите добавить к нему представление:
источник
addView(View v){ // your code after get view }
этого, которое будет использоватьfindViewById(int resourceID)
или раздутое представление, как вашinflatedView
... просто чтобы расширить ваш пример фрагмента.Это поздно, но это может кому-то помочь :) :) Для добавления вида программно попробуйте как
Это создаст весь ваш вид программно. Вы можете добавить любое количество просмотров, как то же самое. Надеюсь, что это может помочь. :)
источник
LinearLayout является подклассом ViewGroup , у которого есть метод addView . Метод addView должен быть тем, что вам нужно.
источник
Еще один способ добавить вид из Activity
источник
Идея программной установки ограничений может быть утомительной. Это решение ниже будет работать для любого макета, будь то ограничение, линейное и т. Д. Наилучшим способом было бы установить заполнитель, т.е. FrameLayout с надлежащими ограничениями (или надлежащим размещением в другом макете, например, линейном) в позиции, в которой вы ожидаете программно созданное представление. иметь.
Все, что вам нужно сделать, это раздувать представление программно и в детстве с помощью
addChild()
метода FrameLayout . Тогда во время выполнения ваш вид будет раздут и помещен в правильное положение. Согласно рекомендациям Android, вы должны добавить только один дочерний элемент в FrameLayout [ссылка] .Вот как будет выглядеть ваш код, если вы хотите программно создать TextView в определенной позиции:
Шаг 1:
В вашем макете, который будет содержать раздуваемое представление, поместите FrameLayout в правильное положение и присвойте ему идентификатор, скажем, «контейнер».
Шаг 2 Создайте макет с корневым элементом в качестве представления, которое вы хотите раздуть во время выполнения, вызовите файл макета как «textview.xml»:
Кстати, установите параметры макета вашего frameLayout равными wrap_content, иначе макет кадра станет таким же большим, как родительский элемент, т.е. активность, то есть экран телефона.
Если не задано, потому что дочерний вид рамки по умолчанию переходит в левую верхнюю часть макета кадра, поэтому ваш вид просто переместится в левую верхнюю часть экрана.
Шаг 3
В вашем методе oncreate сделайте это:
(Обратите внимание, что установка последнего параметра
findViewById
дляnull
и добавление представления путем вызова представленияaddView()
контейнера (frameLayout) - это то же самое, что просто присоединение раздутого представления путем передачиtrue
третьего параметра параметраfindViewById()
. Для получения дополнительной информации см. Это .)источник
Вы, ребята, также должны убедиться, что при переопределении
onLayout
вы должны вызыватьsuper.onLayout
все свойства, иначе представление не будет раздутым!источник