Layout delle schede di progettazione del supporto Android: centro di gravità e modalità scorrevole


98

Sto cercando di utilizzare il nuovo Design TabLayout nel mio progetto. Voglio che il layout si adatti a ogni dimensione e orientamento dello schermo, ma può essere visto correttamente in un orientamento.

Ho a che fare con Gravity e Mode impostando il mio tabLayout come:

    tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

Quindi mi aspetto che se non c'è spazio, tabLayout è scorrevole, ma se c'è spazio, è centrato.

Dalle guide:

public static final int GRAVITY_CENTER Gravity utilizzato per disporre le schede al centro del TabLayout.

public static final int GRAVITY_FILL Gravity utilizzato per riempire il TabLayout il più possibile. Questa opzione ha effetto solo se utilizzata con MODE_FIXED.

public static final int MODE_FIXED Le schede fisse visualizzano tutte le schede contemporaneamente e sono utilizzate al meglio con contenuti che beneficiano di rapidi pivot tra le schede. Il numero massimo di schede è limitato dalla larghezza della vista. Le schede fisse hanno la stessa larghezza, in base all'etichetta della scheda più ampia.

public static final int MODE_SCROLLABLE Le schede scorrevoli visualizzano un sottoinsieme di schede in un dato momento e possono contenere etichette di schede più lunghe e un numero maggiore di schede. Sono utilizzati al meglio per esplorare i contesti nelle interfacce touch quando gli utenti non hanno bisogno di confrontare direttamente le etichette delle schede.

Quindi GRAVITY_FILL è compatibile solo con MODE_FIXED ma, in non specifica nulla per GRAVITY_CENTER, mi aspetto che sia compatibile con MODE_SCROLLABLE, ma questo è ciò che ottengo usando GRAVITY_CENTER e MODE_SCROLLABLE

inserisci qui la descrizione dell'immagine

Quindi utilizza SCROLLABLE in entrambi gli orientamenti, ma non GRAVITY_CENTER.

Questo è quello che mi aspetterei dal paesaggio; ma per avere questo, devo impostare MODE_FIXED, quindi quello che ottengo in verticale è:

inserisci qui la descrizione dell'immagine

Perché GRAVITY_CENTER non funziona per SCROLLABLE se tabLayout si adatta allo schermo? C'è un modo per impostare la gravità e la modalità dinamicamente (e per vedere cosa mi aspetto)?

Grazie mille!

MODIFICATO: Questo è il layout del mio TabLayout:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="match_parent"
    android:background="@color/orange_pager"
    android:layout_height="wrap_content" />

@ Fighter42 hai trovato qualche soluzione a questo? Sono di fronte allo stesso problema.
Spynet

L'unico modo che ho trovato è stato ottenere la dimensione delle tue schede (manualmente) e quindi configurare dinamicamente i parametri di layout a seconda che si adattasse o meno.
Javier Delgado

@ Fighter42, puoi pubblicare del codice di esempio per la soluzione che stai utilizzando?
Sammys

1
So che la mia risposta non va bene per la logica ma mi aiuta. Metti degli spazi prima e dopo il testo. Quindi sarà scorrevole. in entrambe le modalità.
AmmY

Risposte:


127

Tab gravità solo effetti MODE_FIXED.

Una possibile soluzione è impostare il tuo layout_widthsu wrap_contente layout_gravitysu center_horizontal:

<android.support.design.widget.TabLayout
    android:id="@+id/sliding_tabs"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    app:tabMode="scrollable" />

Se le linguette sono più piccole della larghezza dello schermo, anche la TabLayoutstessa sarà più piccola e sarà centrata a causa della gravità. Se le schede sono più grandi della larghezza dello schermo, TabLayoutcorrisponderà alla larghezza dello schermo e lo scorrimento si attiverà.


1
Sto usando Material design per la mia app. Ho seguito l'esempio da androidhive.info/2015/09/… Tab scorrevole non funziona nei dispositivi Kitkat e Jelly Bean. In lollipop sono in grado di scorrere la scheda ma in dispositivi diversi da lollipop la scheda scorrevole non funziona ma lo scorrimento funziona correttamente. Posso sapere quale sarebbe il problema.
user2681579

Questo non ha funzionato per me su API 15 / support.design:25.1.0. Le tabulazioni erano giustificate a sinistra quando più strette della larghezza della finestra. Impostazione app:tabMaxWidth="0dp"e android:layout_centerHorizontal="true"lavorato per centrare le schede.
Baker

1
Ha funzionato per me. Le schede sono sempre centrate, ma quando non sono effettivamente scorrevoli, non riempiono tutta la larghezza.
José Augustinho

14

questo è come l'ho fatto

TabLayout.xml

<android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:background="@android:color/transparent"
            app:tabGravity="fill"
            app:tabMode="scrollable"
            app:tabTextAppearance="@style/TextAppearance.Design.Tab"
            app:tabSelectedTextColor="@color/myPrimaryColor"
            app:tabIndicatorColor="@color/myPrimaryColor"
            android:overScrollMode="never"
            />

Oncreate

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
        mTabLayout = (TabLayout)findViewById(R.id.tab_layout);
        mTabLayout.setOnTabSelectedListener(this);
        setSupportActionBar(mToolbar);

        mTabLayout.addTab(mTabLayout.newTab().setText("Dashboard"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Signature"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Booking/Sampling"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Calendar"));
        mTabLayout.addTab(mTabLayout.newTab().setText("Customer Detail"));

        mTabLayout.post(mTabLayout_config);
    }

    Runnable mTabLayout_config = new Runnable()
    {
        @Override
        public void run()
        {

           if(mTabLayout.getWidth() < MainActivity.this.getResources().getDisplayMetrics().widthPixels)
            {
                mTabLayout.setTabMode(TabLayout.MODE_FIXED);
                ViewGroup.LayoutParams mParams = mTabLayout.getLayoutParams();
                mParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
                mTabLayout.setLayoutParams(mParams);

            }
            else
            {
                mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    };

Ho apportato piccole modifiche alla soluzione di @Mario Velasco sulla parte eseguibile


Questa soluzione ha gli stessi problemi che ho menzionato sulla soluzione di Tiago.
Sotti

Questa soluzione funziona sulla scheda senza icona, cosa succede se ho un'icona con il testo ?? : /
Emre Tekin

@EmreTekin sì, funziona con un'icona, le mie schede avevano icone con testo
Flux

tabLayout.getWidth()restituisce sempre zero per me
ishandutta2007

9

mantiene le cose semplici basta aggiungere app: tabMode = "scrollable" e android: layout_gravity = "bottom"

proprio come questo

<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
app:tabMode="scrollable"
app:tabIndicatorColor="@color/colorAccent" />

inserisci qui la descrizione dell'immagine


7
Questo non è ciò che chiede il creatore. Il problema con questo approccio è che negli scenari in cui hai 2 schede o 3 tre schede nei telefoni in cui il testo è piccolo, avrai un layout come il Google Play Store in cui le schede si trovano sul lato sinistro. Il creatore desidera che le schede arrivino da un bordo all'altro quando possibile e che scorrano in altro modo.
Sotti

Stesso problema. Puoi aggiustarlo?
Hoang Duc Tuan

8

Poiché non ho trovato il motivo per cui si verifica questo comportamento, ho utilizzato il seguente codice:

float myTabLayoutSize = 360;
if (DeviceInfo.getWidthDP(this) >= myTabLayoutSize ){
    tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
}

Fondamentalmente, devo calcolare manualmente la larghezza del mio tabLayout e quindi impostare la modalità Tab a seconda che il tabLayout si adatti o meno al dispositivo.

Il motivo per cui ottengo la dimensione del layout manualmente è perché non tutte le schede hanno la stessa larghezza in modalità Scrollable, e questo potrebbe provocare che alcuni nomi usino 2 linee come è successo a me nell'esempio.


Con questa soluzione il testo potrebbe potenzialmente essere ridotto e utilizzando anche 2 righe. Vedi altre risposte e soluzioni in questo thread a riguardo. Stai riducendo il rischio che appaia ma apparirà spesso comunque quando il TabLayout è un po 'più piccolo della ScreenWidth.
Sotti

7

Guarda android-tablayouthelper

Cambia automaticamente TabLayout.MODE_FIXED e TabLayout.MODE_SCROLLABLE dipende dalla larghezza totale della tabulazione.


Ma quando i titoli della scheda sono dinamici. Il testo va nella riga successiva. E se usa layout personalizzato per tab. Testo ellittico alla fine come
AndroidGeek

4

Questa è la soluzione che ho usato per cambiare automaticamente tra SCROLLABLEe FIXED+ FILL. È il codice completo per la soluzione @ Fighter42:

(Il codice seguente mostra dove inserire la modifica se hai utilizzato il modello di attività a schede di Google)

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    // Set up the tabs
    final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    // Mario Velasco's code
    tabLayout.post(new Runnable()
    {
        @Override
        public void run()
        {
            int tabLayoutWidth = tabLayout.getWidth();

            DisplayMetrics metrics = new DisplayMetrics();
            ActivityMain.this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int deviceWidth = metrics.widthPixels;

            if (tabLayoutWidth < deviceWidth)
            {
                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
            } else
            {
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    });
}

Disposizione:

    <android.support.design.widget.TabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

Se non è necessario riempire la larghezza, è meglio usare la soluzione @karaokyo.


questo funziona bene; passare da orizzontale a verticale e viceversa fa esattamente quello che ci si potrebbe aspettare. Google dovrebbe implementarlo nel modello predefinito per l'attività a schede.
Someone Somewhere

Questa risposta ha gli stessi problemi che ho menzionato nella soluzione di Tiago.
Sotti

4

Ho creato una classe AdaptiveTabLayout per ottenere questo risultato. Questo è stato l'unico modo che ho trovato per risolvere effettivamente il problema, rispondere alla domanda ed evitare / risolvere problemi che altre risposte qui non fanno.

Appunti:

  • Gestisce i layout del telefono / tablet.
  • Gestisce casi in cui c'è abbastanza spazio per MODE_SCROLLABLEma non abbastanza spazio per MODE_FIXED. Se non gestisci questo caso, succederà su alcuni dispositivi, vedrai dimensioni di testo diverse o fornirai due righe di testo in alcune schede, il che sembra male.
  • Ottiene misure reali e non fa alcuna supposizione (come lo schermo è largo 360dp o qualsiasi altra cosa ...). Funziona con le dimensioni reali dello schermo e le dimensioni reali delle schede. Ciò significa che funziona bene con le traduzioni perché non assume alcuna dimensione di scheda, le schede vengono misurate.
  • Si occupa dei diversi passaggi nella fase di onLayout per evitare lavori extra.
  • La larghezza del layout deve essere wrap_contentin xml. Non impostare alcuna modalità o gravità su xml.

AdaptiveTabLayout.java

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.widget.LinearLayout;

public class AdaptiveTabLayout extends TabLayout
{
    private boolean mGravityAndModeSeUpNeeded = true;

    public AdaptiveTabLayout(@NonNull final Context context)
    {
        this(context, null);
    }

    public AdaptiveTabLayout(@NonNull final Context context, @Nullable final AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public AdaptiveTabLayout
    (
            @NonNull final Context context,
            @Nullable final AttributeSet attrs,
            final int defStyleAttr
    )
    {
        super(context, attrs, defStyleAttr);
        setTabMode(MODE_SCROLLABLE);
    }

    @Override
    protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b)
    {
        super.onLayout(changed, l, t, r, b);

        if (mGravityAndModeSeUpNeeded)
        {
            setModeAndGravity();
        }
    }

    private void setModeAndGravity()
    {
        final int tabCount = getTabCount();
        final int screenWidth = UtilsDevice.getScreenWidth();
        final int minWidthNeedForMixedMode = getMinSpaceNeededForFixedMode(tabCount);

        if (minWidthNeedForMixedMode == 0)
        {
            return;
        }
        else if (minWidthNeedForMixedMode < screenWidth)
        {
            setTabMode(MODE_FIXED);
            setTabGravity(UtilsDevice.isBigTablet() ? GRAVITY_CENTER : GRAVITY_FILL) ;
        }
        else
        {
            setTabMode(TabLayout.MODE_SCROLLABLE);
        }

        setLayoutParams(new LinearLayout.LayoutParams
                (LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        mGravityAndModeSeUpNeeded = false;
    }

    private int getMinSpaceNeededForFixedMode(final int tabCount)
    {
        final LinearLayout linearLayout = (LinearLayout) getChildAt(0);
        int widestTab = 0;
        int currentWidth;

        for (int i = 0; i < tabCount; i++)
        {
            currentWidth = linearLayout.getChildAt(i).getWidth();

            if (currentWidth == 0) return 0;

            if (currentWidth > widestTab)
            {
                widestTab = currentWidth;
            }
        }

        return widestTab * tabCount;
    }

}

E questa è la classe DeviceUtils:

import android.content.res.Resources;

public class UtilsDevice extends Utils
{
    private static final int sWIDTH_FOR_BIG_TABLET_IN_DP = 720;

    private UtilsDevice() {}

    public static int pixelToDp(final int pixels)
    {
        return (int) (pixels / Resources.getSystem().getDisplayMetrics().density);
    }

    public static int getScreenWidth()
    {
        return Resources
                .getSystem()
                .getDisplayMetrics()
                .widthPixels;
    }

    public static boolean isBigTablet()
    {
        return pixelToDp(getScreenWidth()) >= sWIDTH_FOR_BIG_TABLET_IN_DP;
    }

}

Esempio di utilizzo:

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    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="match_parent">

    <com.com.stackoverflow.example.AdaptiveTabLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="?colorPrimary"
        app:tabIndicatorColor="@color/white"
        app:tabSelectedTextColor="@color/text_white_primary"
        app:tabTextColor="@color/text_white_secondary"
        tools:layout_width="match_parent"/>

</FrameLayout>

Gist

Problemi / Chiedi aiuto:

  • Vedrai questo:

Logcat:

W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$SlidingTabStrip{3e1ebcd6 V.ED.... ......ID 0,0-466,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{3423cb57 VFE...C. ..S...ID 0,0-144,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{377c4644 VFE...C. ......ID 144,0-322,96} during layout: running second layout pass
W/View: requestLayout() improperly called by android.support.design.widget.TabLayout$TabView{19ead32d VFE...C. ......ID 322,0-466,96} during layout: running second layout pass

Non sono sicuro di come risolverlo. Eventuali suggerimenti?

  • Per rendere le misure figlio TabLayout, sto facendo alcuni casting e ipotesi (come il bambino è un LinearLayout contenente altre viste ....) Ciò potrebbe causare problemi con ulteriori aggiornamenti della libreria di supporto alla progettazione. Un approccio / suggerimenti migliori?

4
 <android.support.design.widget.TabLayout
                    android:id="@+id/tabList"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    app:tabMode="scrollable"/>

1

Questo è l'unico codice che ha funzionato per me:

public static void adjustTabLayoutBounds(final TabLayout tabLayout,
                                         final DisplayMetrics displayMetrics){

    final ViewTreeObserver vto = tabLayout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            tabLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            int totalTabPaddingPlusWidth = 0;
            for(int i=0; i < tabLayout.getTabCount(); i++){

                final LinearLayout tabView = ((LinearLayout)((LinearLayout) tabLayout.getChildAt(0)).getChildAt(i));
                totalTabPaddingPlusWidth += (tabView.getMeasuredWidth() + tabView.getPaddingLeft() + tabView.getPaddingRight());
            }

            if (totalTabPaddingPlusWidth <= displayMetrics.widthPixels){

                tabLayout.setTabMode(TabLayout.MODE_FIXED);
                tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

            }else{
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }

            tabLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        }
    });
}

I DisplayMetrics possono essere recuperati utilizzando questo:

public DisplayMetrics getDisplayMetrics() {

    final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    final Display display = wm.getDefaultDisplay();
    final DisplayMetrics displayMetrics = new DisplayMetrics();

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        display.getMetrics(displayMetrics);

    }else{
        display.getRealMetrics(displayMetrics);
    }

    return displayMetrics;
}

E il tuo XML TabLayout dovrebbe assomigliare a questo (non dimenticare di impostare tabMaxWidth su 0):

<android.support.design.widget.TabLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/tab_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:tabMaxWidth="0dp"/>

1
Questo è quasi finito, ma ci sono alcuni problemi. Il problema più ovvio è che in alcuni dispositivi (e nella maggior parte di quelli lenti) vedrai effettivamente come viene modificato e cambiato il layout.
Sotti

1
C'è un altro problema, questo approccio misura la larghezza totale del TabLayout per decidere se essere scorrevole o meno. Non è molto preciso. Ci sono situazioni in cui il TabLayout non raggiunge entrambi i bordi durante la modalità scorrevole, ma non c'è abbastanza spazio per la modalità fissa senza ridurre il testo abusando del numero di righe sulla scheda (di solito 2). Questa è una diretta conseguenza del fatto che le schede in modalità fissa hanno una larghezza fissa (screenWidth / numberOfTabs) mentre in modalità scorrevole avvolgono il testo + i padding.
Sotti

1

Tutto ciò di cui hai bisogno è aggiungere quanto segue al tuo TabLayout

custom:tabGravity="fill"

Quindi avrai:

xmlns:custom="http://schemas.android.com/apk/res-auto"
<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:tabGravity="fill"
        />

Questo non è ciò che chiede il creatore. Il problema qui è che le schede non saranno mai scorrevoli e ti libererai dello spazio sullo schermo. Le schede inizieranno a ridurre il testo e alla fine ne avranno due allineate.
Sotti

1

L'ho risolto usando quanto segue

if(tabLayout_chemistCategory.getTabCount()<4)
    {
        tabLayout_chemistCategory.setTabGravity(TabLayout.GRAVITY_FILL);
    }else
    {
        tabLayout_chemistCategory.setTabMode(TabLayout.MODE_SCROLLABLE);

    }

1

Esempio molto semplice e funziona sempre.

/**
 * Setup stretch and scrollable TabLayout.
 * The TabLayout initial parameters in layout must be:
 * android:layout_width="wrap_content"
 * app:tabMaxWidth="0dp"
 * app:tabGravity="fill"
 * app:tabMode="fixed"
 *
 * @param context   your Context
 * @param tabLayout your TabLayout
 */
public static void setupStretchTabLayout(Context context, TabLayout tabLayout) {
    tabLayout.post(() -> {

        ViewGroup.LayoutParams params = tabLayout.getLayoutParams();
        if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) { // is already set up for stretch
            return;
        }

        int deviceWidth = context.getResources()
                                 .getDisplayMetrics().widthPixels;

        if (tabLayout.getWidth() < deviceWidth) {
            tabLayout.setTabMode(TabLayout.MODE_FIXED);
            params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        } else {
            tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        tabLayout.setLayoutParams(params);

    });

}

Grazie per l'idea. Con un piccolo cambiamento per il mio caso, funziona a meraviglia
Eren Tüfekçi

1

La mia soluzione finale

class DynamicModeTabLayout : TabLayout {

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun setupWithViewPager(viewPager: ViewPager?) {
        super.setupWithViewPager(viewPager)

        val view = getChildAt(0) ?: return
        view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
        val size = view.measuredWidth

        if (size > measuredWidth) {
            tabMode = MODE_SCROLLABLE
            tabGravity = GRAVITY_CENTER
        } else {
            tabMode = MODE_FIXED
            tabGravity = GRAVITY_FILL
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.