¿Cómo cambiar el tamaño de una vista personalizada mediante programación?


164

Estoy codificando una vista personalizada, extendida desde RelativeLayout, y quiero cambiar su tamaño programáticamente. ¿Cómo puedo hacerlo?

la clase de vista personalizada es algo así como:

public ActiveSlideView(Context context, AttributeSet attr){
        super(context, attr);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if(inflater != null){       
            inflater.inflate(R.layout.active_slide, this);
        }

Respuestas:


253

Android lanza una excepción si no pasa el alto o el ancho de una vista. En lugar de crear un nuevo objeto LayoutParams, use el original para que se conserven todos los demás parámetros establecidos. Tenga en cuenta que el tipo de LayoutParams devuelto por getLayoutParams es el diseño primario , no la vista que está redimensionando.

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) someLayout.getLayoutParams();
params.height = 130;
someLayout.setLayoutParams(params);

2
Como @HerbertD menciona, también recibo un error al hacer esto a menos que use LinearLayout.LayoutParams, incluso a través de un RelativeLayout que estoy redimensionando.
Martin Belcher - AtWrk el

66
@Eigo De acuerdo con la documentación de Android, los LayoutParams se pasan a la Vista principal, ya que esta es la vista responsable del diseño.
sstn

1
Si el valor de entrada debe convertirse en valor dp o funcionaría.
Dory

Esto también es preferible ya que evita crear instancias innecesarias de un nuevo objeto LayoutParams
Stephen Kidson

129
this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, theSizeIWant));

¡Problema resuelto!

NOTA: asegúrese de utilizar el diseño principal LayoutParams. El mío es LinearLayout.LayoutParams!


3
Wut ¿Por qué no RelativeLayout.LayoutParams?
usarías

1
Esto no funcionó para mí, obtuve una excepción de reparto de clase.
Tapan Thaker

44
@Tapan Thanker Use los LayoutParams del diseño primario. Y el diseño de Mi padre es LinearLayout.
herbertD

10
Escribí una versión más genérica de esto: private void resizeView(View view, int newWidth, int newHeight) { try { Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); view.setLayoutParams(ctor.newInstance(newWidth, newHeight)); } catch (Exception e) { e.printStackTrace(); } }
atroutt

2
Esto restablecerá todos los demás parámetros a los valores predeterminados. La respuesta de @smisiewicz es mejor.
Fran Marzoa

66

Esto funciona para mi:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

77
Esto es mucho mejor que las otras respuestas porque este código no requiere conocer el tipo exacto del ViewGroup primario.
Bart Burg

1
¿Sabes cuál es la diferencia entre llamar a requestLayout () y llamar a setLayoutParams (params)?
voghDev

2
setLayoutParams (params) incluye requestLayout ().
illusionJJ

44

Por lo que vale, digamos que desea cambiar el tamaño de la vista en píxeles independientes del dispositivo ( dp ): -

Debe usar un método llamado applyDimension, que es miembro de la clase TypedValuepara convertir de píxeles a dps. Entonces, si quiero establecer la altura en 150dp (por ejemplo), entonces podría hacer esto:

float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, getResources().getDisplayMetrics());
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) someLayout.getLayoutParams();
params.height = (int) pixels;
someLayout.setLayoutParams(params);

donde la expresión: getResources().getDisplayMetrics()obtiene la densidad / resolución de la pantalla


66
En lugar de codificar su dimensión, también puede usar esto para la altura en píxeles:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

¡Esta respuesta es más apropiada como respuesta correcta! Gracias
Yunus Kulyyev


6

prueba este:

...
View view = inflater.inflate(R.layout.active_slide, this);
view.setMinimumWidth(200);

Lo siento, no he publicado todas las preguntas desde que lo respondiste. Ahora esa es toda la pregunta. ¡Gracias!
herbertD

6

Aquí hay una versión más genérica de la solución anterior de @herbertD:

private void resizeView(View view, int newWidth, int newHeight) { 
    try { 
        Constructor<? extends LayoutParams> ctor = view.getLayoutParams().getClass().getDeclaredConstructor(int.class, int.class); 
        view.setLayoutParams(ctor.newInstance(newWidth, newHeight));   
    } catch (Exception e) { 
        e.printStackTrace(); 
    }
}

@atroutt, literalmente me salvaste el día :)
Qasim

5

Utilicé esta manera para aumentar el ancho de la vista personalizada

customDrawingView.post(new Runnable() {
                            @Override
                            public void run() {
                                View view_instance = customDrawingView;
                                android.view.ViewGroup.LayoutParams params = view_instance
                                        .getLayoutParams();
                                int newLayoutWidth = customDrawingView
                                        .getWidth()
                                        + customDrawingView.getWidth();
                                params.width = newLayoutWidth;
                                view_instance.setLayoutParams(params);
                                screenWidthBackup = params.width;
                            }
                        });

4

Lo resolví de esta manera ... Básicamente tengo una vista simple dentro del archivo xml.

 View viewname = findViewById(R.id.prod_extra);
             prodExtra.getLayoutParams().height=64;

2
jaja, muy ingenuo pero funciona bien, sin embargo, recomiendo llamar a setLayoutParams () para propagar adecuadamente el cambio a posibles hijos anidados, así que después de actualizar .width y .height, llame a view.setLayoutParams (view.getLayoutParams ()) esto también es siempre escriba prueba
comeGetSome

@Bhargav Rao podría ayudarme en este tema: https://stackoverflow.com/q/44259342/6596724
tux-world

2

Si solo two or three condition(sizes)tienes, puedes usar @Overide onMeasure como

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Y cambie su tamaño para estas condiciones en la clase CustomView fácilmente.


1

si está anulando onMeasure, no olvide actualizar los nuevos tamaños

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(newWidth, newHeight);
}

1

Así es como lo logré. En la respuesta de Sileria , hizo lo siguiente:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = customHeight;
layout.requestLayout();

Esto es correcto, pero espera que demos la altura pixels, pero quería dar dpla altura que quiero, así que agregué:

public int convertDpToPixelInt(float dp, Context context) {
    return (int) (dp * (((float) context.getResources().getDisplayMetrics().densityDpi) / 160.0f));
}

Entonces se verá así:

ViewGroup.LayoutParams params = layout.getLayoutParams();
params.height = convertDpToPixelInt(50, getContext());
layout.requestLayout();

0

Esto es lo que hice:

View myView;  
myView.getLayoutParams().height = 32;  
myView.getLayoutParams().width = 32;

Si hay un grupo de vistas al que pertenece esta vista, es posible que también deba llamar a yourViewGroup.requestLayout () para que surta efecto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.