web-dev-qa-db-fra.com

Comment créer une barre d'application avec des icônes avec TabLayout Android Design?

J'essaie d'utiliser le nouveau TabLayout dans la bibliothèque de conceptions Android pour créer une barre d'applications 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

S'il vous plaît, aidez-moi à créer une barre d'application similaire:

app bar with icons

Désolé, mon anglais n'est pas bon. Merci, c'est avancé!

19
natuan241

De la documentation:

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

Définissez une vue personnalisée à utiliser pour cet onglet. Cela annule le jeu de valeurs par setText (CharSequence) et setIcon (Drawable).

vous devrez définir vous-même les valeurs du titre

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" />

Mettre à jour

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

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

28
Chris Dinon

Vous pouvez utiliser l'attribut Android:layout de TabItem pour définir l'affichage personnalisé . Dans le fichier xml d'affichage personnalisé, n'oubliez pas de définir id de l'icône et de la vue texte sur @Android:id/icon et Android:id="@Android:id/text1", la bibliothèque se chargera ensuite 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>

. main.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>

J'espère que cette aide.

3
nlt

En tant que documentation said Vous pouvez ajouter des éléments à TabLayout via le fichier XML en utilisant TabItem. Un exemple d'utilisation ressemble à ceci:

 <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
Amir

Lorsque vous utilisez des vecteurs dessinables sous forme d'icônes , vous pouvez réutiliser un dessinable unique pour différents états, en le colorant simplement différemment. De cette façon, vous pouvez réduire la taille de l'APK et l'allocation des ressources. Définissons d'abord 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 d'implémenter getPageTitle, nous créons une méthode getPageIcon qui renvoie un dessin pour un onglet spécifique. Ensuite, nous créons un TabLayout personnalisé:

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 la méthode addTab, où l'icône et la liste d'état de couleur sont définies. La liste d'état de couleur 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
Artjom Zabelin