web-dev-qa-db-ja.com

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

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

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に変換する方法を読んだので、pxで余白を設定する方法がわかったら、自分で変換を管理できます)。しかし、これはCustomButtonクラスで呼び出されるので、親はLinearLayoutからTableLayoutまでさまざまであり、私は彼に自分の親を取得させてその親のインスタンスをチェックさせたくはありません。それもまたかなり不調であると思います。

また、(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();は、topMarginbottomMarginleftMarginrightMarginという属性を持たないViewGroup.LayoutParamsを返すためです。あなたが見るmcインスタンスは、オフセット(-3dp)のマージンと(oml、omr、omt、omb)とオリジナルのマージン(ml、mr、mt、mb)を含むMarginContainerです。

342
stealthjong

ボタンの余白を設定するには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()
);
683
throrin19

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

192
Lyusten Elder

史上最高の方法:

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

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

97
Hiren Patel
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);
28
sagits

これが最近の更新とのオールインワンの答えです。

マージンを更新するためのステップ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;

計算された値を上記のマージン更新関数に入力すると、すべて設定されます。

8
Fangming

この方法で Margin _ 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);
}

_アップデート_

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

7
neferpitou

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

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

以下の関数がうまくいくはずです。 ただし、必ず親ビューのタイプにRelativeLayoutを代入してください。

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}
7
Ian Wong

あなたがカスタムビューにいるとき、あなたは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);
    }
}
2
aldajo92

簡単な一行設定のために

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

しかし、これはifステートメントインスタンスがないので、LayoutParamsを誤って使用した場合は注意してください。

1
Dasser Basyouni

私の例では、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);

0
Rajeev

それが便利であると思うかもしれないあなたのそれらのための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 }
            }
}
0
David Kim

この方法を使って、あなたのデバイスに合わせて変換される20のような静的二次元を置くことができます

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

今日のように、最善の方法はおそらくAirBnBが提供する Paris ライブラリを使うことです。

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

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

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

@Styleable and @Style
0
sonique

更新しました:

ViewGroup.LayoutParamsを使ってレイアウトの幅と高さを設定した方法と同じです。

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();はそれぞれleft、top、right、bottomの値を取ります。左から時計回りに!.

0
mmmcho

この方法を使用して、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);
0
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

それを継承し、そこに余白を設定して、アクティビティがFrameLayoutの元のレイアウトパラメータとは異なる背景と一緒に画面の一部にのみ表示されるように、私は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は私のために働きませんでした - デバイスは毎回クラッシュするでしょう。これらはハードコードされた数字ですが - これはデモンストレーション目的のためのコードの例にすぎません。

0
ali mcnamara