Як в Android я можу програматично задати поля в dp?


401

У цій , цій і цій темі я спробував знайти відповідь про те, як встановити поля для одного виду. Однак мені було цікаво, чи немає більш простого способу. Я поясню, чому я не хотів би використовувати такий підхід:

У мене є спеціальна кнопка, яка розширює кнопку. Якщо для фону встановлено щось інше, ніж фон за замовчуванням (за допомогою дзвінка setBackgroundResource(int id)або setBackgroundDrawable(Drawable d)), я хочу, щоб поля були рівними 0. Якщо я називаю це:

public void setBackgroundToDefault() {
    backgroundIsDefault = true;
    super.setBackgroundResource(android.R.drawable.btn_default);
    // Set margins somehow
}

Я хочу, щоб поля були скинуті до -3dp (я вже читав тут, як конвертувати з пікселів у dp, тому, як тільки я знаю, як встановити поля в px, я можу сам керувати перетворенням). Але оскільки це називається в CustomButtonкласі, батько може змінюватись від LinearLayout до TableLayout, і я вважаю за краще, щоб він не став своїм батьківським і перевіряв екземпляр цього батька. Я думаю, це теж буде досить неефективним.

Крім того, під час дзвінка (використовуючи LayoutParams) parentLayout.addView(myCustomButton, newParams), я не знаю, чи це додасть його до правильної позиції (проте не пробував), скажімо, середня кнопка рядка з п'яти.

Питання: Чи є простіший спосіб встановити поле однієї кнопки програмно, окрім використання LayoutParams?

EDIT: Я знаю спосіб LayoutParams, але мені хотілося б рішення, яке уникає обробки кожного типу контейнерів:

ViewGroup.LayoutParams p = this.getLayoutParams();
    if (p instanceof LinearLayout.LayoutParams) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof RelativeLayout.LayoutParams) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof TableRow.LayoutParams) {
        TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
}

Тому що this.getLayoutParams();повертає ViewGroup.LayoutParams, які не мають атрибути topMargin, bottomMargin, leftMargin, rightMargin. Екземпляр mc, який ви бачите, є лише a, MarginContainerякий містить зміщення (-3dp) поля та (oml, omr, omt, omb) та початкові поля (ml, mr, mt, mb).

Відповіді:


797

Слід LayoutParamsвстановити поля кнопок:

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

Залежно від того, який макет ви використовуєте, ви повинні використовувати RelativeLayout.LayoutParamsабо LinearLayout.LayoutParams.

А щоб перетворити міру dp в піксель, спробуйте:

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);

152
З якого пакета я повинен імпортувати саме цей LayoutParams?
stealthjong

7
setMargins використано px, і ви будете використовувати dp, моє перетворення правильно: dp -> px, щоб встановити правильне значення поля.
throrin19

6
@ChristiaandeJong RelativeLayout.LayoutParams
stoefln

15
це залежить від вашого поточного макета. Якщо ви перебуваєте в LinearLayout, використовуйте LinearLayout.LayoutParams. RelativeLayout.LayoutParams в іншому випадку
throrin19

5
ви повинні імпортувати layoutParams, який є вашим батьківським макетом, наприклад. <linearlayout><relativelayout> <gridlayout> і ви працюєте з компонуванням сітки. тоді вам потрібно використовувати
Relalayout.layoutparams

228

Макет-парами - НЕ ПРАЦЮЄМО! ! !

Потрібен тип використання: MarginLayoutParams

MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;

Приклад коду для MarginLayoutParams:

http://www.codota.com/android/classes/android.view.ViewGroup.MarginLayoutParams


19
Правильно, але не потрібно встановлювати його назад, змінені параметри автоматично відображаються. Таким чином ви можете видалити рядок: vector8.setLayoutParams (params);
Вірзінг

LayaoutParams зазвичай створюють плутанину під час встановлення поля… Отже, цей MarginLayoutParams дуже корисний. Спасибі
Atul Bhardwaj

4
вам потрібно встановити LayoutParams (парами) після зміни
маржування

Я знайшов MarginLayoutParams як новий клас сьогодні # Дякую.
Тушар Пандей

Не працює для Buttonперегляду: ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams()повертаєтьсяnull
Костянтин Конопко

118

Найкращий спосіб коли-небудь:

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(left, top, right, bottom);
        view.requestLayout();
    }
}

Як викликати метод:

setMargins(mImageView, 50, 50, 50, 50);

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


1
я стикаюся з проблемою, коли я встановлюю setMargins (hold.vCenter, 0, 20, 0,0); як це його залишок поля обох сторін (верхній і нижній), що не так у вищезгаданих парамах?
Arbaz.in

1
Дивовижна ідеальна відповідь !! Дякую!!
Сід

33
int sizeInDP = 16;

int marginInDp = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, sizeInDP, getResources()
                    .getDisplayMetrics());

Тоді

layoutParams = myView.getLayoutParams()
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

Або

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

15

Ось відповідь "все в одному" з останніми оновленнями:

Крок 1, щоб оновити маржу

Основна ідея полягає в тому, щоб отримати маржу і потім оновити її. Оновлення буде застосовано автоматично, і вам не потрібно його встановлювати назад. Щоб отримати параметри компонування, просто зателефонуйте за цим методом:

LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();

LayoutParamsПоходить від розташування вашого зору. Якщо вигляд має лінійний макет, вам потрібно імпортувати LinearLayout.LayoutParams. Якщо ви використовуєте відносний макет, імпорт LinearLayout.LayoutParamsтощо.

Тепер, якщо ви встановите запас з допомогою Layout_marginLeft, Rightі т.д., вам необхідно маржею поновлення таким чином ,

layoutParams.setMargins(left, top, right, bottom);

Якщо ви встановлюєте маржу, використовуючи нову layout_marginStart, вам потрібно оновити маржу таким чином

layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);

Крок 2, щоб оновити маржу в dp

Усі два способи оновлення межі вище - це оновлення у пікселях. Вам потрібно зробити переклад dp в пікселі.

float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;

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


9

layout_margin - обмеження, про яке дитина переказує своєму батькові. Однак роль батька полягає в тому, щоб вибрати, чи дозволяти маржу чи ні. В основному, встановивши android: layout_margin = "10dp", дитина просить батьківську групу перегляду виділити простір, який на 10dp більше, ніж його фактичний розмір. (padding = "10dp", з іншого боку, означає, що дочірній вигляд зробить власний вміст на 10dp меншим .)

Отже, не всі ViewGroups поважають маржу . Найвідомішим прикладом може бути перегляд списків, де поля елементів ігноруються. Перед тим, як зателефонувати setMargin()в LayoutParam, ви завжди повинні переконатися, що поточний вид перебуває у ViewGroup, що підтримує маржу (наприклад, LinearLayouot або RelativeLayout), і передавайте результат getLayoutParams()конкретним LayoutParams, які ви хочете. ( ViewGroup.LayoutParamsнавіть не має setMargins()методу!)

Функція, подана нижче, повинна робити хитрість. Однак переконайтеся, що ви замінили RelativeLayout на тип батьківського подання.

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}

9

Цей метод дозволить вам встановити маржу в DP

public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {

        final float scale = con.getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int pixel =  (int)(dp * scale + 0.5f); 

        ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
        s.setMargins(pixel,pixel,pixel,pixel);

        yourView.setLayoutParams(params);
}

ОНОВЛЕННЯ

Ви можете змінити параметр, який відповідає вашим потребам.


8

У Котліні це буде виглядати приблизно так:

val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams

3

Коли ви перебуваєте у власному перегляді, ви можете використовувати getDimensionPixelSize(R.dimen.dimen_value), у моєму випадку я додав поля в LayoutParams, створений initметодом.

У Котліні

init {
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true)
    layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
    val margin = resources.getDimensionPixelSize(R.dimen.dimen_value)
    setMargins(0, margin, 0, margin)
}

на Java:

public class CustomView extends LinearLayout {

    //..other constructors

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.spacing_dime);
        params.setMargins(0, margin, 0, margin);
        setLayoutParams(params);
    }
}

1

Використовуйте цей метод для встановлення маржі у dp

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

        final float scale = getBaseContext().getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int l =  (int)(left * scale + 0.5f);
        int r =  (int)(right * scale + 0.5f);
        int t =  (int)(top * scale + 0.5f);
        int b =  (int)(bottom * scale + 0.5f);

        p.setMargins(l, t, r, b);
        view.requestLayout();
    }
}

виклик методу:

setMargins(linearLayout,5,0,5,0);

1

Для швидкого використання однолінійного налаштування

((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);

але будьте наполегливі за будь-яке неправильне використання LayoutParams, оскільки це не матиме жодного ifекземпляра


1

Створено функцію розширення Kotlin для тих із вас, хто може вважати його зручним.

Переконайтеся, що передавати у пікселях не dp. Щасливе кодування :)

fun View.addLayoutMargins(left: Int? = null, top: Int? = null,
                      right: Int? = null, bottom: Int? = null) {
    this.layoutParams = ViewGroup.MarginLayoutParams(this.layoutParams)
            .apply {
                left?.let { leftMargin = it }
                top?.let { topMargin = it }
                right?.let { rightMargin = it }
                bottom?.let { bottomMargin = it }
            }
}

1

У своєму прикладі я додаю ImageView до LinearLayout програмно. Я встановив верхній і нижній поля в ImagerView. Потім додайте ImageView до LinearLayout.



        ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmap);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        params.setMargins(0, 20, 0, 40);
        imageView.setLayoutParams(params);
        linearLayout.addView(imageView);

1

Ви можете використовувати цей метод і поставити статичні розміри, як 20, які він перетворює відповідно до вашого пристрою

 public static int dpToPx(int dp) 
      {
          float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
  }

0

Як і сьогодні, мабуть, найкраще використовувати Париж , бібліотеку, яку надає AirBnB.

Потім стилі можна застосувати так:

Paris.style(myView).apply(R.style.MyStyle);

він також підтримує спеціальний перегляд (якщо ви розширюєте подання), використовуючи примітки:

@Styleable and @Style

0

Ви повинні зателефонувати

setPadding(int left, int top, int right, int bottom)

так: your_view.setPadding(0,16,0,0)

Те, що ви намагаєтеся використовувати, - це лише геттер.

Android студія показує, що padding...()насправді означає java:

Приклад накладки Зображення показує, що воно викликає лише дзвінкиgetPadding...()

Якщо ви хочете додати поле до свого TextView, вам доведеться LayoutParams:

val params =  LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT)
params.setMargins(int left, int top, int right, int bottom)
your_view.layoutParams = params

-1
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

Мені довелося передавати шахту FrameLayoutдля linearLayout, оскільки він успадковує її та встановлює поля там, тому активність відображається лише на частині екрану разом з іншим фоном, ніж оригінальні параметри компонування в setContentView.

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
linearLayout.setBackgroundColor(getResources().getColor(R.color.full_white));
setContentView(linearLayout,layoutParams);

Ніхто з інших не працював над використанням тієї самої діяльності та зміною поля на основі відкриття діяльності з іншого меню! setLayoutParams для мене ніколи не працював - пристрій виходитиме з ладу кожен раз. Незважаючи на те, що це жорсткі коди - це лише приклад коду для демонстраційних цілей.


-1

Ви можете використовувати ViewGroup.MarginLayoutParamsдля встановлення ширини, висоти та полів

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
marginLayoutParams.setMargins(0,16,0,16);
linearLayout.setLayoutParams(marginLayoutParams);

Де метод setMargins();приймає значення для лівого, верхнього, правого, нижнього відповідно. За годинниковою стрілкою !, починаючи зліва.

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