Androidでは、プログラムでdpのマージンをどのように設定しますか?


401

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

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

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

余白を-3dpにリセットしたい(ピクセルからdpに変換する方法についてはここで既に読んだので、pxで余白を設定する方法を知ったら、自分で変換を管理できる)。しかし、これはCustomButtonクラスで呼び出されるため、親はLinearLayoutからTableLayoutに変化する可能性があり、私はむしろ彼に彼の親を取得してその親のインスタンスをチェックすることを望まないでしょう。それはまた、かなりパフォーマンスが悪いと思います。

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

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

編集:私は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();戻りViewGroup.LayoutParams属性を持っていません、topMarginbottomMarginleftMarginrightMargin。表示されるmcインスタンスは、MarginContainerオフセット(-3dp)マージンと(oml、omr、omt、omb)と元のマージン(ml、mr、mt、mb)を含む単なるa です。

回答:


797

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

152
特定のLayoutParamsをどのパッケージからインポートする必要がありますか?
ステルスジョン

7
setMarginsはpxを使用し、dpを使用します。私の変換は正しいです:dp-> pxで正しいマージン値を設定します。
throrin19 2012年

6
@ChristiaandeJong RelativeLayout.LayoutParams
stoefln 2013年

15
現在のレイアウトによって異なります。LinearLayoutを使用している場合は、LinearLayout.LayoutParamsを使用します。それ以外の場合はRelativeLayout.LayoutParams
throrin19

5
親レイアウトexであるlayoutParamsをインポートする必要があります。<linearlayout> <relativelayout> <gridlayout>そしてグリッドレイアウトで作業しています。次に、relativelayout.layoutparamsを使用する必要があります
Sruit A.Suk

228

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


19
正しいが、元に戻す必要はありません。変更されたパラメータは自動的に反映されます。したがって、次の行を削除できます。vector8.setLayoutParams(params);
2014年

LayaoutParamsは通常、マージンの設定中に混乱を引き起こします...したがって、このMarginLayoutParamsは非常に便利です。ありがとう
Atul Bhardwaj

4
margingの変更後にsetLayoutParams(params)を実行する必要があります
Leo Droidcoder

今日、MarginLayoutParamsを新しいクラスとして見つけました。
Tushar Pandey 2017

Buttonビューでは機能しません:ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams()リターンnull
Konstantin Konopko '16

118

史上最高の方法:

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

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


1
setMargins(holder.vCenter、0、20、0,0);を設定すると問題が発生します。このように、その左側と左側のマージン(上部と下部)は上記のパラメーターの何が問題になっていますか?
Arbaz.18年

1
素晴らしい完璧な答え!! ありがとうございました!!
Sjd

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

15

以下は、最近の更新に関するオールインワンの回答です。

ステップ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;

次に、計算された値を上記のマージン更新関数に入れます。


9

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

したがって、すべてのViewGroupsがmarginを尊重するわけではありません。最も悪名高い例は、アイテムのマージンが無視されるリストビューです。setMargin()LayoutParam を呼び出す前に、現在のビューがマージンをサポートする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);
}

9

このメソッドでは、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);
}

更新

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


8

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

val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams

3

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

コトリンで

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

1

このメソッドを使用して、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);

1

迅速な1行セットアップの使用

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

ただし、これにはif文のインスタンスチェックがないため、LayoutParamsを誤って使用した場合は、carfullにしてください。


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

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

1

あなたはこの方法を使用し、デバイスに応じて変換する20のような静的な次元を置くことができます

 public static int dpToPx(int dp) 
      {
          float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
  }

0

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

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

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

また、アノテーションを使用したカスタムビュー(ビューを拡張する場合)もサポートします。

@Styleable and @Style

0

あなたは電話しなければなりません

setPadding(int left, int top, int right, int bottom)

そのようです: your_view.setPadding(0,16,0,0)

あなたが使おうとしているのはゲッターだけです。

Androidスタジオはpadding...()、Javaで実際に何を意味するかを示しています。

パディングの例 画像は呼び出しのみを示していますgetPadding...()

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

-1
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

FrameLayoutlinearLayoutから継承し、そこにマージンを設定して、アクティビティが画面の一部にのみ表示され、元のレイアウトパラメータとは異なる背景が表示されるように、地雷をキャストする必要がありました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が機能しなかった-デバイスが毎回クラッシュする。これらはハードコードされた数値ですが、これはデモンストレーションのみを目的としたコードの例にすぎません。


-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();がそれぞれ左、上、右、下の値を受け取る場所。左から時計回りに!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.