web-dev-qa-db-fra.com

Sous Android, comment définir les marges dans dp par programme?

Dans this , this et this thread, j’ai essayé de trouver une réponse sur la manière de définir les marges sur une seule vue. Cependant, je me demandais s'il n'y avait pas de moyen plus facile. Je vais expliquer pourquoi je préférerais ne pas utiliser cette approche:

J'ai un bouton personnalisé qui étend le bouton. Si l'arrière-plan est défini sur autre chose que l'arrière-plan par défaut (en appelant soit setBackgroundResource(int id) ou setBackgroundDrawable(Drawable d)), je souhaite que les marges soient égales à 0. Si j'appelle cela:

public void setBackgroundToDefault() {
    backgroundIsDefault = true;
    super.setBackgroundResource(Android.R.drawable.btn_default);
    // Set margins somehow
}

Je veux que les marges se réinitialisent à -3dp (je lis déjà ici comment convertir des pixels en dp, donc une fois que je sais comment définir des marges en px, je peux gérer la conversion moi-même). Mais puisque ceci est appelé dans la classe CustomButton, le parent peut varier de LinearLayout à TableLayout, et je préférerais qu'il ne récupère pas son parent et ne vérifie pas l'instance de ce parent. Ce sera aussi assez performant, j'imagine.

De plus, lors de l'appel (à l'aide de LayoutParams) parentLayout.addView(myCustomButton, newParams), je ne sais pas si cela l'ajoute à la position correcte (je n'ai pas essayé cependant), dites le bouton du milieu d'une rangée de cinq.

Question: Existe-t-il un moyen plus simple de définir la marge d’un bouton unique par programmation en plus de LayoutParams?

EDIT: Je connais la méthode LayoutParams, mais j'aimerais une solution qui évite de manipuler chaque type de conteneur différent:

ViewGroup.LayoutParams p = this.getLayoutParams();
    if (p instanceof LinearLayout.LayoutParams) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof RelativeLayout.LayoutParams) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof TableRow.LayoutParams) {
        TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
}

Parce que this.getLayoutParams(); renvoie un ViewGroup.LayoutParams, qui ne possède pas les attributs topMargin, bottomMargin, leftMargin, rightMargin. L'instance mc que vous voyez est simplement une MarginContainer qui contient offset (-3dp) margin et (oml, omr, omt, omb) les marges d'origine (ml, mr, mt, mb).

321
stealthjong

Vous devez utiliser LayoutParams pour définir les marges de vos boutons:

LayoutParams params = new LayoutParams(
        LayoutParams.WRAP_CONTENT,      
        LayoutParams.WRAP_CONTENT
);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);

Selon la disposition que vous utilisez, vous devez utiliser RelativeLayout.LayoutParams ou LinearLayout.LayoutParams.

Et pour convertir votre mesure dp en pixel, essayez ceci:

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);
660
throrin19

LayoutParams - ne fonctionne pas! ! !

Besoin d'utiliser type de: MarginLayoutParams

MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;

Exemple de code pour MarginLayoutParams:

http://www.codota.com/Android/classes/Android.view.ViewGroup.MarginLayoutParams

186
Lyusten Elder

Le meilleur moyen de ma vie:

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(left, top, right, bottom);
        view.requestLayout();
    }
}

Comment appeler la méthode:

setMargins(mImageView, 50, 50, 50, 50);

J'espère que ceci vous aidera.

92
Hiren Patel
int sizeInDP = 16;

int marginInDp = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, sizeInDP, getResources()
                    .getDisplayMetrics());

Ensuite

layoutParams = myView.getLayoutParams()
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

Ou

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);
25
sagits

Cette méthode vous permettra de définir la Marge inDP

public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {

        final float scale = con.getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int pixel =  (int)(dp * scale + 0.5f); 

        ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
        s.setMargins(pixel,pixel,pixel,pixel);

        yourView.setLayoutParams(params);
}

METTRE À JOUR

Vous pouvez modifier le paramètre qui convient à vos besoins.

7
neferpitou

layout_margin est une contrainte qu'un enfant de vue dit à son parent. Cependant, le rôle du parent est de choisir d'autoriser ou non la marge. Fondamentalement en définissant Android: layout_margin = "10dp", l’enfant demande au groupe de vues parent d’allouer un espace supérieur de 10dp à sa taille réelle. (padding = "10dp", par contre, signifie que la vue enfant réduira son propre contenu 10dp plus petit .)

Par conséquent, tous les ViewGroups ne respectent pas la marge . L'exemple le plus notoire serait listview, où les marges des éléments sont ignorées. Avant d'appeler setMargin() vers un LayoutParam, vous devez toujours vous assurer que la vue actuelle réside dans un ViewGroup prenant en charge la marge (par exemple, LinearLayouot ou RelativeLayout) et transtyper le résultat de getLayoutParams() vers le LayoutParams spécifique de votre choix. (ViewGroup.LayoutParams n'a même pas de méthode setMargins()!)

La fonction ci-dessous devrait faire l'affaire. Cependant, assurez-vous de substituer RelativeLayout au type de la vue parent.

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}
7
Ian Wong

Voici la réponse tout-en-un avec les dernières mises à jour:

Étape 1, mettre à jour la marge

L'idée de base est d'obtenir une marge puis de la mettre à jour. La mise à jour sera appliquée automatiquement et vous n'avez pas besoin de la réinitialiser. Pour obtenir les paramètres de présentation, appelez simplement cette méthode:

LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();

La LayoutParams provient de la disposition de votre vue. Si la vue provient d'une disposition linéaire, vous devez importer LinearLayout.LayoutParams. Si vous utilisez une disposition relative, importez LinearLayout.LayoutParams, etc.

Maintenant, si vous définissez la marge en utilisant Layout_marginLeft, Right, etc., vous devez mettre à jour la marge de cette manière.

layoutParams.setMargins(left, top, right, bottom);

Si vous définissez la marge à l'aide du nouveau layout_marginStart, vous devez mettre à jour la marge de cette manière.

layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);

Étape 2, mettre à jour la marge en dp

Les deux manières de mettre à jour la marge ci-dessus sont des mises à jour en pixels. Vous devez faire une traduction de dp en pixels.

float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;

Maintenant, placez la valeur calculée sur les fonctions de mise à jour de la marge ci-dessus et vous devriez être tous ensemble

6
Fangming

Lorsque vous êtes dans une vue personnalisée, vous pouvez utiliser getDimensionPixelSize(R.dimen.dimen_value); dans mon cas, j'ai ajouté la marge dans LayoutParams créée sur la méthode init.

À Kotlin

init {
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true)
    layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
    val margin = resources.getDimensionPixelSize(R.dimen.dimen_value)
    setMargins(0, margin, 0, margin)
}

en Java:

public class CustomView extends LinearLayout {

    //..other constructors

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.spacing_dime);
        params.setMargins(0, margin, 0, margin);
        setLayoutParams(params);
    }
}
2
user2825576

Pour une installation rapide en une ligne, utilisez

((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);

mais faites attention à toute utilisation incorrecte de LayoutParams, car cela n'aura aucune instance if

1
Dasser Basyouni

Dans mon exemple, j'ajoute un ImageView à un programme LinearLayout. J'ai défini les marges supérieure et inférieure sur ImagerView. Ajoutez ensuite ImageView à LinearLayout.



        ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmap);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        params.setMargins(0, 20, 0, 40);
        imageView.setLayoutParams(params);
        linearLayout.addView(imageView);

0
Rajeev

Création d’une fonction d’extension Kotlin pour ceux qui le trouvent utile.

Assurez-vous de passer en pixels pas dp. Bonne codage :)

fun View.addLayoutMargins(left: Int? = null, top: Int? = null,
                      right: Int? = null, bottom: Int? = null) {
    this.layoutParams = ViewGroup.MarginLayoutParams(this.layoutParams)
            .apply {
                left?.let { leftMargin = it }
                top?.let { topMargin = it }
                right?.let { rightMargin = it }
                bottom?.let { bottomMargin = it }
            }
}
0
David Kim

Vous pouvez utiliser cette méthode et mettre dimen statique comme 20 il convertit en fonction de votre appareil

 public static int dpToPx(int dp) 
      {
          float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
  }
0
Dishant Kawatra

Comme aujourd’hui, le mieux est probablement d’utiliser Paris , une bibliothèque fournie par AirBnB. 

Les styles peuvent ensuite être appliqués comme ceci:

Paris.style(myView).apply(R.style.MyStyle);

il prend également en charge la vue personnalisée (si vous étendez une vue) en utilisant des annotations:

@Styleable and @Style
0
sonique

Mis à jour:

Tout comme vous aviez l'habitude de régler la largeur et la hauteur de la mise en page avec ViewGroup.LayoutParams

Vous pouvez utiliser ViewGroup.MarginLayoutParams pour définir la largeur, la hauteur et les marges, assez explicite, non?

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
marginLayoutParams.setMargins(0,16,0,16);
linearLayout.setLayoutParams(marginLayoutParams);

Où la méthode setMargins(); prend respectivement les valeurs de gauche, haut, droite et bas. Dans le sens horaire !, en commençant par la gauche.

0
mmmcho

Utilisez cette méthode pour définir la marge en dp

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

        final float scale = getBaseContext().getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int l =  (int)(left * scale + 0.5f);
        int r =  (int)(right * scale + 0.5f);
        int t =  (int)(top * scale + 0.5f);
        int b =  (int)(bottom * scale + 0.5f);

        p.setMargins(l, t, r, b);
        view.requestLayout();
    }
}

appelez la méthode:

setMargins(linearLayout,5,0,5,0);
0
Ridwan Bin Sarwar
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

J'ai dû attribuer le mien à FrameLayout pour un linearLayout car il en hérite et y définir des marges afin que l'activité n'apparaisse que sur une partie de l'écran avec un arrière-plan différent de celui de la mise en page originale dans setContentView

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
linearLayout.setBackgroundColor(getResources().getColor(R.color.full_white));
setContentView(linearLayout,layoutParams);

Aucun des autres n'a travaillé pour utiliser la même activité et modifier les marges en fonction de l'ouverture de l'activité à partir d'un menu différent! setLayoutParams n'a jamais fonctionné pour moi - le périphérique plantait à chaque fois. Même s'il s'agit de nombres codés en dur, il ne s'agit que d'un exemple de code à des fins de démonstration uniquement. 

0
ali mcnamara