Может ли этот атрибут динамически изменяться в коде Java?
android:layout_marginRight
У меня есть TextView
, который должен изменить свою позицию несколько пикселей влево динамически.
Как это сделать программно?
Может ли этот атрибут динамически изменяться в коде Java?
android:layout_marginRight
У меня есть TextView
, который должен изменить свою позицию несколько пикселей влево динамически.
Как это сделать программно?
Ответы:
РЕДАКТИРОВАТЬ: более общий способ сделать это, который не зависит от типа макета (кроме того, что это тип макета, который поддерживает поля):
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 . По сути, вам нужно получить объект LayoutParams в TextView, изменить поля, а затем вернуть его обратно в 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
Используйте LayoutParams (как уже объяснялось). Однако будьте осторожны, чтобы выбрать LayoutParams. Согласно https://stackoverflow.com/a/11971553/3184778 «вам нужно использовать тот, который относится к РОДИТЕЛЯм представления, над которым вы работаете, а не к фактическому представлению»
Если, например, TextView находится внутри TableRow, то вам нужно использовать TableRow.LayoutParams вместо RelativeLayout или LinearLayout
Используйте эту функцию для установки всех типов полей
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);
}
Модуль Core KTX предоставляет расширения для общих библиотек, которые являются частью платформы Android, androidx.core.view
среди них.
dependencies {
implementation "androidx.core:core-ktx:{latest-version}"
}
Следующие функции расширения удобны для работы с полями:
setMargins()
функция расширения:Устанавливают задворки всех осей в ViewGroup
«с MarginLayoutParams
. (Размерность должна быть представлена в пикселях, см. Последний раздел, если вы хотите работать с dp)
inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
params.setMargins(16)
updateMargins()
функция расширения:Обновления на полях в ViewGroup
«с ViewGroup.MarginLayoutParams
.
inline fun MarginLayoutParams.updateMargins(
@Px left: Int = leftMargin,
@Px top: Int = topMargin,
@Px right: Int = rightMargin,
@Px bottom: Int = bottomMargin
): Unit
// Example: 8px left margin
params.updateMargins(left = 8)
updateMarginsRelative()
функция расширения:Обновляет относительные поля в ViewGroup
's MarginLayoutParams
(начало / конец вместо левого / правого).
inline fun MarginLayoutParams.updateMarginsRelative(
@Px start: Int = marginStart,
@Px top: Int = topMargin,
@Px end: Int = marginEnd,
@Px bottom: Int = bottomMargin
): Unit
// E.g: 8px start margin
params.updateMargins(start = 8)
Следующие свойства расширения удобны для получения текущих полей:
inline val View.marginBottom: Int
inline val View.marginEnd: Int
inline val View.marginLeft: Int
inline val View.marginRight: Int
inline val View.marginStart: Int
inline val View.marginTop: Int
// E.g: get margin bottom
val bottomPx = myView1.marginBottom
dp
вместо px
:Если вы хотите работать с dp
(независимыми от плотности пикселей) вместо px
, вам нужно сначала преобразовать их. Вы можете легко сделать это с помощью следующего свойства extension:
val Int.px: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
Затем вы можете вызвать предыдущие функции расширения, такие как:
params.updateMargins(start = 16.px, end = 16.px, top = 8.px, bottom = 8.px)
val bottomDp = myView1.marginBottom.dp
Старый ответ:
В 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)