development

안드로이드에서 프로그래밍 방식으로 dp의 여백을 어떻게 설정합니까?

big-blog 2020. 2. 27. 22:23
반응형

안드로이드에서 프로그래밍 방식으로 dp의 여백을 어떻게 설정합니까?


에서 , 스레드가 I 단일 뷰에 여백을 설정하는 방법에 대한 답을 찾기 위해 노력했다. 그러나 더 쉬운 방법이 없는지 궁금했습니다. 왜이 접근법을 사용하고 싶지 않은지 설명 할 것입니다.

버튼을 확장하는 사용자 정의 버튼이 있습니다. 배경이 기본 배경이 아닌 다른 것으로 설정되면 ( setBackgroundResource(int id)또는 을 호출하여 setBackgroundDrawable(Drawable d)) 여백을 0으로 설정하고 싶습니다.

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

나는 여백 (나는 이미 읽은 -3dp을 재설정하려면 여기 내가 픽셀의 세트 마진, 나는 전환이 자신을 관리 할 수있는 방법을 알고 그래서 일단, DP에 픽셀로 변환하는 방법). 그러나 이것은 CustomButton클래스 에서 호출 되므로 부모는 LinearLayout에서 TableLayout까지 다양 할 수 있으며 부모에게 부모를 가져 와서 부모의 인스턴스를 확인하지는 않을 것입니다. 그것은 또한 상당히 성능이 떨어질 것입니다.

또한 (LayoutParams 사용) 호출 할 때 parentLayout.addView(myCustomButton, newParams)올바른 위치에 추가하는지 (아직 시도하지는 않았 음) 알지 못합니다 .5 행의 가운데 버튼을 말합니다.

질문 : LayoutParams를 사용하는 것 외에 프로그래밍 방식으로 단일 Button의 여백을 설정하는 더 쉬운 방법이 있습니까?

편집 : 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속성이없는, topMargin, bottomMargin, leftMargin, rightMargin. 표시되는 mc 인스턴스 MarginContainer는 오프셋 (-3dp) 여백과 (oml, omr, omt, omb) 및 원래 여백 (ml, mr, mt, mb)을 포함하는 것입니다.


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

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


가장 좋은 방법 :

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

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


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

최근 업데이트 된 올인원 답변입니다.

1 단계, 여백 업데이트

기본 아이디어는 여백을 얻은 다음 업데이트하는 것입니다. 업데이트가 자동으로 적용되므로 다시 설정할 필요가 없습니다. 레이아웃 매개 변수를 얻으려면이 메소드를 호출하십시오.

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

LayoutParams보기의 레이아웃에서 온다. 뷰가 선형 레이아웃에서 가져온 경우을 가져와야 LinearLayout.LayoutParams합니다. 상대 레이아웃을 사용하는 경우 import LinearLayout.LayoutParams

다음을 사용하여 여백을 설정하면 이제 Layout_marginLeft, Right등,이 방법으로 업데이트 여유 필요

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

new를 사용하여 여백을 설정하면 다음과 같이 여백 layout_marginStart을 업데이트해야합니다.

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

2 단계, dp의 여백 업데이트

위의 여백을 업데이트하는 두 가지 방법은 모두 픽셀 단위로 업데이트하는 것입니다. dp를 픽셀로 변환해야합니다.

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

이제 계산 된 값을 위의 여백 업데이트 기능에 넣으십시오.


layout_margin은 뷰 자식이 부모에게 알려주는 제약 조건입니다. 그러나 마진을 허용할지 여부를 선택하는 것이 부모의 역할입니다. 기본적으로 android : layout_margin = "10dp"를 설정함으로써 자식은 부모보기 그룹 이 실제 크기보다 10dp 큰 공간을 할당하도록 탄원합니다 . (padding = "10dp"는 반면에 자식 뷰가 자체 컨텐츠를 10dp 작게 만듭니다.)

결과적으로 모든 ViewGroup이 margin을 존중하는 것은 아닙니다 . 가장 악명 높은 예는 항목의 여백이 무시되는 listview입니다. setMargin()LayoutParam 을 호출하기 전에 항상 현재 뷰가 여백을 지원하는 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);
}

이 방법을 사용하면 설정하게됩니다 여백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);
}

최신 정보

필요에 따라 매개 변수를 변경할 수 있습니다.


사용자 정의보기 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)
}

자바에서 :

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

이 방법을 사용하여 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);

빠른 한 줄 설정 사용

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

그러나 레이아웃 if인스턴스 chech 가 없으므로 LayoutParams에 잘못 사용하기에 충분하지 않습니다.


편리하다고 생각되는 사람들을 위해 Kotlin Extension 기능을 만들었습니다.

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

내 예에서는 프로그래밍 방식으로 LinearLayout에 ImageView를 추가하고 있습니다. 위쪽 및 아래쪽 여백을 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);


이 방법을 사용하고 장치에 따라 변환되는 20과 같은 정적 치수를 넣을 수 있습니다

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

오늘처럼 AirBnB에서 제공하는 라이브러리 인 Paris 를 사용하는 것이 가장 좋습니다 .

그런 다음 스타일을 다음과 같이 적용 할 수 있습니다.

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

또한 주석을 사용하여 사용자 정의보기 (보기를 확장하는 경우)를 지원합니다.

@Styleable and @Style

Kotlin에서는 다음과 같습니다.

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

당신은 전화해야 setPadding(int left, int top, int right, int bottom)

이렇게 : your_view.setPadding(0,16,0,0)

사용하려는 것은 게터뿐입니다.

안드로이드 스튜디오는 padding...()실제로 자바에서 의미하는 것을 보여줍니다 .

! 패딩 예제 이미지는 호출 만 표시합니다.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


((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는 나를 위해 결코 작동하지 않았습니다-장치는 매번 충돌합니다. 이 코드는 하드 코드 된 숫자이지만 데모 용 코드의 예일뿐입니다.


업데이트 :

레이아웃 너비와 높이를 설정하는 방법과 마찬가지로 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();가 각각 왼쪽, 위쪽, 오른쪽, 아래쪽의 값을 가져옵니다. 왼쪽에서 시작하여 시계 방향으로!

참고 : https://stackoverflow.com/questions/12728255/in-android-how-do-i-set-margins-in-dp-programmatically



반응형