Comment ajouter par programme des vues aux vues

179

Disons que j'ai un LinearLayout, et je veux y ajouter une vue, dans mon programme à partir du code Java. Quelle méthode est utilisée pour cela? Je ne demande pas comment cela est fait en XML, ce que je sais, mais plutôt, comment puis-je faire quelque chose dans le sens de cet exemple de code?

(One View).add(Another View)

Comme on peut le faire dans Swing.

Moki
la source

Réponses:

248

Appel addView est la bonne réponse, mais vous devez faire un peu plus que cela pour que cela fonctionne.

Si vous créez une vue via un constructeur (par exemple, Button myButton = new Button();), vous devrez appelersetLayoutParams la vue nouvellement construite, en passant une instance de la classe interne LayoutParams de la vue parent, avant d'ajouter votre enfant nouvellement construit à la vue parent.

Par exemple, vous pouvez avoir le code suivant dans votre onCreate()fonction en supposant que votre LinearLayout a un id R.id.main:

LinearLayout myLayout = findViewById(R.id.main);

Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
                                     LinearLayout.LayoutParams.MATCH_PARENT,
                                     LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

Il est important de s'assurer de définir les LayoutParams. Chaque vue nécessite au moins un paramètre layout_width et un paramètre layout_height. Il est également important d'obtenir la bonne classe intérieure. J'ai eu du mal à ajouter des vues à un TableRow pour s'afficher correctement jusqu'à ce que je comprenne que je ne passais pas une instance de TableRow.LayoutParams à setLayoutParams de la vue enfant.

Brian Cooley
la source
5
Comment créeriez-vous la vue par programme, mais en utilisant un fichier de mise en page XML que vous avez spécifiquement écrit pour cette nouvelle vue?
SK9
9
@ SK9 Vous utiliseriez un LayoutInflater, que vous pouvez obtenir à partir d'un contexte, généralement l'activité actuelle. Quelque chose comme: LayoutInflater myInflater = getLayoutInflater; View myView = myInflater.inflate (R.layout.myLayout, parent, false);
Brian Cooley
1
En fait, getLayoutInflater () provient de la classe Window (et non de Context), et c'est une méthode pratique dans Activity.
Brian Cooley
2
En tant que pratique de codage, sur findViewById, transtypez en ViewGroup ou toujours la forme la plus générique d'un objet afin que s'il passe d'un LinearLayout à un RelativeLayout, vous n'ayez pas de refactorisation.
Joel Teply
1
Voici quelques détails: D
Vivek Solanki
51

pour tous ceux qui sont encore intéressés:

le meilleur moyen que j'ai trouvé est d'utiliser la méthode statique gonflée de View.

View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);

où yourViewXML est quelque chose comme R.layout.myView

veuillez noter que vous avez besoin d'un ViewGroup pour ajouter une vue (qui est n'importe quelle disposition à laquelle vous pouvez penser)

Ainsi, à titre d'exemple, disons que vous avez un fragment qui a déjà été gonflé et que vous savez que la vue racine est une mise en page, et que vous souhaitez y ajouter une vue:

    View view = getView(); // returns base view of the fragment
    if (view == null)
        return;
    if (!(view instanceof ViewGroup))
        return;

    ViewGroup viewGroup = (ViewGroup) view;
    View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
ndori
la source
Vous pouvez également écrire une méthode statique, quelque chose comme addView(View v){ // your code after get view }ça prendrait une vue trouvée en utilisant findViewById(int resourceID)ou gonflée comme votre inflatedView... juste pour développer votre exemple de fragment.
zgc7009
22

C'est tard mais cela peut aider quelqu'un :) :) Pour ajouter la vue par programme, essayez comme

LinearLayout rlmain = new LinearLayout(this);      
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);          
LinearLayout   ll1 = new LinearLayout (this);

ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);              
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);              
setContentView(rlmain, llp);

Cela créera votre vue entière par programmation. Vous pouvez ajouter n'importe quel nombre de vues identiques. J'espère que cela peut aider. :)

AndroidOptimist
la source
20

LinearLayout est une sous-classe de ViewGroup , qui possède une méthode appelée addView . La méthode addView doit être ce que vous recherchez.

Klarth
la source
3

Une autre façon d'ajouter une vue depuis l'activité

ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);
yoAlex5
la source
0

L'idée de définir des contraintes par programmation peut être fastidieuse. Cette solution ci-dessous fonctionnera pour n'importe quelle mise en page qu'elle soit contrainte, linéaire, etc. La meilleure façon serait de définir un espace réservé, c'est-à-dire un FrameLayout avec des contraintes appropriées (ou un placement approprié dans une autre mise en page telle que linéaire) à la position où vous attendez la vue créée par programme avoir.

Tout ce que vous avez à faire est de gonfler la vue par programme et en tant qu'enfant du FrameLayout à l'aide de addChild()method. Ensuite, pendant l'exécution, votre vue serait gonflée et placée dans la bonne position. Selon la recommandation Android, vous ne devez ajouter qu'un seul childView à FrameLayout [lien] .

Voici à quoi ressemblerait votre code, en supposant que vous souhaitiez créer TextView par programme à une position particulière:

Étape 1:

Dans votre mise en page qui contiendrait la vue à gonfler, placez un FrameLayout à la bonne position et donnez-lui un identifiant, par exemple "conteneur".

Étape 2 Créez une mise en page avec l'élément racine comme vue que vous souhaitez gonfler pendant l'exécution, appelez le fichier de mise en page comme "textview.xml":

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</TextView>

BTW, définissez les paramètres de mise en page de votre frameLayout sur wrap_content, sinon la disposition du cadre deviendra aussi grande que le parent, c'est-à-dire l'activité, c'est-à-dire l'écran du téléphone.

android:layout_width="wrap_content"
android:layout_height="wrap_content"

S'il n'est pas défini, car une vue enfant du cadre, par défaut, va en haut à gauche de la disposition du cadre, par conséquent, votre vue volera simplement vers le haut à gauche de l'écran.

Étape 3

Dans votre méthode oncreate, procédez comme suit:

FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(Notez que définir le dernier paramètre de findViewByIdto nullet ajouter une vue en appelant la addView()vue conteneur (frameLayout) équivaut simplement à attacher la vue gonflée en passant le truetroisième paramètre de findViewById(). Pour plus d'informations, voir ceci .)

kush
la source
0

Vous devez également vous assurer que lorsque vous remplacez, onLayoutvous DEVEZ appeler super.onLayoutavec toutes les propriétés, sinon la vue ne sera pas gonflée!

Oz Shabat
la source