1
votes

Les marges Android ne fonctionnent pas lorsque la vue a été ajoutée dynamiquement

J'ajoute de manière dynamique une vue au LinearLayout:

LinearLayout base = new LinearLayout(context);
LayoutParams params1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
base.setLayoutParams(params1);    
base.setBackgroundColor(Color.CYAN);
root.addView(base);

LinearLayout another1 = new LinearLayout(context);
LayoutParams params2 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
another1.setLayoutParams(params2);
another1.setOrientation(LinearLayout.VERTICAL);
another1.setBackgroundColor(Color.BLUE);
base.addView(another1);

TextView tv1 = new TextView(context);
tv1.setText("SOME TEST TEXT 1");
tv1.setTextColor(Color.BLACK);
LayoutParams params4 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params4.setMargins(100, 100, 100, 100);
tv1.setLayoutParams(params4);
another1.addView(tv1);

TextView tv2 = new TextView(context);
tv2.setText("SOME TEST TEXT 2");
tv2.setTextColor(Color.BLACK);
LayoutParams params5 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params4.setMargins(100, 100, 100, 100);
tv2.setLayoutParams(params5);
another1.addView(tv2);

Cependant, les marges ne sont pas appliquées. Ce qui suit:

view.invalidate();
view.requestLayout();
parent.invalidate();
parent.requestLayout();

n'a pas fonctionné. Cependant, si je force l'activité à recréer (par exemple, éteindre et rallumer mon téléphone portable), les marges sont appliquées. L'appel de activity.recreate () fonctionne également, mais c'est trop lent.

Comment forcer la mise en page à recalculer les marges? Il y a probablement quelque chose qui ne va pas dans le flux? J'ai essayé d'ajouter mes vues à la racine après la création, d'ajouter des enfants avant et après l'application des propriétés, mais cela n'a pas fonctionné pour moi.

UPD: J'ai essayé de répéter le bogue par programmation et je l'ai obtenu avec ce code:

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(100, 100, 100, 100);
view.setLayoutParams(params);
parent.addView(view);

Voici ce que j'ai

J'attends marges à appliquer, mais elles ne le sont pas. Quel est l'ordre correct d'initialisation d'une telle vue?


3 commentaires

AFAIK, cela ne compilera pas. Toutes les formes de addView () prennent la View comme paramètre, et parent.addView (params) ne semble pas passer un Afficher .


définir la marge après avoir ajouté la vue à la vue parent.


Merci pour l'avis, paramètre addView modifié. J'ai essayé de définir les paramètres après avoir ajouté à la vue parent, j'ai obtenu le même résultat


3 Réponses :


1
votes

Vous avez probablement ajouté des vues enfants à la vue parent dans onCreate ().

Dans onCreate (), la vue parent n'a pas de taille réelle.

Si vous devez le faire dans onCreate () , essayez le code suivant.

    final ViewTreeObserver observer = parent.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            LinearLayout.LayoutParams params = new
                    LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            params.setMargins(100, 100, 100, 100);
            TextView view = new TextView(context);
            view.setLayoutParams(params);
            parent.addView(view);
            observer.removeOnGlobalLayoutListener(this);
        }
    };

J'espère que cela vous aidera!


0 commentaires

1
votes

Donc, mon problème était dans le convertisseur DP vers PX qui n'était tout simplement pas initialisé à ce moment-là. Cependant, pour tout clarifier, mon exemple ci-dessus n'est qu'une erreur (je n'ai pas changé params4 en params5 lors de l'ajout du deuxième TextView. De plus, en testant tout, j'ai découvert que l'ordre d'ajout des mises en page et leurs paramètres importent peu.


0 commentaires

0
votes

Essayez ceci:

      LinearLayout ll = findViewById(R.id.linearLayout);
      LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
      LinearLayout.LayoutParams.MATCH_PARENT,
      LinearLayout.LayoutParams.WRAP_CONTENT);
      layoutParams.setMargins(30,20,30,0);

J'espère que cela vous aidera!


0 commentaires