Як встановити поле ImageView за допомогою коду, а не xml


177

Я хочу додати невідому кількість ImageViewпереглядів до моєї верстки з запасом. У XML я можу використовувати layout_marginтак:

<ImageView android:layout_margin="5dip" android:src="@drawable/image" />

Є ImageView.setPadding(), але ні ImageView.setMargin(). Я думаю, що це за принципами ImageView.setLayoutParams(LayoutParams), але не впевнений, що слід подати до цього.

Хтось знає?

Відповіді:


381

android.view.ViewGroup.MarginLayoutParamsмає метод setMargins(left, top, right, bottom). Прямі підкласи: FrameLayout.LayoutParams, LinearLayout.LayoutParamsі RelativeLayout.LayoutParams.

Використовуючи, наприклад LinearLayout:

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(left, top, right, bottom);
imageView.setLayoutParams(lp);

MarginLayoutParams

Це встановлює поля в пікселях. Для масштабування його використовують

context.getResources().getDisplayMetrics().density

DisplayMetrics


18
Зауважте, що цей параметр встановлює розмір поля в PIXELS, не такий, як одиниця dpi в xml цього питання.
aromero

Як ми можемо використовувати значення dpi замість пікселя?
Паскаль Піше

10
Ви можете масштабувати значення px, використовуючи context.getResources (). GetDisplayMetrics (). Щільність developer.android.com/reference/android/util/…
ключ

1
Зауважте, що можуть бути проблеми з, FrameLayout.LayoutParamsа може, і з іншими: stackoverflow.com/questions/5401952/…
Дмитро Зайцев,

на випадок, якщо ми хотіли б встановити лише нижню межу перегляду зображення, що є, android:layout_centerHorizontal = "true"і android:layout_alignParentBottom = "true"яким чином я міг би це досягти?
ssrp

51
    image = (ImageView) findViewById(R.id.imageID);
    MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
    marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
    image.setLayoutParams(layoutParams);

5
Яка угода з останніми 2 рядками? клонувати параметри поля в іншу змінну параметрів? Я можу підтвердити, що це потрібно :)
Адам Рабунг,

1
на випадок, якщо ми хотіли б встановити лише нижню межу перегляду зображення, що є, android:layout_centerHorizontal = "true"і android:layout_alignParentBottom = "true"яким чином я міг би це досягти?
ssrp

layoutparams.addRule (RelativeLayout.CENTER_HORIZONTAL);
cwhsu

Створення інших параметрів компонування потрібно. Дякую :)
Muzaffer

42

Усі вищезазначені приклади насправді ЗАМІНУЮТЬ будь-які парами, вже наявні для Перегляду, які можуть бути не бажаними. Наведений нижче код просто розширить існуючі парами, не замінюючи їх:

ImageView myImage = (ImageView) findViewById(R.id.image_view);
MarginLayoutParams marginParams = (MarginLayoutParams) image.getLayoutParams();
marginParams.setMargins(left, top, right, bottom);

1
Це перше рішення в цьому списку, яке працювало на мене. Інші накрутили інші парами, які я встановив у XML, включаючи параметри RelativeLayout для позиціонування.
Кріс Датроу

22

Код Кевіна створює зайвий MarginLayoutParamsоб’єкт. Простіша версія:

ImageView image = (ImageView) findViewById(R.id.main_image);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(image.getLayoutParams());
lp.setMargins(50, 100, 0, 0);
image.setLayoutParams(lp);

1
Досить дивно, тоді я отримую "Неможливо вирішити метод setmargins ()", тому я погукався за цим питанням і приземлився тут.
користувач2875404

11

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

  1. Отримайте в цьому випадку параметри MarginLayoutParameters вашого зображення: myImageView

     MarginLayoutParams marginParams = (MarginLayoutParams) myImageView.getLayoutParams();
  2. Тепер просто змініть поле, яке ви хочете змінити, але залиште інші таким, яким вони є:

     marginParams.setMargins(marginParams.leftMargin, 
                             marginParams.topMargin, 
                             150, //notice only changing right margin
                             marginParams.bottomMargin); 

8

Ви можете використовувати цей метод, якщо ви хочете вказати поля в dp:

private void addMarginsInDp(View view, int leftInDp, int topInDp, int rightInDp, int bottomInDp) {
    DisplayMetrics dm = view.getResources().getDisplayMetrics();
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    lp.setMargins(convertDpToPx(leftInDp, dm), convertDpToPx(topInDp, dm), convertDpToPx(rightInDp, dm), convertDpToPx(bottomInDp, dm));
    view.setLayoutParams(lp);
}

private int convertDpToPx(int dp, DisplayMetrics displayMetrics) {
    float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
    return Math.round(pixels);
}

8

Я просто використовую це і чудово працює:

ImageView imageView = (ImageView) findViewById(R.id.image_id);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.setMargins(left, top, right, bottom);
imageView.setLayoutParams(layoutParams);

одиницею setMargins () є піксель не dp. Якщо ви хочете встановити маржу в dp, просто всередині файлу значень / dimens.xml створіть свої параметри, наприклад:

<resources>
    <dimen name="right">16dp</dimen>
    <dimen name="left">16dp</dimen>    
</resources>

і доступ, як:

getResources().getDimension(R.dimen.right);

5

Якщо ви використовуєте kotlin, це можна спростити, створивши функцію розширення

fun View.setMarginExtensionFunction(left: Int, top: Int, right: Int, bottom: Int) {
  val params = layoutParams as ViewGroup.MarginLayoutParams
  params.setMargins(left, top, right, bottom)
  layoutParams = params
}

Тепер все, що вам потрібно, - це перегляд, і цю функцію розширення можна використовувати в будь-якому місці.

val imageView = findViewById(R.id.imageView)
imageView.setMarginExtensionFunction(0, 0, 0, 0)

1
це працює для leftі rightполя, але якщо у вас відносні поля ( startі end), це не працює. Я написав суть з "вдосконаленою" версією вашого коду: gist.github.com/Grohden/f40c53bf86c5395638f7a44bf90e732d ( setMarginsRelativeфункція) - ви могли б це включити у свою відповідь?
Габріель Де Олівейра Роден

4

створити макет динамічно і встановити його параметр, оскільки setmargin () не працюватиме безпосередньо на imageView

ImageView im;
im = (ImageView) findViewById(R.id.your_image_in_XML_by_id);
 RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(im.getLayoutParams());
                        layout.setMargins(counter*27, 0, 0, 0);//left,right,top,bottom
                        im.setLayoutParams(layout);
                        im.setImageResource(R.drawable.yourimage)

4

Для мене це спрацювало:

int imgCarMarginRightPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, definedValueInDp, res.getDisplayMetrics());

MarginLayoutParams lp = (MarginLayoutParams) imgCar.getLayoutParams();
lp.setMargins(0,0,imgCarMarginRightPx,0);
imgCar.setLayoutParams(lp);

2

зразок коду тут, його дуже просто

LayoutParams params1 = (LayoutParams)twoLetter.getLayoutParams();//twoletter-imageview
                params1.height = 70;
                params1.setMargins(0, 210, 0, 0);//top margin -210 here
                twoLetter.setLayoutParams(params1);//setting layout params
                twoLetter.setImageResource(R.drawable.oo);

0

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

public void addMargins(View v, int left, int top, int right, int bottom) {
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
    if (params == null)
        params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                               ViewGroup.LayoutParams.WRAP_CONTENT);
    int oldLeft = params.leftMargin;
    int oldTop = params.topMargin;
    int oldRight = params.rightMargin;
    int oldBottom = params.bottomMargin;
    params.setMargins(oldLeft + left, oldTop + top, oldRight + right, oldBottom + bottom);
    v.setLayoutParams(params);
}

0

Ось приклад для додавання 8px поля зліва, вгорі, вправо, внизу.


ImageView imageView = new ImageView(getApplicationContext());

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(
    ViewGroup.MarginLayoutParams.MATCH_PARENT,
    ViewGroup.MarginLayoutParams.WRAP_CONTENT
);

marginLayoutParams.setMargins(8, 8, 8, 8);

imageView.setLayoutParams(marginLayoutParams);

0

Відповідь від 2020 року:

dependencies {
    implementation "androidx.core:core-ktx:1.2.0"
}

і називати його просто у своєму коді

view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
   setMargins(5)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.