프로그래밍 방식으로 LinearLayout에서 여백 설정


266

화면을 채우고 여백이있는 버튼으로 LinearLayout을 만들기 위해 XML이 아닌 Java를 사용하려고합니다 . 여백없이 작동하는 코드는 다음과 같습니다.

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

그래서 그것은 잘 작동하지만 어떻게 지구상에서 버튼 사이에 공간이 있도록 버튼 여백을 제공합니까? 나는 사용하여 시도 LinearLayout.MarginLayoutParams,하지만 전혀 없다 weight가 더 좋은 없습니다 있도록 회원. 그리고 lp생성자에서도 전달하면 작동하지 않습니다 .

불가능합니까? 외관상으로는 XML에서만 할 수있는 최초의 안드로이드 레이아웃 작업이 아니기 때문입니다.


1
developer.android.com/reference/android/view/… , int, int, int) layoutParams.setMargins (30, 20, 30, 0) 대신에; layoutParams.setMargins (30dp, 20dp, 30dp, 0dp);
DarthestVader

3
setMargins 경우에만 XML을 attributtes 사용 "DP"를 제공 할 수 있습니다 .. 인수로 INT 소요
jyavenard을

답변:


496

그것을 달성하기위한 작은 코드는 다음과 같습니다.

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
포인트 코드 샘플 덕분입니다-설명보다 더 유익한 방법
누군가 어딘가에

25
여백 매개 변수가 픽셀로 설정된 것처럼 보입니다. dps로 설정하는 방법이 있습니까?
Artem Russakovskii

30
@ArtemRussakovskii 안드로이드의 대부분의 기능과 마찬가지로 픽셀을 사용합니다. 딥을 px로 변환하는 전역 유틸리티 함수를 제안합니다. 이것이 내가 모든 앱에서 한 일입니다. 안드로이드 API는 짜증 난다.
mxcl

7
@MaxHowell 그게 내가 끝났어. 그런 기본적인 것들이 때때로 빠지는 것은 믿어지지 않습니다.
Artem Russakovskii

5
@ArtemRussakovskii-DIP를 PX로 변환하려면 TypedValue.applyDimension (...)을 사용하십시오. 참조 stackoverflow.com/questions/2238883/...
가우 탐

64

그래서 그것은 잘 작동하지만 어떻게 지구상에서 버튼 사이에 공간이 있도록 버튼 여백을 제공합니까?

당신 setMargins()LinearLayout.LayoutParams개체를 호출 합니다.

LinearLayout.MarginLayoutParams를 사용해 보았지만 가중치 멤버가 없으므로 좋지 않습니다.

LinearLayout.LayoutParams문서에LinearLayout.MarginLayoutParams 표시된대로 의 하위 클래스입니다 .

불가능합니까?

아니.

XML에서만 할 수있는 첫 번째 안드로이드 레이아웃 작업은 아닙니다.

이 주장에 대한 증거를 제공 할 수 있습니다.

개인적으로, 나는 SDK의 Java 메소드가 아닌 XML을 통해서만 달성 할 수있는 것을 알지 못합니다. 실제로, XML은 실행 가능한 코드가 아니기 때문에 정의상 모든 것이 Java를 통해 수행 가능해야합니다 (SDK에 도달 할 수있는 방법은 아니지만). 그러나 무언가를 알고 있다면 언젠가 고쳐질 SDK의 버그이기 때문에 지적하십시오.


2
하, 알았어 이제 이해 했어 다소 복잡한 레이아웃 시스템에서 비트가 손실되었습니다. 어쨌든 layout_widgth / height를 런타임에 설정해야한다고 생각하지 않습니다.
Timmmm

2
스타일을 설정하는 방법은 없습니다 : stackoverflow.com/questions/2016249/…
Timmmm

1
를 통해 런타임에 너비와 높이를 설정하는 데 문제가 없었습니다 LayoutPararms. 나는 스타일의 용어 ... 그래, 내가 그것을 사용하지 않는 이유가있다. :-)
CommonsWare

6
나는 프로그래밍 방식으로 UI 생성에 그런 피타을 왜 알고 싶다
어딘가의 누군가가

3
사실 며칠 전에 여백을 지원하지 않는 잘못된 LayoutParams를 가져 왔다는 사실을 깨달았습니다.이 답변을 읽으면 가져 오기를 제거하기로 결정했습니다. 10 개가 넘는 옵션이 있습니다. D : linearLayout.LayoutParams에갔습니다. 공장.
Doomsknight

31

항목에 직접 여백을 추가하려면 (일부 항목에서 여백을 직접 편집 할 수 있음) 다음을 수행 할 수 있습니다.

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

... 이것은 주변 레이아웃을 알거나 편집 할 필요없이 작동합니다. 여백을 지원하지 않는 무언가에 대해 이것을 시도하고 실행하는 경우 "instanceof"검사에 유의하십시오.


2
정확히 내가 찾고 있습니다.
djdance

21

장치 화면 픽셀 밀도의 변화로 인해 항상 DIP단위를 사용 하여 프로그래밍 방식으로 여백을 설정 하는 것이 좋습니다 . 아래처럼

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

이것이 도움이되기를 바랍니다.


10

아래 코드를 사용하여 직접 여백을 설정했습니다.

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

여기에있는 것은 LayoutParams다음 패키지를 위해 가져와야 한다는 것을 알아야합니다. android.widget.RelativeLayout.LayoutParams그렇지 않으면 오류가 발생합니다.


7

이 시도

 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
“이 코드가 질문에 대답 할 수 있지만 여기에 코드에 대한 설명을 포함시키는 것이 좋습니다.
xenteros

4

이 시도:

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

위 코드에서 예를 들어 frameLayout의 여백을 변경하고 frameLayout의 뷰 그룹이 RelativeLayout 이므로 (RelativeLayout.LayoutParams) 을 은닉해야합니다.


0

여기에 한 줄 해결책 :

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.