web-dev-qa-db-fra.com

Comment coiffer le séparateur entre les onglets sandwich à la crème glacée?

J'utilise le style suivant avec un ensemble de neuf images de patch pour créer une ligne rouge au bas de certains onglets sandwich à la crème glacée au lieu de la ligne bleue standard:

<style name="customTabStyle" parent="@Android:style/Widget.Holo.ActionBar.TabBar">
    <item name="Android:tabStripLeft">@null</item>
    <item name="Android:tabStripRight">@null</item>
    <item name="Android:tabStripEnabled">false</item>
    <item name="Android:showDividers">none</item>
    <item name="Android:measureWithLargestChild">true</item>
    <item name="Android:background">@drawable/tab_line</item>
    <item name="Android:gravity">center</item>
</style>

<style name="customTabBar" parent="@Android:style/Widget.Holo">
    <item name="Android:showDividers">middle</item>
    <item name="Android:divider">@drawable/divider2</item>
    <item name="Android:dividerPadding">0dp</item>
</style>

<style name="LightThemeSelector" parent="Android:Theme.Holo.Light">
    <item name="Android:actionBarTabStyle">@style/customTabStyle</item>
    <item name="Android:actionBarTabBarStyle">@style/customTabBar</item>
</style>

La ligne rouge est affichée et tout semble bon, à l'exception du séparateur entre les onglets. Comme vous pouvez le voir à l'intérieur de la boîte verte sur l'image, la ligne n'est pas tracée sous le séparateur. Comment sélectionner un dessinable ou un style pour ce séparateur?

Le Android:divider et Android:showDividers les éléments ne sont pas responsables du séparateur entre les onglets. Ils ne sélectionnent que le séparateur dessiné entre l'icône de l'onglet et le titre de l'onglet. Je cache ces séparateurs car il n'y a pas de titre et un séparateur aurait l'air étrange.

Screenshot from the resulting tab bar


pdate Avec la réponse d'Aneal à l'esprit, j'ai ajouté un deuxième style customTabBar. Le style sélectionne un dessinable comme séparateur. Le séparateur est une ligne noire continue créée avec le dessin 9patch suivant:

9patch drawable creating the divider

Avec ce dessin, le séparateur est dessiné, mais il y a aussi une ligne vierge à côté:

tab bar with dividers

45
Janusz

Après avoir supprimé tous les styles que j'utilise, j'ai obtenu l'image suivante:

enter image description here

Cette image contient également les petits espaces. Il semble donc qu'il s'agit d'une sorte de comportement par défaut.

Cependant, j'ai trouvé un moyen de contourner le problème. J'ai défini la ligne rouge comme arrière-plan standard pour toute la barre d'onglets. De cette façon, l'écart apparaît mais personne ne peut le voir car l'arrière-plan, qui contient déjà la ligne est affiché.

J'utilise maintenant le style suivant pour toutes mes activités:

<style name="LightThemeSelector" parent="Android:Theme.Holo.Light">
    <item name="Android:actionBarTabBarStyle">@style/customTabBar</item>
    <item name="Android:actionBarTabStyle">@style/customTabStyle</item>
</style>

Ce style est utilisé pour styliser chaque onglet unique à l'intérieur de la barre d'onglets:

<style name="customTabStyle" parent="@Android:style/Widget.Holo.ActionBar.TabView">
    <item name="Android:showDividers">none</item>
    <item name="Android:measureWithLargestChild">true</item>
    <item name="Android:background">@drawable/tab_line</item>
    <item name="Android:gravity">center</item>
</style>

Pour styliser toute la barre d'onglets, j'utilise le style suivant:

<style name="customTabBar" parent="@Android:style/Widget.Holo.ActionBar.TabBar">
    <item name="Android:showDividers">middle</item>
    <item name="Android:divider">@drawable/divider</item>
    <item name="Android:dividerPadding">0dp</item>
    <item name="Android:background">@drawable/tab_unselected</item>
</style>

Ce style définit mon séparateur personnalisé et définit également l'arrière-plan de la barre d'onglets. Comme arrière-plan, je mets directement les neuf patchs à dessiner qui sont dessinés si aucun onglet n'est sélectionné. Le résultat de tout cela est une barre d'onglets avec un soulignement rouge sans aucun espace.

enter image description here

51
Janusz

Voici.

<style name="YourTheme" parent="@Android:style/Theme.Holo.Light">
    <item name="Android:actionBarTabBarStyle">@style/Divider</item>
</style>

<style name="Divider" parent="@Android:style/Widget.Holo.ActionBar.TabBar">
    <item name="Android:divider">@drawable/your_divider_drawable_here</item>
    <item name="Android:showDividers">middle</item>
    <item name="Android:dividerPadding">12dip</item>
</style>
22
adneal
<style name="AppTheme" parent="AppBaseTheme">
    <item>......
    </item>
    <item name="Android:actionBarDivider">@null</item>

</style>

ici @null est pour ne pas fournir de diviseur et si vous souhaitez personnaliser votre diviseur, utilisez @ drawable/your_divider_image

8
Devang

Btw. Cela est dû à un énorme bogue dans l'attribut ICS dans la mise en œuvre de la classe LinerLayout d'Android: divider). Il a été introduit dans Honeycomb, rompu dans ICS et fonctionne à nouveau dans Dragée.

Le problème est que lorsque vous utilisez Android: le séparateur crée un petit espace entre les enfants pour placer le séparateur, mais placez le séparateur non dans cet espace, mais après, il sera donc chevauché par l'onglet lui-même et l'espace restera vide. Bug très stupide. Essayez de comparer le code source de LinerLayout pour les versions 4.0 et 4.1.

Et oui, la solution est de mettre le délimiteur à l'arrière-plan de tous les onglets et il ne sera visible que dans les espaces entre les onglets causés par ce bogue.

6
ATom

Si vous souhaitez vous débarrasser des séparateurs, vous pouvez faire ceci:

<style name="customTabBar" parent="@Android:style/Widget.Holo.ActionBar.TabBar">
    <item name="Android:divider">@null</item>
</style>
6
Kid24

Basé sur réponse d'ATom , voici un moyen d'avoir quelque chose qui ressemble à des diviseurs dans toutes les versions Android Android.

Pour que cela fonctionne, vous n'utilisez aucune des méthodes de séparation natives (car elles sont cassées dans certaines versions). N'oubliez pas de supprimer tout code où vous définissez des séparateurs.

L'astuce consiste simplement à définir une très petite marge droite dans les vues utilisées pour chaque onglet. De cette façon, il y aura un petit espace où vous pourrez voir l'arrière-plan (le TabHost). Pour terminer cela, vous définissez l'arrière-plan du TabHost pour imiter le diviseur étiré.

Bien que cette astuce ne fonctionne pas pour toutes les conceptions possibles que vous pourriez souhaiter, elle fonctionne bien pour de nombreux cas comme celui que j'avais.

Voici un exemple d'implémentation:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // ...
    //      inflate or create tabHost  in code
    //      call tabHost.setup
    // ...

    TabWidget tabWidget = tabHost.getTabWidget();
    tabWidget.setBackgroundResource(R.drawable.tab_divider);

    // ...  add tabs

    for( int i = 0; tabWidget.getChildCount()-1; i++) {
        View view = tabWidget.getChildAt(i);
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
        layoutParams.rightMargin = getResources().getDimensionPixelSize(R.dimen.tab_divider_width); //1dp
        view.setLayoutParams(layoutParams);
    }
    return tabHost;
}

Voici un exemple tab_divider dessinable:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape="rectangle">
        <solid Android:color="@color/divider_color" />
        <stroke Android:width="@dimen/tab_divider_vertical_padding" 
                Android:color="@color/tab_background_color"/>
</shape>
1
Pedro Loureiro