Comment redimensionner une vue personnalisée par programmation?


164

Je suis en train de coder une vue personnalisée, étendue de RelativeLayout, et je souhaite la redimensionner par programmation, comment puis-je faire?

la classe de vue personnalisée est quelque chose comme:

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

Réponses:


253

Android lève une exception si vous ne parvenez pas à transmettre la hauteur ou la largeur d'une vue. Au lieu de créer un nouvel objet LayoutParams, utilisez celui d'origine afin que tous les autres paramètres définis soient conservés. Notez que le type de LayoutParams renvoyé par getLayoutParams est celui de la mise en page parent et non de la vue que vous redimensionnez.

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

2
Comme le mentionne @HerbertD, j'obtiens également une erreur en le faisant, sauf si j'utilise LinearLayout.LayoutParams, même si c'est un RelativeLayout que je redimensionne.
Martin Belcher - AtWrk

6
@Eigo Selon la documentation Android, les LayoutParams sont passés à la vue parente, car c'est la vue qui est responsable de la mise en page.
sstn

1
Si la valeur in doit être convertie en valeur dp ou cela fonctionnerait.
Dory

Ceci est également préférable car cela évite d'instancier inutilement un nouvel objet LayoutParams
Stephen Kidson

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

Problème résolu!

REMARQUE: assurez-vous d'utiliser la mise en page parent LayoutParams. Le mien est LinearLayout.LayoutParams!


3
Wut. Pourquoi ne pas utiliserRelativeLayout.LayoutParams?
nmr

1
Cela n'a pas fonctionné pour moi, j'ai eu une exception de distribution de classe pour cela.
Tapan Thaker

4
@Tapan Thanker Utilisez les LayoutParams de la mise en page Parent. Et la disposition My Parent est LinearLayout.
herbertD

10
J'ai écrit une version plus générique de ceci: 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
Cela réinitialisera tous les autres paramètres aux valeurs par défaut. La réponse @smisiewicz est meilleure.
Fran Marzoa

66

Cela fonctionne pour moi:

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

7
C'est bien mieux que les autres réponses car ce code ne nécessite pas de connaître le type exact du ViewGroup parent.
Bart Burg

1
Savez-vous quelle est la différence entre l'appel de requestLayout () et l'appel de setLayoutParams (params)?
voghDev

2
setLayoutParams (params) inclut requestLayout ().
illusionJJ

44

Pour ce que ça vaut, disons que vous vouliez redimensionner la vue en pixels indépendants de l'appareil ( dp ): -

Vous devez utiliser une méthode appelée applyDimension, qui est membre de la classe TypedValuepour convertir des pixels en dps. Donc, si je veux régler la hauteur à 150dp (disons) - alors je pourrais faire ceci:

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

où l'expression: getResources().getDisplayMetrics()obtient la densité / résolution de l'écran


6
Au lieu de coder en dur votre dimension, vous pouvez également l'utiliser pour la hauteur en pixel:float pixels = context.getResources().getDimensionPixelSize(R.dimen.card_height);
Francois Dermu

cette réponse est plus appropriée comme réponse correcte !. Merci
Yunus Kulyyev


6

essayez celui-ci:

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

Désolé, je n'ai pas posté toutes les questions depuis que vous y avez répondu. Voilà toute la question. Merci!
herbertD

6

Voici une version plus générique de la solution ci-dessus 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, vous avez littéralement sauvé ma journée :)
Qasim

5

J'ai utilisé cette méthode pour augmenter la largeur de la vue personnalisée

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

Je l'ai résolu de cette façon .. J'ai fondamentalement une vue simple à l'intérieur du fichier xml.

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

2
haha, méthode très naïve mais qui fonctionne bien, cependant je recommande d'appeler setLayoutParams () éventuellement pour propager correctement les modifications aux enfants imbriqués possibles, donc après la mise à jour de .width et .height, appelez view.setLayoutParams (view.getLayoutParams ()) c'est aussi toujours dactylographier
comeGetSome

@Bhargav Rao pourriez-vous m'aider sur ce sujet: https://stackoverflow.com/q/44259342/6596724
tux-world

2

Si vous avez seulement, two or three condition(sizes)vous pouvez utiliser @Overide onMeasure comme

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

Et modifiez facilement votre taille pour ces conditions dans la classe CustomView.


1

si vous remplacez onMeasure, n'oubliez pas de mettre à jour les nouvelles tailles

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

1

C'est ainsi que j'ai réalisé cela. Dans réponse de Sileria, il / elle a fait ce qui suit:

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

C'est correct, mais il s'attend à ce que nous donnions la hauteur en pixels , mais je voulais donner dpla hauteur que je veux donc j'ai ajouté:

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

Cela ressemblera donc à ceci:

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

0

C'est ce que j'ai fait:

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

S'il existe un groupe de vues auquel appartient cette vue, vous devrez peut-être également appeler yourViewGroup.requestLayout () pour qu'il prenne effet.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.