Як програмно додати перегляди до переглядів


179

Скажімо, у мене є LinearLayout , і я хочу додати її в свою програму з коду Java. Який метод для цього використовується? Я не запитую, як це робиться в XML, про що я знаю, а, як, я можу щось зробити в рамках цього зразкового коду?

(One View).add(Another View)

Як це можна зробити в Swing.

Відповіді:


248

Виклик addView- це правильна відповідь, але для цього потрібно зробити трохи більше, ніж це.

Якщо ви створюєте Перегляд за допомогою конструктора (наприклад, Button myButton = new Button();), вам потрібно буде зателефонуватиsetLayoutParams за щойно побудованим поданням, передавши екземпляр внутрішнього класу LayoutParams батьківського виду, перш ніж додати до нього батьківський погляд.

Наприклад, у вашій onCreate()функції може бути наступний код, припускаючи, що ваш LinearLayout має ідентифікатор R.id.main:

LinearLayout myLayout = findViewById(R.id.main);

Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
                                     LinearLayout.LayoutParams.MATCH_PARENT,
                                     LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

Переконайтесь, що встановити LayoutParams важливо. Кожному виду потрібен принаймні макет_ ширина та параметр макета_висота. Також важливим є отримання правильного внутрішнього класу. Я боровся з тим, щоб перегляди додані в TableRow для відображення належним чином, поки я не зрозумів, що я не передаю екземпляр TableRow.LayoutParams до встановленого дочірнього видуLayoutParams.


5
Як би ви створили представлення програмно, але використовуючи файл макета XML, який ви спеціально написали для цього нового перегляду?
SK9

9
@ SK9 Ви б використовували LayoutInflater, який ви можете отримати з контексту, як правило, поточної активності. Щось на кшталт: LayoutInflater myInflater = getLayoutInflater; Переглянути myView = myInflater.inflate (R.layout.myLayout, батьківський, помилковий);
Брайан Кулі

1
Насправді getLayoutInflater () походить від класу Window (не Контекст), і це зручний метод у Activity.
Брайан Кулі

2
Як практика кодування, на findViewById, що передається ViewGroup або завжди найбільш загальній формі об'єкта, так що якщо він зміниться з LinearLayout на RelativeLayout, у вас не буде рефакторингу.
Джоель Теплі

1
Ось деякі деталі: D
Vivek Solanki

51

для всіх, хто ще цікавиться:

найкращий спосіб, який я знайшов, - це використовувати надутий статичний метод View.

View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);

де yourViewXML - це щось на зразок R.layout.myView

зауважте, що вам потрібен ViewGroup, щоб додати перегляд (який будь-який макет ви можете придумати)

тому в якості прикладу можна сказати, що у вас є фрагмент, який його перегляд уже завищений, і ви знаєте, що корінне подання є макетом, і ви хочете додати його в перегляд:

    View view = getView(); // returns base view of the fragment
    if (view == null)
        return;
    if (!(view instanceof ViewGroup))
        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

Це пізно, але це може допомогти комусь :) :) Для програмного додавання перегляду спробуйте як

LinearLayout rlmain = new LinearLayout(this);      
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);          
LinearLayout   ll1 = new LinearLayout (this);

ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);              
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);              
setContentView(rlmain, llp);

Це створить весь ваш перегляд програмно. Ви можете додати будь-яке число перегляду як однакове. Сподіваюся, це може допомогти. :)



3

Ще один спосіб додати перегляд із діяльності

ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);

0

Ідея програмного встановлення обмежень може бути стомлюючою. Це рішення нижче буде працювати для будь-якого макета, будь то обмеження, лінійне тощо. Найкращим способом було б встановити заповнювач, тобто FrameLayout з належними обмеженнями (або правильне розміщення в іншому макеті, наприклад, лінійному) у тому місці, де ви очікували б програмно створеного перегляду мати.

Все, що вам потрібно зробити, це надути подання програмно і це як дитина в FrameLayout за допомогою addChild()методу. Тоді під час виконання ваш погляд буде завищений і розміщений у правильному положенні. Згідно з рекомендацією для Android, вам слід додати лише одне дочірнє перегляд у FrameLayout [посилання] .

Ось як виглядатиме ваш код, припускаючи, що ви хочете програмно створити TextView на певній позиції:

Крок 1:

У своєму макеті, який би містив перегляд, який має бути завищеним, розмістіть FrameLayout у правильному положенні та надайте йому ідентифікатор, скажімо, "контейнер".

Крок 2 Створіть макет із кореневим елементом, як перегляд, який ви хочете надути під час виконання, назвіть файл макета як "textview.xml":

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</TextView>

BTW, встановіть параметри макетів вашого frameLayout на wrap_content завжди, макет кадру стане таким же великим, як і батьківський, тобто активність, тобто екран телефону.

android:layout_width="wrap_content"
android:layout_height="wrap_content"

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

Крок 3

У своєму методі oncreate зробіть це:

FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(Зверніть увагу , що установка останнього параметра findViewByIdдо nullі додаючи точку зору, закликаючи addView()на перегляд контейнера (frameLayout) такий же , як просто прикріплення надутий вигляд, передаючи trueв 3 - й параметр findViewById(). Детальніше про це читайте це .)


0

Ви, хлопці, також повинні переконатися, що коли ви перекриєте onLayout, ВІН ВІДКЛЮЧИТИ super.onLayoutз усіма властивостями, інакше вид не буде завищений!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.