Comment créer app bar avec des icônes en utilisant TabLayout Android Design?

j'essaie d'utiliser le nouveau TabLayout dans la bibliothèque de design android pour créer app bar avec des icônes.

public void setupTabLayout(TabLayout tabLayout) {
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
    tabLayout.setupWithViewPager(mViewpager);
    tabLayout.getTabAt(0).setIcon(R.drawable.ic_tabbar_library);
    tabLayout.getTabAt(1).setIcon(R.drawable.ic_tabbar_recents);
    tabLayout.getTabAt(2).setIcon(R.drawable.ic_tabbar_favorites);
    tabLayout.getTabAt(3).setIcon(R.drawable.ic_tabbar_notifications);
    tabLayout.getTabAt(4).setIcon(R.drawable.ic_tabbar_settings);
}

Résultat:

app bar with icons

Merci de m'aider à créer de la barre d'application similaire:

app bar with icons

Désolé mon anglais n'est pas bon.Merci d'avance !

19
demandé sur natuan241 2015-06-03 11:06:06

4 réponses

à Partir de la documentation :

https://developer.android.com/reference/android/support/design/widget/TabLayout.Tab.html#setCustomView(android.view.View)

définir une vue personnalisée à utiliser pour cet onglet. Cette option remplace les valeurs définies par setText(CharSequence) et setIcon (Drawable).

vous devrez définir le titre de valeurs vous-même

à Partir de votre exemple:

public void setupTabLayout(TabLayout tabLayout) {
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
    tabLayout.setupWithViewPager(mViewpager);

    TextView tab = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
    tab.setText("Library");
    tab.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_tabbar_library, 0, 0);
    tabLayout.getTabAt(0).setCustomView(tab);
    //..
}

custom_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tab" />

mise à Jour

l'api a changé pour vous permettre de définir un id personnalisé afin que vous n'ayez pas à définir le texte/dessiner manuellement. Il utilisera les valeurs de l'adaptateur.

si la vue fournie contient un TextView avec un ID de text1 alors que sera mis à jour avec la valeur donnée à setText(CharSequence). De la même manière, si cette mise en page contient une ImageView avec l'icône ID, alors elle sera être mis à jour avec la valeur donnée à setIcon(Drawable).

28
répondu Chris Dinon 2018-02-02 21:15:09

documentation dit Vous pouvez ajouter des éléments à TabLayout le fichier xml par l'utilisation de TabItem. Un exemple d'utilisation est de la forme:

 <android.support.design.widget.TabLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <android.support.design.widget.TabItem
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

 </android.support.design.widget.TabLayout>
2
répondu Amir Hadifar 2016-06-01 09:54:29

Vous pouvez utiliser l'attribut android:layoutTabItem affichage personnalisé. Dans le fichier de vue xml personnalisé, n'oubliez pas de définir id de la vue d'icône et de texte à @android:id/icon et android:id="@android:id/text1", alors la bibliothèque s'occupera du reste.

Voici un exemple:

. custom_tab_item.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

  <ImageView
      android:id="@android:id/icon"
      android:layout_width="16dp"
      android:layout_height="16dp"
      android:layout_marginTop="4dp"
      android:scaleType="centerInside"/>

  <TextView
      android:id="@android:id/text1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginLeft="8dp"
      android:textSize="16dp"/>

</LinearLayout>

. principal.xml

<android.support.design.widget.TabLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

  <android.support.design.widget.TabItem
      android:id="@+id/ti_activities"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:icon="@drawable/ic_question"
      android:layout="@layout/custom_tab_item"
      android:text="@string/activities"/>

  <android.support.design.widget.TabItem
      android:id="@+id/ti_profile"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:icon="@drawable/ic_question"
      android:layout="@layout/custom_tab_item"
      android:text="@string/Profile"/>

</android.support.design.widget.TabLayout>

Espérons que cette aide.

2
répondu nlt 2016-12-05 12:51:31

quand vous utilisez vector un drawable comme des icônes vous pourriez vouloir réutiliser un seul tirable pour différents états, en le teintant simplement différemment. de cette façon, vous pouvez réduire la taille de l'apk et l'allocation des ressources. d'abord définir un FragmentPagerAdapter personnalisé (j'utilise kotlin au lieu de java ici)

class TabPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {

    override fun getCount(): Int = 2

    override fun getItem(position: Int): Fragment = when (position) {
        0 -> FirstFragment.newInstance()
        else -> SecondFragment.newInstance()
    }

    fun getPageIcon(context: Context, position: Int): Drawable = when (position) {
        0 -> ContextCompat.getDrawable(context, R.drawable.ic_whatshot)
        else -> ContextCompat.getDrawable(context, R.drawable.ic_face)
    }
}

au lieu de mettre en oeuvre getPageTitle nous créer un getPageIcon méthode, qui renvoie un drawable pour un onglet spécifique. Ensuite, nous créons une coutume TabLayout:

class IconTabLayout : TabLayout {

    private var viewPager: ViewPager? = null

    constructor(context: Context) : super(context)
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)

    override fun onAttachedToWindow() {
        if (viewPager == null) {
            if (parent is ViewPager) viewPager = parent as ViewPager
        }
        super.onAttachedToWindow()
    }

    override fun setupWithViewPager(viewPager: ViewPager?, autoRefresh: Boolean) {
        this.viewPager = viewPager
        super.setupWithViewPager(viewPager, autoRefresh)
    }

    override fun addTab(@NonNull tab: Tab, position: Int, setSelected: Boolean) {
        if (viewPager != null && viewPager!!.adapter is TabPagerAdapter) {
            val icon: Drawable = DrawableCompat.wrap((viewPager!!.adapter as TabPagerAdapter).getPageIcon(context, position))
            DrawableCompat.setTintList(icon.mutate(), ContextCompat.getColorStateList(context, R.color.tab_color))
            tab.icon = icon
        }
        super.addTab(tab, position, setSelected)
    }
}

ainsi la magie se produit dans le addTab méthode, où l'icône et la liste des états de couleurs sont définies. La liste des états de couleurs a la structure suivante:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states -->
    <item android:color="@color/tab_not_active" android:state_focused="false" android:state_pressed="false" android:state_selected="false" />
    <item android:color="@color/tab_active" android:state_focused="false" android:state_pressed="false" android:state_selected="true" />

    <!-- Focused states -->
    <item android:color="@color/tab_not_active" android:state_focused="true" android:state_pressed="false" android:state_selected="false" />
    <item android:color="@color/tab_active" android:state_focused="true" android:state_pressed="false" android:state_selected="true" />

    <!-- Pressed -->
    <item android:color="@color/tab_not_active" android:state_pressed="true" />
</selector>
1
répondu Artjom Zabelin 2017-03-14 17:53:38