En Android, ¿cómo configuro los márgenes en dp mediante progtwigción?

En esto , este y este hilo intenté encontrar una respuesta sobre cómo establecer los márgenes en una sola vista. Sin embargo, me preguntaba si no hay una manera más fácil. Explicaré por qué prefiero no utilizar este enfoque:

Tengo un botón personalizado que amplía el botón. Si el fondo está configurado en algo más que el fondo predeterminado (llamando a setBackgroundResource(int id) o setBackgroundDrawable(Drawable d) ), quiero que los márgenes sean 0. Si llamo a esto:

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

Quiero que los márgenes se restablezcan a -3dp (ya leí aquí cómo convertir de píxeles a dp, así que una vez que sé cómo establecer los márgenes en px, puedo administrar la conversión yo mismo). Pero como esto se llama en la clase CustomButton , el elemento principal puede variar de LinearLayout a TableLayout, y prefiero que no obtenga su padre y verifique la instancia de ese padre. Eso también será bastanteperformante, imagino.

Además, al llamar (usando LayoutParams) parentLayout.addView(myCustomButton, newParams) , no sé si esto lo agrega a la posición correcta (sin embargo, no lo he intentado), por ejemplo, el botón central de una fila de cinco.

Pregunta: ¿Hay alguna manera más fácil de establecer el margen de un solo botón programáticamente además de usar LayoutParams?

EDITAR: Conozco la forma de LayoutParams, pero me gustaría una solución que evite manejar cada tipo de contenedor diferente:

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

Porque this.getLayoutParams(); devuelve un ViewGroup.LayoutParams , que no tiene los atributos topMargin , bottomMargin , leftMargin , rightMargin . La instancia de mc que ve es solo un MarginContainer que contiene márgenes de compensación (-3dp) y (oml, omr, omt, omb) y los márgenes originales (ml, mr, mt, mb).

Debería usar LayoutParams para establecer los márgenes de sus botones:

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

Según el diseño que esté utilizando, debe usar RelativeLayout.LayoutParams o LinearLayout.LayoutParams .

Y para convertir su medida dp a píxel, intente esto:

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

LayoutParams – ¡NO FUNCIONA! ! !

Necesita usar el tipo de: MarginLayoutParams

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

Ejemplo de código para MarginLayoutParams:

http://www.codota.com/android/classes/android.view.ViewGroup.MarginLayoutParams

La mejor manera alguna vez:

 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ómo llamar al método:

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

Espero que esto te ayudará.

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

Entonces

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

O

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

layout_margin es una restricción que una vista secundaria le dice a su padre. Sin embargo, es la función de los padres elegir si se permite el margen o no. Básicamente al establecer android: layout_margin = “10dp”, el niño le pide al grupo de vista principal que asigne un espacio que es 10dp más grande que su tamaño real. (padding = “10dp”, por otro lado, significa que la vista secundaria reducirá su propio contenido 10 pb ).

En consecuencia, no todos los ViewGroups respetan el margen . El ejemplo más notorio sería listview, donde los márgenes de los artículos son ignorados. Antes de llamar a setMargin() a un LayoutParam, siempre debes asegurarte de que la vista actual está viviendo en un ViewGroup que admite margen (por ejemplo, LinearLayouot o Relative Lay) y lanzar el resultado de getLayoutParams() a los LayoutsParams específicos que deseas. ( ViewGroup.LayoutParams ni siquiera tiene el método setMargins() !)

La función a continuación debería hacer el truco. Sin embargo, asegúrese de sustituir RelativeLayout por el tipo de vista principal.

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

Aquí está la respuesta todo en uno con actualizaciones recientes:

Paso 1, para actualizar el margen

La idea básica es obtener margen y luego actualizarlo. La actualización se aplicará automáticamente y no es necesario volver a configurarla. Para obtener los parámetros de diseño, simplemente llame a este método:

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

LayoutParams proviene del diseño de su vista. Si la vista es de un diseño lineal, debe importar LinearLayout.LayoutParams . Si usa una disposición relativa, importe LinearLayout.LayoutParams , etc.

Ahora, si configura el margen usando Layout_marginLeft , Right , etc., debe actualizar el margen de esta manera

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

Si establece el margen utilizando el nuevo layout_marginStart , debe actualizar el margen de esta manera

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

Paso 2, para actualizar el margen en dp

Las dos formas de actualizar el margen anterior se actualizan en píxeles. Necesitas hacer una traducción de dp a píxeles.

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

Ahora ponga el valor calculado en las funciones de actualización de margen anteriores y debería estar todo listo

Este método te permitirá establecer el margen en 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); } 

ACTUALIZAR

Puede cambiar el parámetro que se adapte a sus necesidades.

Como hoy, lo mejor es probablemente usar Paris , una biblioteca proporcionada por AirBnB.

Los estilos se pueden aplicar así:

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

también admite la vista personalizada (si extiende una vista) usando anotaciones:

 @Styleable and @Style 

Use este método para establecer el margen en 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(); } } 

llamar al método:

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

Para una configuración rápida de una línea

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

pero sea cuidadoso con cualquier uso incorrecto de LayoutParams, ya que esto no tendrá if instancia de statement chech

Cuando está en una vista personalizada, puede usar getDimensionPixelSize(R.dimen.dimen_value) ; en mi caso, agregué el margen en LayoutParams creado en el método init .

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

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