studio - En Android, ¿cómo establezco los márgenes en dp mediante programación?
padding android studio (11)
En this , this y this hilo traté de 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 usar este enfoque:
Tengo un botón personalizado que extiende el botón. Si el fondo se configura en un valor diferente al del 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í here cómo convertir de píxeles a dp, así que una vez que sepa cómo establecer márgenes en px, puedo administrar la conversión yo mismo). Pero como esto se llama en la clase CustomButton
, el padre puede variar de LinearLayout a TableLayout, y prefiero que no obtenga a su padre y verifique la instancia de ese padre. Eso también será bastante inoportuno, me imagino.
Además, al llamar (usando LayoutParams) parentLayout.addView(myCustomButton, newParams)
, no sé si esto lo agrega a la posición correcta (no lo he intentado), diga el botón central de una fila de cinco.
Pregunta: ¿Hay alguna forma más fácil de configurar el margen de un solo botón programáticamente además de usar LayoutParams?
EDIT: Sé de la manera de LayoutParams, pero me gustaría una solución que evite el manejo de 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 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).
Aquí está la respuesta todo en uno con las 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 que la vuelva a configurar. Para obtener los parámetros de diseño, simplemente llame a este método:
LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();
El LayoutParams
proviene del diseño de su vista. Si la vista es de un diseño lineal, necesita importar LinearLayout.LayoutParams
. Si usa un diseño relativo, importe LinearLayout.LayoutParams
, etc.
Ahora, si establece el margen usando Layout_marginLeft
, Right
, etc., necesita actualizar el margen de esta manera
layoutParams.setMargins(left, top, right, bottom);
Si establece el margen usando el nuevo layout_marginStart
, necesita 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 configurado
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
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);
}
}
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);
Dependiendo del diseño que esté utilizando, debe usar RelativeLayout.LayoutParams
o LinearLayout.LayoutParams
.
Y para convertir tu medida dp a píxel, prueba esto:
Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
yourdpmeasure,
r.getDisplayMetrics()
);
Este método le 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.
La mejor manera nunca
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á.
LayoutParams - ¡NO FUNCIONA! ! !
Necesita uso 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
Para un uso rápido de configuración de una línea
((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);
pero tenga cuidado para cualquier uso incorrecto de LayoutParams, ya que esto no tendrá ninguna instancia de declaración if
chech
Utilice 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();
}
}
llama al método:
setMargins(linearLayout,5,0,5,0);
layout_margin es una restricción que un niño de vista le dice a su padre. Sin embargo, es función de los padres elegir si se permite o no el margen. Básicamente, al configurar android: layout_margin = "10dp", el niño está pidiendo al grupo de vista principal que asigne un espacio que sea 10dp más grande que su tamaño real. (padding = "10dp", por otro lado, significa que la vista secundaria hará que su propio contenido sea 10dp más pequeño ).
En consecuencia, no todos los ViewGroups respetan el margen . El ejemplo más notorio sería listview, donde se ignoran los márgenes de los elementos. Antes de llamar a setMargin()
a un LayoutParam, siempre debe asegurarse de que la vista actual esté viviendo en un ViewGroup que admita un margen (por ejemplo, LinearLayouot o RelativeLayout), y getLayoutParams()
el resultado de getLayoutParams()
en el LayoutParams específico que desee. ( ViewGroup.LayoutParams
ni siquiera tiene el método setMargins()
!)
La siguiente función debe 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);
}
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);