以编程方式改变视图的右边缘?

这个属性可以在Java代码中动态更改吗?

android:layout_marginRight

我有一个TextView,它必须动态地向左改变它的位置一些像素。

如何以编程的方式做到这一点?

189145 次浏览

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。假设它在线性布局中,尝试如下:

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);

我现在不能测试它,所以我的casting可能会有一点偏差,但LayoutParams是需要修改以改变边缘的。

请注意

不要忘记,如果你的TextView是内部,例如,a < >强RelativeLayout < / >强,应该使用< >强使用。LayoutParams < / >强代替 LinearLayout。LayoutParams < / p >

使用LayoutParams(如上所述)。但是要小心选择LayoutParams。根据https://stackoverflow.com/a/11971553/3184778“你需要使用与你正在处理的视图的PARENT相关的那个,而不是实际的视图”

例如,如果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);
}

更新:Android KTX

核心KTX模块为属于Android框架的公共库提供了扩展,其中包括androidx.core.view

dependencies {
implementation "androidx.core:core-ktx:{latest-version}"
}

下面的扩展函数可以方便地处理页边距:

注意:它们都是MarginLayoutParams的扩展函数,所以 首先,你需要获取并转换视图的layoutParams:

val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)

设置ViewGroupMarginLayoutParams中所有轴的边距。(维度必须以像素为单位提供,如果你想使用dp,请参阅最后一部分)

inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
params.setMargins(16)

更新ViewGroupViewGroup.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)

更新ViewGroupMarginLayoutParams中的相对边距(开始/结束而不是左/右)。

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)