Đặt lề trong một chương trình tuyến tính theo chương trình


266

Tôi đang cố gắng sử dụng Java ( không phải XML ) để tạo một linearLayout với các nút lấp đầy màn hình và có lề. Đây là mã hoạt động mà không có lề:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Vì vậy, nó hoạt động tốt, nhưng làm thế nào trên trái đất bạn cung cấp cho các nút lề để có không gian giữa chúng? Tôi đã thử sử dụng LinearLayout.MarginLayoutParams, nhưng nó không có weightthành viên nên không tốt. Và nó cũng không hoạt động nếu bạn vượt qua nó lptrong hàm tạo của nó.

Điều này là không thể? Bởi vì nó chắc chắn trông nó và nó sẽ không phải là nhiệm vụ bố trí Android đầu tiên bạn chỉ có thể làm trong XML.


1
developer.android.com/reference/android/view/ Mạnh, int, int, int) Thay vì layoutParams.setMargins (30, 20, 30, 0); bạn đặt layoutParams.setMargins (30dp, 20dp, 30dp, 0dp);
DarthestVader

3
setMargins lấy int làm đối số .. bạn chỉ có thể cung cấp "dp" bằng cách sử dụng xml attributtes
jyavenard

Câu trả lời:


496

Đây là một ít mã để thực hiện nó:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);

6
cảm ơn về một mẫu mã điểm - có lợi hơn nhiều so với chỉ mô tả
Ai đó ở đâu đó vào

25
Có vẻ như các thông số lề được đặt theo pixel. Bất kỳ cách nào để đặt chúng trong dps?
Artem Russakovskii

30
@ArtemRussakovskii Giống như hầu hết các chức năng trong Android, chúng lấy pixel. Tôi đề nghị một chức năng tiện ích toàn cầu chuyển đổi dips thành px. Đây là những gì tôi đã làm trong tất cả các ứng dụng của mình. API Android hút.
mxcl

7
@MaxHowell Đó là những gì tôi đã làm. Thật đáng kinh ngạc khi những thứ cơ bản như thế đôi khi bị thiếu.
Artem Russakovskii

5
@ArtemRussakovskii - sử dụng TypedValue.applyDimension (...) để chuyển đổi DIP thành PX. Xem stackoverflow.com/questions/2238883/
Mạnh

64

Vì vậy, nó hoạt động tốt, nhưng làm thế nào trên trái đất bạn cung cấp cho các nút lề để có không gian giữa chúng?

Bạn gọi setMargins()trên LinearLayout.LayoutParamsđối tượng.

Tôi đã thử sử dụng linearLayout.MarginLayoutParams, nhưng nó không có thành viên trọng lượng nên không tốt.

LinearLayout.LayoutParamslà một lớp con của LinearLayout.MarginLayoutParams, như được chỉ ra trong tài liệu .

Điều này là không thể?

Không.

đây không phải là nhiệm vụ bố trí Android đầu tiên bạn chỉ có thể thực hiện trong XML

Bạn được chào đón để cung cấp bằng chứng của yêu cầu này.

Cá nhân, tôi không biết bất cứ điều gì chỉ có thể được thực hiện thông qua XML và không thông qua các phương thức Java trong SDK. Trong thực tế, theo định nghĩa, mọi thứ phải có thể thực hiện được thông qua Java (mặc dù không nhất thiết phải thông qua các phương thức có thể truy cập SDK), vì XML không phải là mã thực thi. Nhưng, nếu bạn biết điều gì đó, hãy chỉ ra điều đó, bởi vì đó là một lỗi trong SDK sẽ được khắc phục vào một ngày nào đó.


2
Ha, ok tôi hiểu rồi. Đã bị mất một chút trong hệ thống bố trí khá phức tạp. Tôi không nghĩ có cách nào để thiết lập layout_widgth / height khi chạy.
Timmmm

2
Và không có cách nào để thiết lập kiểu: stackoverflow.com/questions/2016249/iêu
Timmmm

1
Tôi chưa gặp vấn đề với việc thiết lập chiều rộng và chiều cao khi chạy qua LayoutPararms. Tôi nói về phong cách ... vâng, có một lý do tôi không sử dụng chúng. :-)
CommonsWare

6
Tôi muốn biết lý do tại sao một Pita như vậy để lập trình UI một cách lập trình
Ai đó ở đâu đó vào

3
Mất nhiều năm tôi mới nhận ra, điều đó còn nguyên vẹn vài ngày trước tôi đã nhập vào LayoutParams sai không hỗ trợ Margins ... Đọc những câu trả lời này tôi quyết định loại bỏ việc nhập của mình. Có hơn 10 tùy chọn D: Tôi đã chọn linearLayout.LayoutParams. Làm.
Doomsknight

31

Để thêm lề trực tiếp vào các mục (một số mục cho phép chỉnh sửa lề trực tiếp), bạn có thể làm:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

... cái này hoạt động mà không cần biết về / chỉnh sửa bố cục xung quanh. Lưu ý kiểm tra "instanceof" trong trường hợp bạn thử và chạy cái này với thứ gì đó không hỗ trợ lề.


2
Chính xác là tôi đang tìm kiếm.
djdance

21

Do sự thay đổi về mật độ pixel màn hình thiết bị, tốt nhất là luôn luôn sử dụng DIPđơn vị để đặt lề theo chương trình. Thích bên dưới_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

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


10

Tôi đã thiết lập lề trực tiếp bằng cách sử dụng mã dưới đây

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Điều duy nhất ở đây là lưu ý rằng LayoutParamsnên được nhập cho gói sau android.widget.RelativeLayout.LayoutParams, nếu không sẽ có lỗi.


7

Thử cái này

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

7
 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);

2
Trong khi mã này có thể trả lời câu hỏi, tốt hơn là bao gồm phần giải thích mã ở đây.
xenteros

4

Thử cái này:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;

3
/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

bạn nên lưu trữ loại khung nhìn của viewgroup. Ví dụ, trong đoạn mã trên, tôi muốn thay đổi lề của frameLayout và nhóm khung nhìn của frameLayout là RelativeLayout, vì vậy bạn cần chuyển đổi sang (RelativeLayout.LayoutParams)


0

Đây là một giải pháp dòng duy nhất:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
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.