Изменить правильную маржу в представлении Programmatically?
Может ли этот атрибут динамически изменяться в Java-коде?
android:layout_marginRight
У меня есть TextView
, который должен динамически менять свое положение на несколько пикселей слева.
Как это сделать программно?
Ответы
Ответ 1
EDIT: более общий способ сделать это, не полагаясь на тип макета (кроме того, что это тип макета, который поддерживает поля):
public static void setMargins (View v, int l, int t, int r, int b) {
if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
p.setMargins(l, t, r, b);
v.requestLayout();
}
}
Вы должны проверить документы для TextView. В принципе, вы захотите получить объект TextView LayoutParams и изменить поля, а затем вернуть его обратно в TextView. Предположим, что это в LinearLayout, попробуйте что-то вроде этого:
TextView tv = (TextView)findViewById(R.id.my_text_view);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, 0, 10, 0); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);
Я не могу проверить это прямо сейчас, так что мое кастинг может быть отключен, но LayoutParams - это то, что нужно изменить, чтобы изменить маржу.
Примечание
Не забывайте, что если ваш TextView находится внутри, например, RelativeLayout, следует использовать RelativeLayout.LayoutParams вместо LinearLayout.LayoutParams
Ответ 2
Используйте LayoutParams (как уже объяснено). Однако будьте осторожны, чтобы выбрать LayoutParams. В соответствии с fooobar.com/questions/50781/... вам нужно использовать тот, который относится к PARENT вида, над которым вы работаете, а не фактический вид"
Если, например, TextView находится внутри TableRow, вам нужно использовать TableRow.LayoutParams вместо RelativeLayout или LinearLayout
Ответ 3
Используйте эту функцию для установки всех типов полей
public void setViewMargins(Context con, ViewGroup.LayoutParams params,
int left, int top , int right, int bottom, View view) {
final float scale = con.getResources().getDisplayMetrics().density;
// convert the DP into pixel
int pixel_left = (int) (left * scale + 0.5f);
int pixel_top = (int) (top * scale + 0.5f);
int pixel_right = (int) (right * scale + 0.5f);
int pixel_bottom = (int) (bottom * scale + 0.5f);
ViewGroup.MarginLayoutParams s = (ViewGroup.MarginLayoutParams) params;
s.setMargins(pixel_left, pixel_top, pixel_right, pixel_bottom);
view.setLayoutParams(params);
}
Ответ 4
В Kotlin вы можете объявить функцию расширения, например:
fun View.setMargins(
leftMarginDp: Int? = null,
topMarginDp: Int? = null,
rightMarginDp: Int? = null,
bottomMarginDp: Int? = null
) {
if (layoutParams is ViewGroup.MarginLayoutParams) {
val params = layoutParams as ViewGroup.MarginLayoutParams
leftMarginDp?.run { params.leftMargin = this.dpToPx(context) }
topMarginDp?.run { params.topMargin = this.dpToPx(context) }
rightMarginDp?.run { params.rightMargin = this.dpToPx(context) }
bottomMarginDp?.run { params.bottomMargin = this.dpToPx(context) }
requestLayout()
}
}
fun Int.dpToPx(context: Context): Int {
val metrics = context.resources.displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), metrics).toInt()
}
Тогда вы можете назвать это как:
myView1.setMargins(8, 16, 34, 42)
Или:
myView2.setMargins(topMarginDp = 8)