Android: pourquoi n'y a-t-il pas de maxHeight pour une vue?


184

La vue a unminHeight mais manque d'une manière ou d'une autremaxHeight :

Ce que j'essaie de réaliser, c'est que certains éléments (vues) remplissent un fichier ScrollView. Quand il y a 1..3 éléments, je veux les afficher directement. Cela signifie que le ScrollViewa la hauteur de 1, 2 ou 3 éléments.

Lorsqu'il y a 4 éléments ou plus, je souhaite que le ScrollViewdéveloppement cesse (donc a maxHeight) et commence à fournir le défilement.

Cependant, il n'existe malheureusement aucun moyen de définir un fichier maxHeight. Donc, je dois probablement définir ma ScrollViewhauteur par programme sur soit WRAP_CONTENTlorsqu'il y a 1..3 éléments et définir la hauteur sur 3*sizeOf(View)lorsqu'il y a 4 éléments ou plus.

Quelqu'un peut-il expliquer pourquoi il n'y en a pas maxHeight, alors qu'il y en a déjà un minHeight?

(BTW: certaines vues, comme ImageViewavoir un maxHeightimplémenté.)


J'ai publié une solution dans un autre fil de discussion: stackoverflow.com/questions/18425758
...

2
J'ai créé une solution pour cela sur chintanrathod.com
Chintan Rathod

Google supprime maxHeight est ennuyeux et peu pratique. Regardez tout ce que vous devez faire maintenant pour obtenir le même résultat.
Ian Wambai

Réponses:


86

Aucune de ces solutions ne fonctionnait pour ce dont j'avais besoin, à savoir un ScrollView défini sur wrap_content mais ayant un maxHeight afin qu'il cesse de s'étendre après un certain point et commence à défiler. J'ai simplement remplacé la méthode onMeasure dans ScrollView.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(300, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Cela peut ne pas fonctionner dans toutes les situations, mais cela me donne certainement les résultats nécessaires pour ma mise en page. Et il répond également au commentaire de madhu.

Si une mise en page est présente sous la vue de défilement, cette astuce ne fonctionnera pas - madhu 5 mars à 4:36


1
Quand cela ne fonctionnerait-il pas? Cela semble être une solution très propre. Je me demande pourquoi ils ne l'ont pas implémenté dans le xml.
Christophe Smet

1
Cela ne fonctionnerait probablement pas si vous définissez manuellement la hauteur pour dire 240. Je n'ai pas pris la peine de vérifier le mode dans lequel se trouve le scrollview car je n'avais besoin de supporter qu'un mode spécifique (wrap_content).
whizzle

Il y a une modification pour cette réponse qui dit «Si une mise en page est présente sous la vue de défilement, cette astuce ne fonctionnera pas», ce qui n'est pas vrai. J'ai une mise en page alignée au bas de la page et cette mise en page personnalisée a "android: layout_above = '@ + ...'" qui place toujours la mise en page personnalisée au-dessus de la mise en page du bas :)
Machine Tribe

70

Pour créer un ScrollViewou ListViewavec un maxHeight, il vous suffit de créer un Transparent LinearLayout autour de lui avec une hauteur de ce que vous voulez que maxHeight soit. Vous définissez ensuite la hauteur de ScrollView sur wrap_content. Cela crée un ScrollView qui semble s'agrandir jusqu'à ce que sa hauteur soit égale à la LinearLayout parent.


3
Cela était utile pour empêcher une boîte de dialogue avec un contenu défilant de s'étendre sur toute la hauteur de l'écran.
Kyle Ivey

Une petite suggestion serait d'utiliser un FrameLayout au lieu d'un LinearLayout mais je doute que cela compte.
Kyle Ivey

43
Si une mise en page présente sous la vue de défilement, cette astuce ne fonctionnera pas
Sreedhu Madhu

2
pouvez-vous s'il vous plaît fournir un code? cela n'a pas fonctionné pour moi, alors peut-être que je fais quelque chose de mal ...
Développeur Android

ne fonctionnera pas si vous avez des boutons en dessous. il poussera les boutons hors de l'écran
Li Tian Gong

43

Cela a fonctionné pour moi pour le rendre personnalisable en xml:

MaxHeightScrollView.java:

public class MaxHeightScrollView extends ScrollView {

private int maxHeight;
private final int defaultHeight = 200;

public MaxHeightScrollView(Context context) {
    super(context);
}

public MaxHeightScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

private void init(Context context, AttributeSet attrs) {
    if (attrs != null) {
        TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        //200 is a defualt value
        maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_maxHeight, defaultHeight);

        styledAttrs.recycle();
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

attr.xml

<declare-styleable name="MaxHeightScrollView">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>

exemple de mise en page

<blah.blah.MaxHeightScrollView android:layout_weight="1"
                app:maxHeight="90dp"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
                <EditText android:id="@+id/commentField"
                    android:hint="Say Something"
                    android:background="#FFFFFF"
                    android:paddingLeft="8dp"
                    android:paddingRight="8dp"
                    android:gravity="center_vertical"
                    android:maxLines="500"
                    android:minHeight="36dp"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" />
            </blah.blah.MaxHeightScrollView>

Créer une vue personnalisée est certainement le meilleur moyen d'y parvenir.
Bertram Gilfoyle

Et cela fonctionne si vous avez une mise en page sous la vue de défilement! Parfait!
Ragaisis

25

(Je sais que cela ne répond pas directement à la question mais pourrait être utile à d'autres personnes recherchant la fonctionnalité maxHeight)

ConstraintLayout offre une hauteur maximale pour ses enfants via

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true" 

ou

app:layout_constraintWidth_max="300dp"
app:layout_constrainedWidth="true" 

Exemple d'utilisation ici .


2
Cela ne fonctionne pas si la vue est dans une chaîne verticale (comme spécifié dans la documentation ConstraintLayout)
Arno Schoonbee

Merci pour l'info.
user1506104

8

J'aurais commenté la réponse de Whizzle si je le pouvais, mais j'ai pensé qu'il était utile de noter que pour que je puisse résoudre ce problème dans le contexte du mode multi-fenêtre sous Android N, j'avais besoin de modifier légèrement le code pour ceci:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if(MeasureSpec.getSize(heightMeasureSpec) > maxHeight) {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

Cela permet à la mise en page d'être redimensionnée pour être plus petite que la hauteur maximale, mais aussi l'empêcher d'être plus grande que la hauteur maximale. J'ai utilisé ceci est une classe de mise en page qui remplace RelativeLayoutet cela m'a permis de créer une boîte de dialogue personnalisée avec ScrollViewcomme enfant de MaxHeightRelativeLayoutqui n'élargit pas toute la hauteur de l'écran et se rétrécit également pour s'adapter à la plus petite taille de veuve en multi-fenêtre pour Android N.


4

Il n'y a aucun moyen de définir maxHeight. Mais vous pouvez définir la hauteur.

Pour ce faire, vous devrez découvrir la hauteur de chaque élément de votre scrollView. Après cela, définissez simplement la hauteur de scrollView sur numberOfItens * heightOfItem.

Pour découvrir la hauteur d'un élément, procédez comme suit:

View item = adapter.getView(0, null, scrollView);
item.measure(0, 0);
int heightOfItem = item.getMeasuredHeight();

Pour régler la hauteur, procédez comme suit:

// if the scrollView already has a layoutParams:
scrollView.getLayoutParams().height = heightOfItem * numberOfItens;
// or
// if the layoutParams is null, then create a new one.
scrollView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, heightOfItem * numberOfItens));

4

Enroulez votre ScrollViewautour de votre plaine LinearLayoutavec layout_height = "max_height", cela fera un travail parfait. En fait, j'ai ce code en production des 5 dernières années sans aucun problème.

<LinearLayout
        android:id="@+id/subsParent"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:gravity="bottom|center_horizontal"
        android:orientation="vertical">

        <ScrollView
            android:id="@+id/subsScroll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginEnd="15dp"
            android:layout_marginStart="15dp">

            <TextView
                android:id="@+id/subsTv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/longText"
                android:visibility="visible" />

        </ScrollView>
    </LinearLayout>

1
Solution parfaite en effet. Intelligent et simple. Il convient même pour le recyclage.
Alex Belets

3

Ma MaxHeightScrollViewvue personnalisée

public class MaxHeightScrollView extends ScrollView {
    private int maxHeight;

    public MaxHeightScrollView(Context context) {
        this(context, null);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MaxHeightScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray styledAttrs =
                context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
        try {
            maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.MaxHeightScrollView_mhs_maxHeight, 0);
        } finally {
            styledAttrs.recycle();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

style.xml

<declare-styleable name="MaxHeightScrollView">
    <attr name="mhs_maxHeight" format="dimension" />
</declare-styleable>

En utilisant

<....MaxHeightScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:mhs_maxHeight="100dp"
    >

    ...

</....MaxHeightScrollView>

2

J'ai une réponse ici:

https://stackoverflow.com/a/29178364/1148784

Créez simplement une nouvelle classe étendant ScrollView et remplacez sa onMeasureméthode.

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (maxHeight > 0){
            int hSize = MeasureSpec.getSize(heightMeasureSpec);
            int hMode = MeasureSpec.getMode(heightMeasureSpec);

            switch (hMode){
                case MeasureSpec.AT_MOST:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.UNSPECIFIED:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
                    break;
                case MeasureSpec.EXACTLY:
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(hSize, maxHeight), MeasureSpec.EXACTLY);
                    break;
            }
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

2

Comme mentionné ci-dessus, ConstraintLayout offre une hauteur maximale pour ses enfants via:

app:layout_constraintHeight_max="300dp"
app:layout_constrainedHeight="true"

En outre, si la hauteur maximale d'un enfant de ConstraintLayout est incertaine jusqu'à l'exécution de l'application, il existe toujours un moyen de faire en sorte que cet enfant adapte automatiquement une hauteur modifiable, peu importe où il a été placé dans la chaîne verticale.

Par exemple, nous devons afficher une boîte de dialogue du bas avec un en-tête TextView mutable, un ScrollView mutable et un pied de page TextView mutable. La hauteur maximale de la boîte de dialogue est de 320dp , lorsque la hauteur totale n'atteint pas 320dp. ScrollView agit comme wrap_content, lorsque la hauteur totale dépasse ScrollView agit comme "maxHeight = 320dp - hauteur de l'en-tête - hauteur du pied de page".

Nous pouvons y parvenir simplement via un fichier de mise en page xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="320dp">

    <TextView
        android:id="@+id/tv_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_10"
        android:gravity="center"
        android:padding="10dp"
        app:layout_constraintBottom_toTopOf="@id/scroll_view"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1"
        app:layout_constraintVertical_chainStyle="packed"
        tools:text="header" />

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_30"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@id/tv_footer"
        app:layout_constraintHeight_max="300dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_header">

        <LinearLayout
            android:id="@+id/ll_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_sub1"
                android:layout_width="match_parent"
                android:layout_height="160dp"
                android:gravity="center"
                android:textColor="@color/orange_light"
                tools:text="sub1" />

            <TextView
                android:id="@+id/tv_sub2"
                android:layout_width="match_parent"
                android:layout_height="160dp"
                android:gravity="center"
                android:textColor="@color/orange_light"
                tools:text="sub2" />

        </LinearLayout>
    </ScrollView>

    <TextView
        android:id="@+id/tv_footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/black_50"
        android:gravity="center"
        android:padding="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/scroll_view"
        tools:text="footer" />
</android.support.constraint.ConstraintLayout>

La plupart des codes d'importation sont courts:

app:layout_constraintVertical_bias="1"
app:layout_constraintVertical_chainStyle="packed"

app:layout_constrainedHeight="true"

L'utilisation horizontale de maxWidth est tout à fait la même.


1

Avez-vous essayé d'utiliser la valeur layout_weight ? Si vous en définissez une sur une valeur supérieure à 0, cela étendra cette vue dans l'espace restant disponible.

Si vous aviez plusieurs vues qui devaient être étirées, la valeur deviendra un poids entre elles.

Donc, si vous aviez deux vues définies sur une valeur layout_weight de 1, elles s'étireraient toutes les deux pour remplir l'espace, mais elles s'étireraient toutes les deux sur une quantité d'espace égale. Si vous définissez l'un d'entre eux sur la valeur 2, il s'étirerait deux fois plus que l'autre vue.

Quelques informations supplémentaires ici répertoriées sous Disposition linéaire.


1
Le problème avec les poids est qu'ils sont relatifs. Différentes tailles d'écran, différents résultats, par exemple avec un écran de 800 pixels, je peux définir un poids sur une certaine valeur, de sorte qu'une zone spécifique se retrouve avec les 200 pixels souhaités. Cependant, avec un écran 850px, la zone spécifique finit par être plus grande que 200px, mais les éléments inclus ne font toujours que 200px. C'est pourquoi j'ai préféré avoir un maxHeightque je puisse régler sur une valeur de creux spécifique. (J'ai finalement fini par calculer et définir les hauteurs par programme)
znq

1

Je pense que vous pouvez régler la hauteur au moment de l'exécution pour 1 article seulement scrollView.setHeight(200px), pour 2 articles scrollView.setheight(400px)pour 3 ou plusscrollView.setHeight(600px)


8
Vous ne souhaitez pas définir la dimension dans "px". Il est très probable que vous n'obteniez pas le résultat souhaité sur plusieurs appareils. developer.android.com/guide/topics/resources/…
Hernd DerBeld

@HerndDerBeld c'est ainsi que cela fonctionne dans le code. si vous le souhaitez, vous pouvez toujours convertir assez facilement de DP en pixels: float pixels = TypedValue.applyDimension (TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources () .getDisplayMetrics ());
développeur android

1

Comme nous le savons, les appareils exécutant Android peuvent avoir différentes tailles d'écran. Comme nous le savons par ailleurs, les vues doivent s'ajuster dynamiquement et devenir l'espace qui convient.

Si vous définissez une hauteur maximale, vous forcez peut-être la vue à ne pas avoir suffisamment d'espace ou à prendre moins d'espace. Je sais que parfois, il semble être pratiquement de définir une hauteur maximale. Mais si jamais la résolution change radicalement, et elle le sera !, alors la vue, qui a une hauteur maximale, ne semblera pas appropriée.

Je pense qu'il n'y a pas de moyen approprié de faire exactement la mise en page que vous voulez. Je vous recommande de réfléchir à votre mise en page en utilisant des gestionnaires de mise en page et des mécanismes relatifs. Je ne sais pas ce que vous essayez d'accomplir, mais cela me semble un peu étrange qu'une liste ne montre que trois éléments, puis l'utilisateur doit faire défiler.

btw. minHeight n'est pas garanti (et ne devrait peut-être pas exister non plus). cela peut avoir un certain avantage de forcer les éléments à être visibles tandis que d'autres éléments relatifs deviennent plus petits.


6
C'est faux. Avec cette logique, vous ne pourriez pas non plus dire android: layout_width = "500dp".
Glenn Maynard

Je ne vois pas ce qui devrait être faux ni votre interprétation logique. Si vous définissez layout_width (ce qui est parfois correct), il n'est pas garanti que vous l'obteniez. 500dp peut-être regarder sur un appareil approprié, sur un autre non. Gestionnaires de mise en page ftw! Peut-être pourriez-vous expliquer plus bcs que le vote négatif dérange :)
Diego Frehner

3
Il est tout aussi valable de dire android: maxWidth = "500dp" que de dire android: layout_width = "500dp". Ils imposent tous deux des dimensions spécifiques sur la vue.
Glenn Maynard

1

Si quelqu'un envisage d'utiliser la valeur exacte pour LayoutParams, par exemple

setLayoutParams(new LayoutParams(Y, X );

N'oubliez pas de prendre en compte la densité de l'affichage de l'appareil, sinon vous pourriez avoir un comportement très étrange sur différents appareils. Par exemple:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics d = new DisplayMetrics();
display.getMetrics(d);
setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, (int)(50*d.density) ));

0

Obtenez d'abord la hauteur de l'élément en pixels

View rowItem = adapter.getView(0, null, scrollView);   
rowItem.measure(0, 0);    
int heightOfItem = rowItem.getMeasuredHeight();

alors simplement

Display display = getWindowManager().getDefaultDisplay();    
DisplayMetrics displayMetrics = new DisplayMetrics();    
display.getMetrics(displayMetrics);    
scrollView.getLayoutParams().height = (int)((heightOfItem * 3)*displayMetrics .density);

0

si vous voulez créer une vue de défilement ou une vue de liste sans débordement, mais uniquement sur un RelativeLayout avec une vue de dessus et une vue de dessous en haut et en bas:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/topview"
    android:layout_below="@+id/bottomview" >

Cela nécessite plus de crédit. Mise en œuvre spécifique mais simple.
Luke Allison

0

J'ai utilisé un ScrollView personnalisé fait dans Kotlin qui utilise maxHeight. Exemple d'utilisation:

<com.antena3.atresplayer.tv.ui.widget.ScrollViewWithMaxHeight
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:maxHeight="100dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
</com.antena3.atresplayer.tv.ui.widget.ScrollViewWithMaxHeight>

Voici le code de ScrollViewWidthMaxHeight:

import android.content.Context
import android.util.AttributeSet
import android.widget.ScrollView
import timber.log.Timber

class ScrollViewWithMaxHeight @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ScrollView(context, attrs, defStyleAttr) {

companion object {
    var WITHOUT_MAX_HEIGHT_VALUE = -1
}

private var maxHeight = WITHOUT_MAX_HEIGHT_VALUE

init {
    val a = context.obtainStyledAttributes(
        attrs, R.styleable.ScrollViewWithMaxHeight,
        defStyleAttr, 0
    )
    try {
        maxHeight = a.getDimension(
            R.styleable.ScrollViewWithMaxHeight_android_maxHeight,
            WITHOUT_MAX_HEIGHT_VALUE.toFloat()
        ).toInt()
    } finally {
        a.recycle()
    }
}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    var heightMeasure = heightMeasureSpec
    try {
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)
        if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE) {
            heightSize = maxHeight
            heightMeasure = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST)
        } else {
            heightMeasure = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.UNSPECIFIED)
        }
        layoutParams.height = heightSize
    } catch (e: Exception) {
        Timber.e(e, "Error forcing height")
    } finally {
        super.onMeasure(widthMeasureSpec, heightMeasure)
    }
}

fun setMaxHeight(maxHeight: Int) {
    this.maxHeight = maxHeight
}
}

qui a également besoin de cette déclaration dans values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollViewWithMaxHeight">
        <attr name="android:maxHeight" />
    </declare-styleable>
</resources>
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.