Trong Android, làm cách nào để đặt lề trong dp theo chương trình?


401

Trong này , nàynày chủ đề tôi đã cố gắng để tìm một câu trả lời về cách thiết lập lề trên một cái nhìn duy nhất. Tuy nhiên, tôi đã tự hỏi nếu không có cách nào dễ dàng hơn. Tôi sẽ giải thích lý do tại sao tôi không muốn sử dụng phương pháp này:

Tôi có một nút tùy chỉnh mở rộng nút. Nếu nền được đặt thành một cái gì đó khác với nền mặc định (bằng cách gọi một trong hai setBackgroundResource(int id)hoặc setBackgroundDrawable(Drawable d)), tôi muốn lề là 0. Nếu tôi gọi đây là:

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

Tôi muốn lề được đặt lại thành -3dp (Tôi đã đọc ở đây cách chuyển đổi từ pixel sang dp, vì vậy một khi tôi biết cách đặt lề trong px, tôi có thể tự mình quản lý chuyển đổi). Nhưng vì cái này được gọi trong CustomButtonlớp, nên cha mẹ có thể thay đổi từ linearLayout sang TableLayout, và tôi không muốn anh ta lấy cha mẹ của mình và kiểm tra ví dụ của cha mẹ đó. Điều đó cũng sẽ khá kém hiệu quả, tôi tưởng tượng.

Ngoài ra, khi gọi (sử dụng LayoutParams) parentLayout.addView(myCustomButton, newParams), tôi không biết liệu điều này có thêm nó vào đúng vị trí không (tuy nhiên chưa thử), hãy nói nút giữa của một hàng năm.

Câu hỏi: Có cách nào dễ dàng hơn để đặt lề của một Nút duy nhất theo chương trình bên cạnh việc sử dụng LayoutParams không?

EDIT: Tôi biết về cách LayoutParams, nhưng tôi muốn một giải pháp tránh xử lý từng loại container khác nhau:

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

Bởi vì this.getLayoutParams();lợi nhuận một ViewGroup.LayoutParams, mà không có các thuộc tính topMargin, bottomMargin, leftMargin, rightMargin. Ví dụ mc bạn thấy chỉ là một MarginContainertệp chứa lề (-3dp) và (oml, omr, omt, omb) và lề gốc (ml, mr, mt, mb).

Câu trả lời:


797

Bạn nên sử dụng LayoutParamsđể đặt lề nút:

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

Tùy thuộc vào bố cục bạn đang sử dụng, bạn nên sử dụng RelativeLayout.LayoutParamshoặc LinearLayout.LayoutParams.

Và để chuyển đổi số đo dp của bạn thành pixel, hãy thử điều này:

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);

152
Từ gói nào tôi nên nhập vào LayoutParams cụ thể đó?
tàng hình

7
setMargins đã sử dụng px và bạn sẽ sử dụng dp, chuyển đổi của tôi là đúng: dp -> px để đặt giá trị lề chính xác.
throrin19

6
@ChristiaandeJong RelativeLayout.LayoutParams
stoefln 26/03/13

15
nó phụ thuộc vào cách bố trí hiện tại của bạn. Nếu bạn đang ở trong linearLayout, hãy sử dụng linearLayout.LayoutParams. RelativeLayout.LayoutParams nếu không
throrin19

5
bạn nên nhập layoutParams là bố cục cha mẹ cũ của bạn. <linearlayout> <relat khóayout> <Gridlayout> và bạn đang làm việc với bố cục lưới. sau đó, bạn cần sử dụng
relateelsayout.layoutparams

228

LayoutParams - KHÔNG LÀM VIỆC! ! !

Cần sử dụng loại: MarginLayoutParams

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

Ví dụ mã cho MarginLayoutParams:

http://www.codota.com/android/groupes/android.view.Viewgroup.MarginLayoutParams


19
Đúng, nhưng không cần thiết lập lại, các thông số đã thay đổi sẽ tự động được phản ánh. Do đó, bạn có thể xóa dòng: vector8.setLayoutParams (params);
Wirsing

LayaoutParams thường tạo ra sự nhầm lẫn trong khi thiết lập lề ... Vì vậy, MarginLayoutParams này rất hữu ích. Cảm ơn
Atul Bhardwaj

4
bạn cần phải thiết lậpLoutoutParams (params) sau khi thay đổi
lề

tôi đã tìm thấy MarginLayoutParams là lớp mới hôm nay # Cảm ơn.
Tushar Pandey

Không hoạt động để Buttonxem: ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams()trả vềnull
Konstantin Konopko

118

Cách tốt nhất từng có:

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

Cách gọi phương thức:

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

Hy vọng điều này sẽ giúp bạn.


1
tôi đang gặp vấn đề khi tôi đặt setMargins (chủ.v.venter, 0, 20, 0,0); Như thế này, lề trái của nó cả hai bên (trên và dưới) có gì sai với các thông số trên?
Arbaz.in

1
Câu trả lời hoàn hảo tuyệt vời !! Cảm ơn bạn!!
Sjd

33
int sizeInDP = 16;

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

Sau đó

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

Hoặc là

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

15

Đây là câu trả lời tất cả trong một với các bản cập nhật gần đây:

Bước 1, để cập nhật ký quỹ

Ý tưởng cơ bản là lấy lề ra và sau đó cập nhật nó. Bản cập nhật sẽ được áp dụng tự động và bạn không cần thiết lập lại. Để có được các tham số bố trí, chỉ cần gọi phương thức này:

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

Sự LayoutParamsxuất phát từ cách bố trí của bạn. Nếu chế độ xem là từ bố cục tuyến tính, bạn cần nhập LinearLayout.LayoutParams. Nếu bạn sử dụng bố trí tương đối, nhập khẩu LinearLayout.LayoutParams, vv

Bây giờ, nếu bạn thiết lập lề bằng Layout_marginLeft, Right, vv, bạn cần phải cập nhật lề theo cách này

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

Nếu bạn đặt lề bằng cách sử dụng mới layout_marginStart, bạn cần cập nhật lề theo cách này

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

Bước 2, để cập nhật ký quỹ trong dp

Tất cả hai cách cập nhật lề trên đều được cập nhật bằng pixel. Bạn cần thực hiện một bản dịch từ dp sang pixel.

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

Bây giờ đặt giá trị được tính cho các hàm cập nhật lề ở trên và bạn sẽ được thiết lập tất cả


9

layout_margin là một ràng buộc mà một đứa trẻ xem nói với cha mẹ của nó. Tuy nhiên, vai trò của cha mẹ là chọn có cho phép ký quỹ hay không. Về cơ bản bằng cách đặt android: layout_margin = "10dp", đứa trẻ đang nài nỉ nhóm xem cha mẹ để phân bổ không gian lớn hơn 10dp so với kích thước thực tế của nó. (mặt khác, padding = "10dp", có nghĩa là chế độ xem con sẽ làm cho nội dung của chính nó nhỏ hơn 10dp .)

Do đó, không phải tất cả các Viewgroup đều tôn trọng lề . Ví dụ nổi tiếng nhất sẽ là listview, trong đó lề của các mục bị bỏ qua. Trước khi bạn gọi setMargin()đến LayoutParam, bạn phải luôn đảm bảo rằng chế độ xem hiện tại đang tồn tại trong Viewgroup hỗ trợ lề (ví dụ: linearLayouot hoặc RelativeLayout) và đưa ra kết quả của getLayoutParams()LayoutParams cụ thể mà bạn muốn. ( ViewGroup.LayoutParamsthậm chí không có setMargins()phương pháp!)

Các chức năng dưới đây nên làm thủ thuật. Tuy nhiên, hãy đảm bảo bạn thay thế RelativeLayout thành kiểu của khung nhìn cha.

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

9

Phương pháp này sẽ cho phép bạn thiết lập Margin trong 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);
}

CẬP NHẬT

Bạn có thể thay đổi tham số phù hợp với nhu cầu của bạn.


8

Trong Kotlin nó sẽ trông như thế này:

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

3

Khi bạn ở Chế độ xem tùy chỉnh, bạn có thể sử dụng getDimensionPixelSize(R.dimen.dimen_value), trong trường hợp của tôi, tôi đã thêm lề trong LayoutParams được tạo trêninit phương thức.

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

trong 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

Sử dụng phương pháp này để đặt lề trong 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();
    }
}

gọi phương thức:

setMargins(linearLayout,5,0,5,0);

1

Để sử dụng thiết lập một dòng nhanh chóng

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

nhưng hãy cẩn thận cho bất kỳ việc sử dụng sai đối với LayoutParams, vì điều này sẽ không có ifví dụ thống kê chech


1

Đã tạo một chức năng mở rộng Kotlin cho những người bạn có thể thấy nó tiện dụng.

Hãy chắc chắn để vượt qua trong pixel không dp. Chúc mừng mã hóa :)

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

Trong ví dụ của tôi, tôi đang thêm ImageView vào linearLayout theo chương trình. Tôi đã đặt lề trên và dưới thành ImagerView. Sau đó thêm ImageView vào 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

Bạn có thể sử dụng phương pháp này và đặt độ mờ tĩnh như 20 nó chuyển đổi theo thiết bị của bạn

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

0

Như ngày nay, tốt nhất có lẽ là sử dụng Paris , một thư viện được cung cấp bởi AirBnB.

Kiểu sau đó có thể được áp dụng như thế này:

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

nó cũng hỗ trợ chế độ xem tùy chỉnh (nếu bạn mở rộng chế độ xem) bằng cách sử dụng chú thích:

@Styleable and @Style

0

Bạn phải gọi

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

như vậy your_view.setPadding(0,16,0,0)

Những gì bạn đang cố gắng sử dụng chỉ là getter.

Studio Android cho thấy những gì padding...() thực sự có nghĩa trong java:

ví dụ đệm Hình ảnh cho thấy nó chỉ gọigetPadding...()

Nếu bạn muốn thêm một lề vào TextView của mình, bạn sẽ phải vào 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);

Tôi đã phải sử dụng khai thác FrameLayoutcho linearLayout vì nó kế thừa từ nó và đặt lề ở đó để hoạt động chỉ xuất hiện trên một phần của màn hình cùng với một nền khác với các thông số bố cục ban đầu trong 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);

Không ai trong số những người khác làm việc để sử dụng cùng một hoạt động và thay đổi lề dựa trên việc mở hoạt động từ một menu khác! setLayoutParams không bao giờ làm việc cho tôi - thiết bị sẽ bị sập mỗi lần. Mặc dù đây là những số được mã hóa cứng - đây chỉ là một ví dụ về mã cho mục đích trình diễn.


-1

Bạn có thể sử dụng ViewGroup.MarginLayoutParamsđể đặt chiều rộng, chiều cao và lề

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

Trong đó phương thức setMargins();lấy các giá trị tương ứng cho trái, trên, phải, dưới. Theo chiều kim đồng hồ!, Bắt đầu từ bên trái.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.