Встановити поля в LinearLayout програмно


266

Я намагаюся використовувати Java ( не XML ) для створення LinearLayout з кнопками, які заповнюють екран і мають поля. Ось код, який працює без поля:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Так це чудово працює, але як на землі ви надаєте полям кнопок, щоб між ними було місця? Я спробував використовувати LinearLayout.MarginLayoutParams, але у нього немає weightчлена, тому це не добре. І це не працює, якщо ви також передасте його lpв його конструктор.

Це неможливо? Тому що це впевнено виглядає, і це не буде першим завданням для розмітки Android, яке ви можете виконати лише в XML.


1
developer.android.com/reference/android/view/… , int, int, int) Замість layoutParams.setMargins (30, 20, 30, 0); ви ставите layoutParams.setMargins (30dp, 20dp, 30dp, 0dp);
DarthestVader

3
setMargins приймає int як аргументи. Ви можете надати "dp" лише за допомогою xml attributtes
jyavenard

Відповіді:


496

Ось невеликий код для його виконання:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);

6
дякую за точковий зразок коду - спосіб більш вигідний, ніж просто описи
Хтось десь

25
Схоже, параметри поля встановлюються в пікселях. Будь-який спосіб встановити їх у dps?
Артем Русаковський

30
@ArtemRussakovskii Як і більшість функцій в Android, вони займають пікселі. Я пропоную функцію глобальної утиліти, яка перетворює дайви в px. Це я робив у всіх своїх програмах. Android API смокче.
mxcl

7
@MaxHowell Саме цим я і закінчився. Неймовірно, що таких речей часом не вистачає.
Артем Русаковський

5
@ArtemRussakovskii - використовуйте TypedValue.applyDimension (...) для перетворення DIP в PX. Дивіться stackoverflow.com/questions/2238883/…
Гаутам

64

Так це чудово працює, але як на землі ви надаєте полям кнопок, щоб між ними було місця?

Ви дзвоните setMargins()на LinearLayout.LayoutParamsоб’єкт.

Я спробував використовувати LinearLayout.MarginLayoutParams, але він не має ваги, тому це не добре.

LinearLayout.LayoutParamsє підкласом LinearLayout.MarginLayoutParams, як зазначено в документації .

Це неможливо?

Немає.

це не буде першою задачею для верстки Android, яку ви можете виконати лише в XML

Ви можете надати підтвердження цієї претензії.

Особисто я не знаю нічого, що може бути здійснено лише через XML, а не через методи Java у SDK. Насправді, за визначенням, все повинно бути виконано через Java (хоча це не обов'язково через SDK-доступні методи), оскільки XML не є виконуваним кодом. Але, якщо вам щось відомо, вкажіть це, тому що це помилка в SDK, яка повинна виправитись колись.


2
Ха, добре, я зараз розумію. Дещо загубився в системі компонування, що досить складно. Я не думаю, що в будь-якому разі потрібно встановити layout_widgth / висоту під час виконання.
Тиммммм

2
І немає ніякого способу , щоб встановити стиль: stackoverflow.com/questions/2016249 / ...
Timmmm

1
У мене не було проблем із встановленням ширини та висоти під час виконання через LayoutPararms. Я з точки зору стилів ... так, ну є причина, що я їх не використовую. :-)
CommonsWare

6
Хочеться знати, чому таке ПДТА програмно генерувати інтерфейс користувача
хтось десь

3
Змусив мене віками усвідомити, що інфакт кілька днів тому я імпортував неправильні LayoutParams, які не підтримували поля… Читаючи ці відповіді, я вирішив видалити імпорт. Існує понад 10 варіантів D: Я пішов на linearLayout.LayoutParams. Працює.
Doomsknight

31

Щоб додати поля безпосередньо до елементів (деякі елементи дозволяють безпосередньо редагувати поля), можна зробити:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

... це працює без необхідності знати / редагувати навколишній макет. Помітьте прапорець "instanceof" у випадку, якщо ви спробуєте запустити це проти чогось, що не підтримує поля.


2
Його саме я шукаю.
djdance

21

Через різницю щільності пікселів на екрані пристрою добре використовувати DIPодиницю для програмного встановлення поля. Як і нижче_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

Сподіваюсь, це допоможе.


10

Я встановив поля безпосередньо за допомогою коду нижче

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Єдине, що тут потрібно помітити, що LayoutParamsслід імпортувати наступний пакет android.widget.RelativeLayout.LayoutParams, інакше буде помилка.


7

Спробуйте це

 LayoutParams params = new LayoutParams(
            LayoutParams.WRAP_CONTENT,      
            LayoutParams.WRAP_CONTENT
    );
    params.setMargins(left, top, right, bottom);
    yourbutton.setLayoutParams(params);

7
 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);

2
«Хоча цей код може відповісти на питання, краще включити сюди пояснення коду.
xenteros

4

Спробуйте це:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;

3
/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

Ви повинні бути виробом типу viewGroup.In відображення виду коду вище, наприклад, я хочу змінити маржу frameLayout, і вид групи в frameLayout є RelativeLayout , так що вам потрібно , щоб таємним (RelativeLayout.LayoutParams)


0

Ось один рядок Рішення:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.