【发布时间】:2011-05-27 05:23:16
【问题描述】:
这个属性可以在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 的文档。基本上,您需要获取 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 而不是 线性布局.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 module 为作为 Android 框架一部分的公共库提供扩展,androidx.core.view 就是其中之一。
dependencies {
implementation "androidx.core:core-ktx:{latest-version}"
}
以下扩展函数可以方便地处理边距:
注意:都是
MarginLayoutParams的扩展函数,所以 首先,您需要获取并转换您的视图的layoutParams:val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
setMargins()扩展功能:设置ViewGroup的MarginLayoutParams中所有轴的边距。 (尺寸必须以像素为单位,如果要使用 dp,请参阅最后一节)
inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
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)
更新ViewGroup 的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,则需要先转换它们。您可以使用以下扩展属性轻松做到这一点:
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)
【讨论】:
params varaibble 在代码中被遗漏了,但我在第一种情况下找到了它,而不是在其他情况下现在你的答案是完全描述性的