【问题标题】:How to create app bar with icons using TabLayout Android Design?如何使用 TabLayout Android Design 创建带有图标的应用栏?
【发布时间】:2015-08-17 07:39:55
【问题描述】:

我正在尝试使用 android 设计库中的新 TabLayout 来创建带有图标的应用栏。

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);
}

结果:

请帮我创建类似的应用栏:

对不起,我的英语不好。谢谢提前!

【问题讨论】:

    标签: android-tabhost android-tabs android-design-library


    【解决方案1】:

    来自文档:

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

    设置用于此选项卡的自定义视图。这会覆盖设置的值 通过 setText(CharSequence) 和 setIcon(Drawable)。

    您必须自己设置标题值

    从你的例子:

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

    更新

    API 已更改为允许您设置自定义 id,因此您不必手动设置文本/drawable。它将使用适配器的值。

    如果提供的视图包含一个 ID 为 text1 的 TextView,那么 将使用赋予 setText(CharSequence) 的值进行更新。 同样,如果此布局包含带有 ID 图标的 ImageView,那么它 将使用赋予 setIcon(Drawable) 的值进行更新。

    【讨论】:

    • 感谢您对@Chris Dinon 的支持。这是我的解决方案:github.com/natuan0rg/Android-Design-Support-Library-Sample/tree/…
    • 非常感谢它的工作原理,但是每次我需要添加它时我都必须为 custom_tab 充气,我不能使用同一个,你知道为什么吗?
    • 如何显示文本?我只能看到图标:(
    • @YousefZakher 如果您的视图不太复杂,您可以在运行时实例化它,例如:TextView tabText = new TextView(MainActivity.this);
    • @Chris Dinon:如果 tablayout 片段中还有另一个片段,则在打开第二个片段时,会重新创建选项卡项并删除修改。
    【解决方案2】:

    当您使用vector drawables as icons 时,您可能希望将单个可绘制对象重复用于不同的状态,只需对其进行不同的着色即可。 This way you can reduce the apk size and the allocation of resources.先定义一个自定义的FragmentPagerAdapter(我这里用的是kotlin而不是java)

    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)
        }
    }
    

    我们创建了一个getPageIcon 方法,而不是实现getPageTitle,它返回一个特定选项卡的drawable。接下来我们创建一个自定义的 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)
        }
    }
    

    所以魔法发生在addTab 方法中,其中设置了图标和颜色状态列表。颜色状态列表的结构如下:

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

    【讨论】:

      【解决方案3】:

      您可以使用TabItem 的属性android:layout 来设置自定义视图。 在自定义视图 xml 文件中,记得将图标和文本视图的 id 设置为 @android:id/iconandroid:id="@android:id/text1",然后库将负责其余的工作。

      这是一个例子:

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

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        正如documentation 所说,您可以使用TabItem 通过xml 将项目添加到TabLayout。示例用法如下:

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

        【讨论】:

        • 应定义布局高度和宽度。
        • @jani If not AS 给你警告
        • 添加只是为了让新手不会惊慌失措:P
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-10
        • 2016-04-06
        • 2015-08-29
        • 1970-01-01
        相关资源
        最近更新 更多