¿Cómo establecer el atributo layout_weight dinámicamente desde el código?

245

¿Cómo puedo establecer el valor del atributo layout_weightpara el botón en Android dinámicamente desde el código de Java?

Adham
fuente
Será muy similar a esta pregunta / respuesta: stackoverflow.com/questions/4638832/… y esta: stackoverflow.com/questions/4637233/…
Rich Schuler
Si ya ha definido la vista en el archivo de diseño (xml), la creación de nuevos LayoutParams sobrescribe otros parámetros definidos en el archivo xml. Así que primero debes usar "getLayoutParams". Ver respuesta completa stackoverflow.com/questions/4641072/…
Shirish Herwade

Respuestas:

463

Puede pasarlo como parte del LinearLayout.LayoutParamsconstructor:

LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
    LayoutParams.MATCH_PARENT,
    LayoutParams.MATCH_PARENT,
    1.0f
);
YOUR_VIEW.setLayoutParams(param);

El último parámetro es el peso.

Erich Douglass
fuente
2
Debería serparam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, (float) 1.0);
Mithun Sreedharan
49
Si no quieres lanzar de un doble a un flotante, solo pon 1.0f
Xample
8
O incluso más simple 1fsi no hay decimales
solo el
44
qué hacer si el diseño principal esRelative
Pratik Butani
99
@pratik si el diseño principal es relativo, usted no usa pesas
invertigo
121

Uso LinearLayout.LayoutParams:

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
Button button = new Button(this);
button.setLayoutParams(params);

EDITAR: ¡Ah, la respuesta de Erich es más fácil!

Kevin Coppock
fuente
27
La respuesta de Erich puede ser más fácil de escribir, pero la suya es más fácil de leer. Como dice para qué atributo se usa el 1.0f.
Johan
3
el suyo estableció que puede modificar el peso sobre la marcha llamando a 'view.getLayoutParams ()' y luego modifique el valor.
RobGThai
1
FILL_PARENTha quedado en desuso y MATCH_PARENTdebería usarse en su lugar.
Simon Forsberg el
2
@LocalPCGuy No es cierto. Siempre y cuando esté apuntando a SDK> = 8 (que debería ser absolutamente), MATCH_PARENTpuede usarse en lugar de FILL_PARENTincluso en dispositivos más antiguos.
Kevin Coppock
2
@LocalPCGuy Ya nadie usa API 7 o menos . Si usted está tratando de hacer que su aplicación compatible con las API de 7 o menos, lo que probablemente se encuentra con un montón de otros problemas antes de preocuparse FILL_PARENTvs MATCH_PARENT.
Simon Forsberg
82

Si ya define su vista en su archivo de diseño (xml), solo desea cambiar el peso mediante programación, de esta manera es mejor

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)   
mButton.getLayoutParams();
params.weight = 1.0f;
mButton.setLayoutParams(params);

Un nuevo LayoutParams sobrescribe otros parámetros definidos en su archivo xml como márgenes, o debe especificarlos en LayoutParams.

pkliang
fuente
2
Con "params.weight = 1f;" ya está configurando el peso en el objeto LayoutParams. No es necesario llamar "mButton.setLayoutParams (params);".
MrMaffen
2
No, debe llamar a setLayoutParams
SIr Codealot el
1
Esta es en realidad la respuesta más elegante y cambia directamente un objeto de interfaz de usuario específico. La mejor respuesta también es buena y anterior a esta publicación. Por lo tanto, se merece como la mejor respuesta. Sin embargo, voté por esta publicación.
El Android original
Gran y simple solución!
Jeremy
¡Funciona de maravilla! Muchas gracias :)
Vinay Vissh
26

Si el constructor con ancho, alto y peso no funciona, intente usar el constructor con ancho y alto. Y luego establezca manualmente el peso.

Y si desea establecer el ancho de acuerdo con el peso, establezca el ancho como 0 en el constructor. Lo mismo se aplica para la altura. El siguiente código funciona para mí.

LinearLayout.LayoutParams childParam1 = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT);
childParam1.weight = 0.3f;
child1.setLayoutParams(childParam1);

LinearLayout.LayoutParams childParam2 = new LinearLayout.LayoutParams(0,LinearLayout.LayoutParams.MATCH_PARENT);
childParam2.weight = 0.7f;
child2.setLayoutParams(childParam2);

parent.setWeightSum(1f);
parent.addView(child1);
parent.addView(child2);
Ganindu
fuente
¡Justo lo que necesitaba! ¡Todos están hablando de establecer pesos aquí, nadie mostró lo que sucede cuando esos Niños pesados ​​se agregan a la Vista de Padres! ¡En realidad estaba buscando cómo agregar weightSum en ParentView! ¡Gracias!
sud007
14

Si alguien busca respuesta, use esto:

LinearLayout.LayoutParams lay = (LinearLayout.LayoutParams) myLayout.getLayoutParams();
lay.weight = 0.5;

Si está inicializando su diseño desde un archivo xml, esto será mucho más conveniente que proporcionar nuevos parámetros de diseño para Diseño lineal.

ceniza
fuente
Esta debería ser la respuesta aceptada, ya que no modifica ninguna variable establecida previamente como ancho / alto / margen / relleno, etc. Todo se mantiene y se reutiliza mientras se cambia el peso.
MrMaffen
1
Si la vista para configurar layout_weightya se ha establecido, debe llamar View.requestLayout()para actualizar.
Atacante el
6

Cualquiera de LinearLayout.LayoutParamsy TableLayout.LayoutParamsfuncionó para mí, para los botones es el correcto TableRow.LayoutParams. Es decir:

            TableRow.LayoutParams buttonParams = new TableRow.LayoutParams(
                    TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT, 1f);

Sobre usar MATCH_PARENTo WRAP_CONTENTser el mismo.

gantzer89
fuente
3
FILL_PARENTha quedado en desuso y MATCH_PARENTdebería usarse en su lugar.
Simon Forsberg el
Creo que LayoutParams.MATCH_PARENT debería cambiarse a 0.
CoolMind
Llamas al LayoutParamspadre directo. Supongo que tuvo un accidente al intentar usar LinearLayout.LayoutParamssin el padre LinearLayout.
Carro abandonado
4

Si ya ha definido su vista en el archivo de diseño (xml) y solo desea cambiar el peso de forma programática, entonces crear nuevos LayoutParams sobrescribe otros parámetros definidos en su archivo xml.

Entonces, primero debes usar "getLayoutParams" y luego setLayoutParams

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mButton.getLayoutParams(); params.weight = 4f; mButton.setLayoutParams(params);

Shirish Herwade
fuente
3

Si layoutparamsya está definido (en XML o dinámicamente), aquí hay una línea:

((LinearLayout.LayoutParams) mView.getLayoutParams()).weight = 1;
SolidSnake
fuente
Respuesta subestimada
Adam Higgins
0

Usando Kotlin puedes hacer algo como:

import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.widget.CardView
import android.widget.*

import android.widget.LinearLayout

class RespondTo : CardView {
    constructor(context: Context) : super(context) {
        init(context)
    }

    private fun init(context: Context) {


        val parent = LinearLayout(context)

        parent.apply {
            layoutParams = LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT, 1.0f).apply {
                orientation = LinearLayout.HORIZONTAL

                addView(EditText(context).apply {
                    id = generateViewId()
                    layoutParams = LinearLayout.LayoutParams(0,
                            LinearLayout.LayoutParams.WRAP_CONTENT, 0.9f).apply {
                    }
                })
                addView(ImageButton(context).apply({
                    layoutParams = LinearLayout.LayoutParams(0,
                            LinearLayout.LayoutParams.WRAP_CONTENT, 0.1f)
                    background = null
                    setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_save_black_24px))
                    id = generateViewId()
                    layoutParams = RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT).apply {
                        addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                        // addRule(RelativeLayout.LEFT_OF, myImageButton.id)
                    }
                }))
            }
        }
        this.addView(parent)
    }
}
Hasan A Yousef
fuente