499

この、これこのスレッドでは、単一のビューにマージンを設定する方法についての答えを見つけようとしましたしかし、もっと簡単な方法はないのだろうかと思っていました。このアプローチを使用したくない理由を説明します。

Buttonを拡張するカスタムButtonがあります。背景がデフォルトの背景以外に設定されている場合(またはのいずれsetBackgroundResource(int id)かを呼び出すことによりsetBackgroundDrawable(Drawable d))、マージンを0にします。これを呼び出す場合:

public void setBackgroundToDefault() {
    backgroundIsDefault = true;
    super.setBackgroundResource(android.R.drawable.btn_default);
    // Set margins somehow
}

マージンを-3dpにリセットしたい(ピクセルからdpに変換する方法はすでにここで読んだので、ピクセルでマージンを設定する方法を知ったら、自分で変換を管理できます)。ただし、これはCustomButtonクラスで呼び出されるため、親はLinearLayoutごとに異なる可能性があります。親を取得してその親のインスタンスを確認することは避けたいと思います。それもかなりパフォーマンスが悪いと思います。

また、(LayoutParamsを使用して)呼び出すとき、parentLayout.addView(myCustomButton, newParams)これが正しい位置に追加されるかどうかはわかりません(ただし、試していません)。たとえば、5行の中央のボタンを押します。

質問: LayoutParamsを使用する以外に、プログラムで単一のボタンのマージンを設定する簡単な方法はありますか?

編集:私はLayoutParamsの方法を知っていますが、それぞれの異なるコンテナータイプの処理を回避するソリューションが必要です:

ViewGroup.LayoutParams p = this.getLayoutParams();
    if (p instanceof LinearLayout.LayoutParams) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof RelativeLayout.LayoutParams) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof TableRow.LayoutParams) {
        TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
}

は、属性、、、を持たないをthis.getLayoutParams();返すためです。表示されるmcインスタンスは、オフセット(-3dp)マージンと(oml、omr、omt、omb)および元のマージン(ml、mr、mt、mb)を含むだけです。ViewGroup.LayoutParamstopMarginbottomMarginleftMarginrightMarginMarginContainer

4

25 に答える 25

925

LayoutParamsボタンの余白を設定するには、次を使用する必要があります。

LayoutParams params = new LayoutParams(
        LayoutParams.WRAP_CONTENT,      
        LayoutParams.WRAP_CONTENT
);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);

RelativeLayout.LayoutParams使用しているレイアウトに応じて、またはを使用する必要がありますLinearLayout.LayoutParams

また、dpメジャーをピクセルに変換するには、次のことを試してください。

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);
于 2012-10-04T13:36:01.627 に答える
278

LayoutParams-機能していません!!!

使用タイプが必要:MarginLayoutParams

MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;

MarginLayoutParamsのコード例:

http://www.codota.com/android/classes/android.view.ViewGroup.MarginLayoutParams

于 2014-03-23T22:32:13.910 に答える
142

史上最高の方法:

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(left, top, right, bottom);
        view.requestLayout();
    }
}

メソッドの呼び出し方法:

setMargins(mImageView, 50, 50, 50, 50);

これがお役に立てば幸いです。

于 2016-02-04T11:34:20.710 に答える
46
int sizeInDP = 16;

int marginInDp = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, sizeInDP, getResources()
                    .getDisplayMetrics());

それで

layoutParams = myView.getLayoutParams()
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

または

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);
于 2015-08-16T19:49:33.763 に答える
23

最近の更新によるオールインワンの回答は次のとおりです。

ステップ1、マージンを更新するには

基本的な考え方は、マージンを取り除いてから更新することです。更新は自動的に適用され、元に戻す必要はありません。レイアウトパラメータを取得するには、次のメソッドを呼び出すだけです。

LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();

LayoutParamsビューのレイアウトに由来します。ビューが線形レイアウトからのものである場合は、をインポートする必要がありますLinearLayout.LayoutParams。相対レイアウトを使用する場合は、インポートLinearLayout.LayoutParamsなど。

ここで、、などを使用してマージンを設定する場合はLayout_marginLeftRightこの方法でマージンを更新する必要があります

layoutParams.setMargins(left, top, right, bottom);

新しいを使用してマージンを設定する場合はlayout_marginStart、この方法でマージンを更新する必要があります

layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);

ステップ2、dpのマージンを更新します

上記のマージンを更新する2つの方法はすべて、ピクセル単位で更新しています。dpからピクセルへの変換を行う必要があります。

float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;

次に、計算された値を上記のマージン更新関数に入れます。これですべての設定が完了します。

于 2017-11-29T17:38:28.973 に答える
15

Android KTXを使用すると、次のようなことができます。

yourView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
   setMargins(0, 0, 0, 0)
}
于 2021-07-01T08:46:15.457 に答える
14

Kotlinでは次のようになります。

val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams
于 2019-09-23T12:33:50.627 に答える
10

layout_marginは、ビューの子がその親に伝える制約です。ただし、マージンを許可するかどうかを選択するのは親の役割です。基本的に、android:layout_margin = "10dp"を設定することにより、子は親ビューグループに実際のサイズよりも10dp大きいスペースを割り当てるように要求しています。(一方、padding = "10dp"は、子ビューが独自のコンテンツを10dp小さくすることを意味します。)

したがって、すべてのViewGroupがマージンを尊重するわけではありません。最も悪名高い例は、アイテムの余白が無視されるリストビューです。LayoutParamを呼び出す前にsetMargin()、現在のビューがマージンをサポートするViewGroup(LinearLayouotやRelativeLayoutなど)に存在することを常に確認し、その結果をgetLayoutParams()必要な特定のLayoutParamにキャストする必要があります。(方法ViewGroup.LayoutParamsすらありませんsetMargins()!)

以下の関数でうまくいくはずです。ただし、親ビューのタイプをRelativeLayoutに置き換えてください。

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}
于 2015-04-01T00:25:35.397 に答える
10

この方法では、DPでマージン設定できます

public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {

        final float scale = con.getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int pixel =  (int)(dp * scale + 0.5f); 

        ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
        s.setMargins(pixel,pixel,pixel,pixel);

        yourView.setLayoutParams(params);
}

アップデート

必要に応じてパラメータを変更できます。

于 2015-05-26T07:32:46.143 に答える
8

この方法を使用して、デバイスに応じて変換される20のような静的寸法を配置できます

 public static int dpToPx(int dp) 
      {
          float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
  }
于 2019-05-29T07:47:26.633 に答える
7

シンプルなKotlin拡張ソリューション

すべて/任意の側を個別に設定します。

fun View.setMargin(left: Int? = null, top: Int? = null, right: Int? = null, bottom: Int? = null) {
    val params = (layoutParams as? MarginLayoutParams)
    params?.setMargins(
            left ?: params.leftMargin,
            top ?: params.topMargin,
            right ?: params.rightMargin,
            bottom ?: params.bottomMargin)
    layoutParams = params
}

myView.setMargin(10, 5, 10, 5)
// or just any subset
myView.setMargin(right = 10, bottom = 5)

リソース値を直接参照します。

fun View.setMarginRes(@DimenRes left: Int? = null, @DimenRes top: Int? = null, @DimenRes right: Int? = null, @DimenRes bottom: Int? = null) {
    setMargin(
            if (left == null) null else resources.getDimensionPixelSize(left),
            if (top == null) null else resources.getDimensionPixelSize(top),
            if (right == null) null else resources.getDimensionPixelSize(right),
            if (bottom == null) null else resources.getDimensionPixelSize(bottom),
    )
}

myView.setMarginRes(top = R.dimen.my_margin_res)

すべての側面をプロパティとして直接均等に設定するには:

var View.margin: Int
    get() = throw UnsupportedOperationException("No getter for property")
    set(@Px margin) = setMargin(margin, margin, margin, margin)
   
myView.margin = 10 // px

// or as res
var View.marginRes: Int
    get() = throw UnsupportedOperationException("No getter for property")
    set(@DimenRes marginRes) {
        margin = resources.getDimensionPixelSize(marginRes)
    }

myView.marginRes = R.dimen.my_margin_res

特定の側面を直接設定するには、次のようなプロパティ拡張を作成できます。

var View.leftMargin
    get() = marginLeft
    set(@Px leftMargin) = setMargin(left = leftMargin)

var View.leftMarginRes: Int
    get() = throw UnsupportedOperationException("No getter for property")
    set(@DimenRes leftMarginRes) {
        leftMargin = resources.getDimensionPixelSize(leftMarginRes)
    }

これにより、以下を作成horizontalまたはvertical変形することもできます。

var View.horizontalMargin
    get() = throw UnsupportedOperationException("No getter for property")
    set(@Px horizontalMargin) = setMargin(left = horizontalMargin, right = horizontalMargin)

var View.horizontalMarginRes: Int
    get() = throw UnsupportedOperationException("No getter for property")
    set(@DimenRes horizontalMarginRes) {
        horizontalMargin = resources.getDimensionPixelSize(horizontalMarginRes)
    }

注:マージンの設定に失敗した場合は、レンダリングする前に早すぎる可能性があります。つまり、params == null。変更をでラップしてみてくださいmyView.post{ margin = 10 }

于 2020-08-30T04:59:33.717 に答える
6

それは私がした方法ですkotlin

fun View.setTopMargin(@DimenRes dimensionResId: Int) {
    (layoutParams as ViewGroup.MarginLayoutParams).topMargin = resources.getDimension(dimensionResId).toInt()
}
于 2020-09-24T23:01:52.597 に答える
5

TextViewにマージンを追加する場合は、LayoutParamsを実行する必要があります。

val params =  LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT)
params.setMargins(int left, int top, int right, int bottom)
your_view.layoutParams = params

LayoutParamsは、Relative、Linear、View、ViewGroupsなどの任意のレイアウトにすることができます。必要に応じてLayoutParamsを選択します。ありがとう

于 2019-09-23T13:12:40.823 に答える
3

この方法を使用して、dpにマージンを設定します

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

        final float scale = getBaseContext().getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int l =  (int)(left * scale + 0.5f);
        int r =  (int)(right * scale + 0.5f);
        int t =  (int)(top * scale + 0.5f);
        int b =  (int)(bottom * scale + 0.5f);

        p.setMargins(l, t, r, b);
        view.requestLayout();
    }
}

メソッドを呼び出す:

setMargins(linearLayout,5,0,5,0);
于 2018-06-20T15:29:57.593 に答える
3

カスタムビューを使用getDimensionPixelSize(R.dimen.dimen_value)している場合は、使用できます。私の場合は、initメソッドで作成されたLayoutParamsにマージンを追加しました。

Kotlinで

init {
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true)
    layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
    val margin = resources.getDimensionPixelSize(R.dimen.dimen_value)
    setMargins(0, margin, 0, margin)
}

Javaの場合:

public class CustomView extends LinearLayout {

    //..other constructors

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.spacing_dime);
        params.setMargins(0, margin, 0, margin);
        setLayoutParams(params);
    }
}
于 2018-08-01T04:28:19.227 に答える
1

1行のセットアップをすばやく行うには

((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);

ただし、LayoutParamsを誤って使用する場合は、ステートメントifインスタンスチェックがないため、十分に注意してください。

于 2018-07-18T00:55:41.383 に答える
1

便利だと思われる方のために、Kotlin拡張機能を作成しました。

dpではなくピクセルを渡すようにしてください。ハッピーコーディング:)

fun View.addLayoutMargins(left: Int? = null, top: Int? = null,
                      right: Int? = null, bottom: Int? = null) {
    this.layoutParams = ViewGroup.MarginLayoutParams(this.layoutParams)
            .apply {
                left?.let { leftMargin = it }
                top?.let { topMargin = it }
                right?.let { rightMargin = it }
                bottom?.let { bottomMargin = it }
            }
}
于 2019-04-26T04:35:33.453 に答える
1

私の例では、プログラムでImageViewをLinearLayoutに追加しています。上マージンと下マージンをImagerViewに設定しました。次に、ImageViewをLinearLayoutに追加します。



        ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmap);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        params.setMargins(0, 20, 0, 40);
        imageView.setLayoutParams(params);
        linearLayout.addView(imageView);

于 2019-05-09T10:26:22.823 に答える
1

他の回答に基づいて、私はあなたの親を識別し、それに応じてパラメータを使用するジェネリック拡張関数を作成しました:

//takes margin values as integer , eg for 12dp top , you will pass 12
fun View?.setMarginFromConstant(mLeft:Int, mTop:Int, mRight:Int, mBottom:Int){
    this?.apply {
        val left = context?.dpToPixel(mLeft)?:0
        val top = context?.dpToPixel(mTop)?:0
        val right = context?.dpToPixel(mRight)?:0
        val bottom = context?.dpToPixel(mBottom)?:0
        when (val params = this.layoutParams) {
            is ConstraintLayout.LayoutParams -> {
                params.marginStart = left
                params.marginEnd = right
                params.topMargin = top
                params.bottomMargin = bottom
            }
            is FrameLayout.LayoutParams -> {
                params.marginStart = left
                params.marginEnd = right
                params.topMargin = top
                params.bottomMargin = bottom
            }
            is RecyclerView.LayoutParams -> {
                params.marginStart = left
                params.marginEnd = right
                params.topMargin = top
                params.bottomMargin = bottom
            }
        }
    }

}

fun Context.dpToPixel(dp: Int): Int =
    (dp * applicationContext.resources.displayMetrics.density).toInt()

他の親ビューグループのサポートも追加できます

于 2021-03-11T08:48:07.627 に答える
0

今日のように、おそらくAirBnBが提供するライブラリであるParisを使用するのが最善でしょう。

次に、次のようにスタイルを適用できます。

Paris.style(myView).apply(R.style.MyStyle);

また、注釈を使用したカスタムビュー(ビューを拡張する場合)もサポートします。

@Styleable and @Style
于 2018-05-15T00:39:49.387 に答える
0

興味のある人のためにDPを使用してutils関数を動作させます:

public static void setMargins(Context context, View view, int left, int top, int right, int bottom) {
    int marginLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, left, context.getResources().getDisplayMetrics());
    int marginTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, top, context.getResources().getDisplayMetrics());
    int marginRight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, right, context.getResources().getDisplayMetrics());
    int marginBottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, bottom, context.getResources().getDisplayMetrics());

    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(marginLeft, marginTop, marginRight, marginBottom);
        view.requestLayout();
    }
}
于 2021-01-12T15:24:56.730 に答える
0

この方法を使用して、dpを正しく設定できます。

public int dpFormat(int dp) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

その後、電話します

setMargins(dpFormat(15), dpFormat(15), dpFormat(15), dpFormat(15));
于 2021-09-17T19:54:34.243 に答える
0

Kotlinを使用して、

        yourLayoutId.updateLayoutParams<ViewGroup.MarginLayoutParams> {
            setMargins(15,15,15,15)
        }
于 2022-02-23T05:10:55.827 に答える
-1
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

FrameLayoutを継承し、そこにマージンを設定するため、linearLayoutにキャストする必要がありました。これにより、アクティビティは画面の一部にのみ表示され、の元のレイアウトパラメータとは異なる背景が表示されsetContentViewます。

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
linearLayout.setBackgroundColor(getResources().getColor(R.color.full_white));
setContentView(linearLayout,layoutParams);

同じアクティビティを使用し、別のメニューからアクティビティを開くことに基づいてマージンを変更するために働いた人は他にいませんでした!setLayoutParamsは私には機能しませんでした-デバイスは毎回クラッシュしていました。これらはハードコードされた番号ですが、これはデモンストレーションのみを目的としたコードの例にすぎません。

于 2019-02-15T13:21:19.433 に答える
-1

ViewGroup.MarginLayoutParams幅、高さ、余白を設定するために使用できます

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
marginLayoutParams.setMargins(0,16,0,16);
linearLayout.setLayoutParams(marginLayoutParams);

メソッドsetMargins();がそれぞれ左、上、右、下の値を取り込む場合。時計回りに!、左から。

于 2019-06-03T18:20:03.370 に答える