プログラムでビューの右マージンを変更しますか?


173

この属性はJavaコードで動的に変更できますか?

android:layout_marginRight

私は、TextView動的に左にいくつかのピクセルの位置を変更する必要があるを持っています。

プログラムでそれを行う方法?

回答:


463

編集:レイアウトタイプに依存しないこれを行うより一般的な方法(それがマージンをサポートするレイアウトタイプであることを除いて):

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などの内部にある場合、LinearLayout.LayoutParamsではなくRelativeLayout.LayoutParamsを使用する必要があることを忘れないでください。


39
他の人がこれを探している場合に備えて、回答を詳しく説明します。プログラムでTextViewを作成している場合は、.getLayoutParams();を介して取得しようとする代わりに、新しいLinearLayout.LayoutParamsオブジェクトも作成する必要があります。
アレス

これは素晴らしく機能し、余白をピクセル単位で設定するようです。dpで設定することは可能ですか?
SirRupertIII

3
@KKendall:最初にDPをPXに変換するだけです。
ケビンコポック

あなたのメモに従って:私は疑っています。テキストビューまたはボタンがテーブル行内にある場合はどうなりますか?次に、相対レイアウト、テーブルレイアウトの代わりに何を使用すればよいですか?
tejas 2013年

1
メモに関連して、tv.getLayoutParams()をViewGroup.MarginLayoutParamsにキャストできます。このように、マージンを実装している限り、どのレイアウトが親であるかは問題ではありません
Radu Simionescu

17

(すでに説明したように)LayoutParamsを使用します。ただし、選択するLayoutParamsには注意してください。https://stackoverflow.com/a/11971553/3184778によると、「実際のビューではなく、作業中のビューの親に関連するビューを使用する必要があります」

たとえば、TextViewがTableRow内にある場合、RelativeLayoutまたはLinearLayoutの代わりにTableRow.LayoutParamsを使用する必要があります。


明確にしていただきありがとうございます!
Scott Biggs

1
マージンを設定するためにテキストボックスの宛先を知る必要があるのは本当にうんざりです...宛先に依存しないソリューションがあると思います。
TatiOverflow、2018年

10

この関数を使用して、すべてのタイプのマージンを設定します

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

2
なぜ0.5fを追加したのですか?
behelit 2018

2
@behelit私はこれが遅いことを知っていますが、見ている人にとっては... floatをintにキャストすると、floatは丸くなります。0.0-> 0.4は0に丸められ、0.5-> 0.9は1に丸められます。これにより、最終的な整数に矛盾が生じる可能性があります。これを防ぐために、0.5を追加すると、すべての丸めが1になることが保証されます。なぜですか?あなたのフロートが0.3であると言います:0.3 + 0.5 = 0.8は1に切り上げます。フロートが0.8であると言います:0.8 + 0.5 = 1.3は1に切り下げます。負の整数を取得しないように、減算ではなく0.5を追加します)
Psest328

7

アップデート:Android KTX

コアKTXモジュールは、Androidのフレームワークの一部である共通ライブラリ用の拡張機能を提供しandroidx.core.view、それらの間。

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

次の拡張関数は、マージンを処理するのに便利です。

内のすべての軸の余白設定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)

余白を更新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)

アップデートの相対マージン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) 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.