안드로이드에서 프로그램적으로 dp에서 마진을 설정하려면 어떻게 해야 합니까?
이 스레드와 이 스레드에서 저는 단일 뷰에서 여백을 설정하는 방법에 대한 답을 찾으려고 했습니다.하지만, 저는 더 쉬운 방법이 없는지 궁금합니다.이 접근 방식을 사용하고 싶지 않은 이유를 설명하겠습니다.
단추를 확장하는 사용자 지정 단추가 있습니다.이 아닌 ("" "" " " " " " " " " (" 중 하나를 으로써)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
클래스, 부모는 선형 레이아웃에서 테이블 레이아웃에 따라 다를 수 있으며, 저는 그가 부모를 데려와서 해당 부모의 인스턴스를 확인하지 않도록 하고 싶습니다.제 생각에는 그것도 꽤 비효율적일 것 같습니다.
(LayoutParams) 호출 (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();
를 반환합니다.ViewGroup.LayoutParams
이 속이없것인 .topMargin
,bottomMargin
,leftMargin
,rightMargin
mc입니다.MarginContainer
여기에는 오프셋(-3dp) 여백과 (omml, omr, ommt, 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()
);
레이아웃 매개 변수 - 작동하지 않습니다!
필요한 사용 유형: 여유 레이아웃 매개 변수
MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;
여백 레이아웃 매개변수의 코드 예:
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);
Android KTX를 사용하면 다음과 같은 작업을 수행할 수 있습니다.
yourView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
setMargins(0, 0, 0, 0)
}
다음은 최근 업데이트에 대한 올인원 답변입니다.
1단계, 마진 업데이트
기본 아이디어는 마진을 뺀 다음 업데이트하는 것입니다.업데이트가 자동으로 적용되므로 다시 설정할 필요가 없습니다.레이아웃 매개 변수를 가져오려면 다음 메서드를 호출합니다.
LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();
그LayoutParams
보기 레이아웃에서 가져옵니다.뷰가 선형 레이아웃에서 가져온 경우, 다음 항목을 가져와야 합니다.LinearLayout.LayoutParams
레이아웃을 에는 상대레웃사경는우용하기, 오가져을아이를 가져옵니다.LinearLayout.LayoutParams
타기.
이 이다음사마설을 사용해서 하면,Layout_marginLeft
,Right
etc,', .
layoutParams.setMargins(left, top, right, bottom);
사용하여 layout_marginStart
.
layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);
2단계, dp 단위로 마진 업데이트
위의 마진을 업데이트하는 두 가지 방법은 모두 픽셀 단위로 업데이트됩니다.당신은 dp를 픽셀로 변환해야 합니다.
float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;
이제 위의 마진 업데이트 기능에 계산된 값을 입력하면 모든 설정이 완료됩니다.
코틀린에서는 다음과 같이 표시됩니다.
val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams
layout_module은 뷰 자식이 부모에게 알려주는 제약 조건입니다.하지만 마진을 허용할지 여부를 선택하는 것은 부모의 역할입니다.기본적으로 안드로이드:slid_dll="10dp"를 설정함으로써, 아이는 부모 뷰 그룹에 실제 크기보다 10dp 큰 공간을 할당해 달라고 간청합니다.(반면, "sigma="10dp"는 하위 보기가 자체 콘텐츠를 10dp 더 작게 만드는 것을 의미합니다.)
따라서 모든 보기 그룹이 마진을 존중하는 것은 아닙니다.가장 악명 높은 예는 항목의 여백이 무시되는 목록 보기입니다.전화하기 전에setMargin()
, 하고 LayoutParam의 .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);
}
갱신하다
필요에 따라 매개 변수를 변경할 수 있습니다.
당신은 이 방법을 사용하고 당신의 장치에 따라 변환되는 20개의 정적 치수를 넣을 수 있습니다.
public static int dpToPx(int dp)
{
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
간단한 Kotlin 확장 솔루션
모든/모든 면을 독립적으로 설정:
fun View.setMargin(left: Int? = null, top: Int? = null, right: Int? = null, bottom: Int? = null) {
val params = (layoutParams as? MarginLayoutParams)
params?.setMargins(
left ?: params.leftMargin,
top ?: params.topMargin,
right ?: params.rightMargin,
bottom ?: params.bottomMargin)
layoutParams = params
}
myView.setMargin(10, 5, 10, 5)
// or just any subset
myView.setMargin(right = 10, bottom = 5)
리소스 값을 직접 참조합니다.
fun View.setMarginRes(@DimenRes left: Int? = null, @DimenRes top: Int? = null, @DimenRes right: Int? = null, @DimenRes bottom: Int? = null) {
setMargin(
if (left == null) null else resources.getDimensionPixelSize(left),
if (top == null) null else resources.getDimensionPixelSize(top),
if (right == null) null else resources.getDimensionPixelSize(right),
if (bottom == null) null else resources.getDimensionPixelSize(bottom),
)
}
myView.setMarginRes(top = R.dimen.my_margin_res)
모든 면을 속성으로 동일하게 직접 설정하려면:
var View.margin: Int
get() = throw UnsupportedOperationException("No getter for property")
set(@Px margin) = setMargin(margin, margin, margin, margin)
myView.margin = 10 // px
// or as res
var View.marginRes: Int
get() = throw UnsupportedOperationException("No getter for property")
set(@DimenRes marginRes) {
margin = resources.getDimensionPixelSize(marginRes)
}
myView.marginRes = R.dimen.my_margin_res
특정 면을 직접 설정하려면 다음과 같은 특성 확장을 작성할 수 있습니다.
var View.leftMargin
get() = marginLeft
set(@Px leftMargin) = setMargin(left = leftMargin)
var View.leftMarginRes: Int
get() = throw UnsupportedOperationException("No getter for property")
set(@DimenRes leftMarginRes) {
leftMargin = resources.getDimensionPixelSize(leftMarginRes)
}
이것은 당신이 만들 수 있게 해줍니다.horizontal
또는vertical
변형도 포함됩니다.
var View.horizontalMargin
get() = throw UnsupportedOperationException("No getter for property")
set(@Px horizontalMargin) = setMargin(left = horizontalMargin, right = horizontalMargin)
var View.horizontalMarginRes: Int
get() = throw UnsupportedOperationException("No getter for property")
set(@DimenRes horizontalMarginRes) {
horizontalMargin = resources.getDimensionPixelSize(horizontalMarginRes)
}
되지 않은 전에 할 수 . 즉, " ": 마진설에실경렌패전우더너에즉빨수수다행있리할습니무고참링"
params == null
수정 내용을 다음으로 포장해 보십시오.myView.post{ margin = 10 }
그것이 내가 해온 방법입니다.kotlin
fun View.setTopMargin(@DimenRes dimensionResId: Int) {
(layoutParams as ViewGroup.MarginLayoutParams).topMargin = resources.getDimension(dimensionResId).toInt()
}
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
레이아웃 매개변수는 상대, 선형, 보기 또는 보기 그룹과 같은 레이아웃일 수 있습니다.필요에 따라 LayoutParams(레이아웃 파라미터)를 선택합니다.감사해요.
Kotlin과 함께 사용할 수 있습니다.View.updateLayoutParams
확장 기능:
yourView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
setMargins(15,15,15,15)
}
// or
yourView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = 15
}
이 방법을 사용하여 마진(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);
사용자 정의 보기에서 다음을 사용할 수 있습니다.getDimensionPixelSize(R.dimen.dimen_value)
저의 경우, 저는 LayoutParams에 여백을 추가했습니다.init
방법.
인 코틀린
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);
}
}
빠른 한 줄 설정을 위해 사용
((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);
하십시오. 에는 " " " "라는 단어가 때문입니다. 이 경우에는 사용할 수 없습니다.if
statement instance 인스턴스 체흐)
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 }
}
}
이 예에서는 선형 레이아웃에 ImageView를 프로그래밍 방식으로 추가하고 있습니다.이미저 보기에 위쪽 및 아래쪽 여백을 설정했습니다.그런 다음 이미지 보기를 선형 레이아웃에 추가합니다.
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);
작업 유틸리티는 관심 있는 사용자를 위해 DP를 사용하여 작동합니다.
public static void setMargins(Context context, View view, int left, int top, int right, int bottom) {
int marginLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, left, context.getResources().getDisplayMetrics());
int marginTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, top, context.getResources().getDisplayMetrics());
int marginRight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, right, context.getResources().getDisplayMetrics());
int marginBottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, bottom, context.getResources().getDisplayMetrics());
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
p.setMargins(marginLeft, marginTop, marginRight, marginBottom);
view.requestLayout();
}
}
다른 답변을 바탕으로 부모님을 식별하고 그에 따라 매개변수를 사용하는 일반 확장 기능을 만들었습니다.
//takes margin values as integer , eg for 12dp top , you will pass 12
fun View?.setMarginFromConstant(mLeft:Int, mTop:Int, mRight:Int, mBottom:Int){
this?.apply {
val left = context?.dpToPixel(mLeft)?:0
val top = context?.dpToPixel(mTop)?:0
val right = context?.dpToPixel(mRight)?:0
val bottom = context?.dpToPixel(mBottom)?:0
when (val params = this.layoutParams) {
is ConstraintLayout.LayoutParams -> {
params.marginStart = left
params.marginEnd = right
params.topMargin = top
params.bottomMargin = bottom
}
is FrameLayout.LayoutParams -> {
params.marginStart = left
params.marginEnd = right
params.topMargin = top
params.bottomMargin = bottom
}
is RecyclerView.LayoutParams -> {
params.marginStart = left
params.marginEnd = right
params.topMargin = top
params.bottomMargin = bottom
}
}
}
}
그리고.
fun Context.dpToPixel(dp: Int): Int =
(dp * applicationContext.resources.displayMetrics.density).toInt()
다른 상위 뷰 그룹에 대한 지원도 추가할 수 있습니다.
이 방법을 사용하여 dp를 올바르게 설정할 수 있습니다.
public int dpFormat(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
그리고 나서 전화합니다.
setMargins(dpFormat(15), dpFormat(15), dpFormat(15), dpFormat(15));
val params = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
params.setMargins(0, 0, 0, 400)
binding.container.setLayoutParams(params)
@Lyusten Elder의 답은 맞지만, 하기 전에 px를 dp로 변환해야 한다는 것을 잊지 마세요.
다음과 같이:
public static int getDpFromPx(Context context, float px) {
return Math.round(px * context.getResources().getDisplayMetrics().density);
}
현재로서는 에어비앤비에서 제공하는 도서관인 파리를 이용하는 것이 최선일 것입니다.
그런 다음 스타일을 다음과 같이 적용할 수 있습니다.
Paris.style(myView).apply(R.style.MyStyle);
또한 주석을 사용하여 사용자 정의 보기(보기를 확장하는 경우)를 지원합니다.
@Styleable and @Style
저는 View Group을 사용하고 있었습니다.테마 단추 구성요소의 레이아웃 매개변수입니다.View Group을 사용합니다.레이아웃 매개 변수가 setMargin을 사용할 수 없습니다.
대신 아래와 같이 마진 레이아웃 매개변수를 사용하면 저에게 효과가 있었습니다.
ViewGroup.MarginLayoutParams params =new ViewGroup.MarginLayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
params.setMargins(0,8,0,0);
저는 다음 코드가 작동했습니다.
buttonLinearLayout.layoutParams as MarginLayoutParams).apply
{
top.run {
topMargin = resources.getDimension(R.dimen.spacing).toInt()
}
}
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
linearLayout.setBackgroundResource(R.drawable.smartlight_background);
나는 내 것을 던져야 했습니다.FrameLayout
이 linearLayout의 .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.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();
왼쪽, 위쪽, 오른쪽, 아래쪽의 값을 각각 사용합니다.시계방향으로! 왼쪽부터 시작합니다.
언급URL : https://stackoverflow.com/questions/12728255/in-android-how-do-i-set-margins-in-dp-programmatically
'sourcecode' 카테고리의 다른 글
RMagick 2.13.1을 설치할 수 없습니다. MagickWand.h를 찾을 수 없습니다. (0) | 2023.06.02 |
---|---|
안드로이드 기기에서 apk 파일을 가져오려면 어떻게 해야 합니까? (0) | 2023.06.02 |
오토매퍼:새 개체를 만들지 않고 속성 값 업데이트 (0) | 2023.06.02 |
Gem native 확장을 빌드하지 못했습니다(Compass 설치). (0) | 2023.06.02 |
div 내에서 텍스트 수직 정렬 (0) | 2023.06.02 |