J'ai des onglets d'installation comme UPDATE 29/05/2015 this post. Les onglets prennent toute la largeur de mon mobile Nexus 4, mais de la tablette Nexus 7 au centre, sans couvrir la largeur de l'écran.
Nexus 7 capture d'écran Nexus 4 capture d'écran
Une réponse "plus simple" empruntée à Kaizie serait simplement ajouter app:tabMaxWidth="0dp"
dans votre TabLayout
xml:
<Android.support.design.widget.TabLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
J'ai eu le même problème et j'ai vérifié le style TabLayout, et j'ai trouvé que son style par défaut est Widget.Design.TabLayout
qui a différentes implémentations (normal, paysage et sw600dp).
Celui dont nous avons besoin est celui pour les tablettes (sw600dp) qui a la mise en oeuvre suivante:
<style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
<item name="tabGravity">center</item>
<item name="tabMode">fixed</item>
</style>
À partir de ce style, nous utiliserons "tabGravity" (dont les valeurs possibles sont "center" ou "fill") en utilisant la valeur "fill".
Mais nous devons aller plus loin et nous voyons ensuite que celui-ci s’étend de Base.Widget.Design.TabLayout
, dont l’implémentation est:
<style name="Base.Widget.Design.TabLayout" parent="Android:Widget">
<item name="tabMaxWidth">@dimen/tab_max_width</item>
<item name="tabIndicatorColor">?attr/colorAccent</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabPaddingStart">12dp</item>
<item name="tabPaddingEnd">12dp</item>
<item name="tabBackground">?attr/selectableItemBackground</item>
<item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
<item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
Ainsi, à partir de ce style, nous devrons remplacer "tabMaxWidth". Dans mon cas, je l'ai réglé sur 0dp
, donc il n'y a pas de limite.
Et mon style ressemblait à ça:
<style name="MyTabLayout" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
</style>
Et puis la barre d'onglets remplira tout l'écran d'un côté à l'autre.
Solution pour la liste déroulante: (TabLayout.MODE_SCROLLABLE), c’est-à-dire chaque fois que vous avez besoin de plus de 2 onglets (onglets dynamiques)
Étape 1: style.xml
<style name="tabCustomStyle" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
<item name="tabIndicatorColor">#FFFEEFC4</item>
<item name="tabIndicatorHeight">2dp</item>
<item name="tabTextAppearance">@style/MyCustomTabTextAppearance</item>
<item name="tabSelectedTextColor">#FFFEEFC4</item>
</style>
<style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
<item name="Android:textSize">@dimen/tab_text_size</item>
<item name="Android:textAppearance">@style/TextAppearance.roboto_medium</item>
<item name="textAllCaps">true</item>
</style>
<style name="TextAppearance.roboto_medium" parent="Android:TextAppearance">
<item name="Android:fontFamily">sans-serif-medium</item>
</style>
Étape 2: Votre mise en page XML
<Android.support.design.widget.TabLayout
Android:id="@+id/sliding_tabs"
style="@style/tabCustomStyle"
Android:layout_width="match_parent"
Android:layout_height="@dimen/tab_strip_height"
Android:background="@color/your_color"
app:tabMode="scrollable"
app:tabTextColor="@color/your_color" />
Étape 3: Dans votre activité/fragment où que vous soyez avec des onglets.
/**
* To allow equal width for each tab, while (TabLayout.MODE_SCROLLABLE)
*/
private void allotEachTabWithEqualWidth() {
ViewGroup slidingTabStrip = (ViewGroup) mTabLayout.getChildAt(0);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
View tab = slidingTabStrip.getChildAt(i);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) tab.getLayoutParams();
layoutParams.weight = 1;
tab.setLayoutParams(layoutParams);
}
}
Pour que les onglets occupent toute la largeur (divisés en tailles égales), appliquez ce qui suit à la vue TabLayout
:
TabLayout tabLayout = (TabLayout) findViewById(R.id.your_tab_layout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
C'est utile, vous devez essayer
<Android.support.design.widget.TabLayout
Android:id="@+id/tabs"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabIndicatorColor="@color/white"
app:tabSelectedTextColor="@color/white"
app:tabTextColor="@color/orange" />
<Android.support.design.widget.TabLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed" />
travaille pour moi. Cela a aussi xmlns:app="http://schemas.Android.com/apk/res-auto"
Pour moi, le code suivant a fonctionné et était suffisant.
<Android.support.design.widget.TabLayout
Android:id="@+id/tabs"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:tabGravity="fill"/>
Vérifiez ci-dessous le code pour les solutions.
Ci-dessous le code de mise en page:
<com.yourpackage.CustomTabLayout
Android:id="@+id/tabs"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="@color/off_white"
app:tabIndicatorColor="@color/primaryColor"
app:tabIndicatorHeight="3dp"
app:tabMode="scrollable"
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp" />
Remarque: pour le nombre d'onglets dynamiques, n'oubliez pas d'appeler setTabNumbers (tabcount).
import Android.content.Context;
import Android.support.design.widget.TabLayout;
import Android.util.AttributeSet;
import Android.util.
import Java.lang.reflect.Field;
public class CustomTabLayout extends TabLayout
{
private static final int WIDTH_INDEX = 0;
private int DIVIDER_FACTOR = 3;
private static final String SCROLLABLE_TAB_MIN_WIDTH = "mScrollableTabMinWidth";
public CustomTabLayout(Context context) {
super(context);
initTabMinWidth();
}
public CustomTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initTabMinWidth();
}
public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initTabMinWidth();
}
public void setTabNumbers(int num)
{
this.DIVIDER_FACTOR = num;
initTabMinWidth();
}
private void initTabMinWidth()
{
int[] wh = getScreenSize(getContext());
int tabMinWidth = wh[WIDTH_INDEX] / DIVIDER_FACTOR;
Log.v("CUSTOM TAB LAYOUT", "SCREEN WIDTH = " + wh[WIDTH_INDEX] + " && tabTotalWidth = " + (tabMinWidth*DIVIDER_FACTOR) + " && TotalTabs = " + DIVIDER_FACTOR);
Field field;
try {
field = TabLayout.class.getDeclaredField(SCROLLABLE_TAB_MIN_WIDTH);
field.setAccessible(true);
field.set(this, tabMinWidth);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;
public static int[] getScreenSize(Context context) {
int[] widthHeight = new int[2];
widthHeight[WIDTH_INDEX] = 0;
widthHeight[HEIGHT_INDEX] = 0;
try {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthHeight[WIDTH_INDEX] = size.x;
widthHeight[HEIGHT_INDEX] = size.y;
if (!isScreenSizeRetrieved(widthHeight))
{
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
widthHeight[0] = metrics.widthPixels;
widthHeight[1] = metrics.heightPixels;
}
// Last defense. Use deprecated API that was introduced in lower than API 13
if (!isScreenSizeRetrieved(widthHeight)) {
widthHeight[0] = display.getWidth(); // deprecated
widthHeight[1] = display.getHeight(); // deprecated
}
} catch (Exception e) {
e.printStackTrace();
}
return widthHeight;
}
private static boolean isScreenSizeRetrieved(int[] widthHeight) {
return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
}
}
Référence extraite de https://medium.com/@elsenovraditya/set-tab-minimum-width-of-scrollable-tablayout-programmatically-8146d6101efe
Dans ma variante de ce problème, j'avais 3 onglets de taille modérée qui ne prenaient pas toute la largeur sur les tablettes. Je n'avais pas besoin de faire défiler les onglets sur les tablettes, car celles-ci sont assez grandes pour les afficher toutes ensemble sans aucun défilement. Mais j'avais besoin que les onglets soient défilables sur les téléphones, car les téléphones sont trop petits pour afficher tous les onglets ensemble.
La meilleure solution dans mon cas consistait à ajouter un fichier res/layout-sw600dp/main_activity.xml
, où le TabLayout approprié pourrait avoir app:tabGravity="fill"
et app:tabMode="fixed"
. Mais dans mon res/layout/main_activity.xml
habituel, je laissais de côté app:tabGravity="fill"
et app:tabMode="fixed"
, et j'avais app:tabMode="scrollable"
à la place.
Solution pour Scrollable (Kotlin)
En XML:
<com.google.Android.material.tabs.TabLayout
Android:id="@+id/home_tab_layout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
Android:fillViewport="true"
app:tabGravity="fill" />
En Kotlin:
Dans mon cas, si moins de 3 onglets, j'attribue un espace égal.
Note: Si la condition est selon vos besoins
if(list.size <= 3){
allotEachTabWithEqualWidth(your_tab_layout)
}
fun allotEachTabWithEqualWidth(tabLayout: TabLayout) {
mTabLayout.tabMode= TabLayout.MODE_FIXED
val slidingTabStrip = tabLayout.getChildAt(0) as ViewGroup
for (i in 0 until tabLayout.getTabCount()) {
val tab = slidingTabStrip.getChildAt(i)
val layoutParams = tab.layoutParams as LinearLayout.LayoutParams
layoutParams.weight = 1f
tab.layoutParams = layoutParams
}
}