使用带有工具栏的滑动选项卡

Posted

技术标签:

【中文标题】使用带有工具栏的滑动选项卡【英文标题】:Using Sliding Tabs with Toolbar 【发布时间】:2015-07-04 06:50:21 【问题描述】:

我已经开始从使用ActionBarActivity 更改为AppCompatActivity,但我也开始使用Toolbar 而不是标准的ActionBar

但是,在我的一个具有滑动标签类型布局的活动中,以下行似乎已被弃用:

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

虽然我已经在 Stack Overflow 上查看了有关此问题的其他一些答案,但是否有任何内置方法可以更改它以支持使用 Toolbar。如果是这样,你能解释一下我将如何改变它吗?如何更改 onTabSelected 等已弃用的方法?

另外,我注意到 Google Play 音乐应用的标签下方看起来像是一个扩展的工具栏/部分(请参阅 this image for what I am talking about)。我怎样才能拥有这种类型的布局?

提前致谢。

【问题讨论】:

滑动标签使用developer.android.com/samples/SlidingTabsBasic/project.html 我查看了代码,但不确定它是如何工作的。 ***.com/questions/26540078/… 如我所说,我看过代码,但是有很多Java文件和布局文件。它究竟是如何工作的? @GabrieleMariotti 我设法添加了来自 SlidingTabsBasic 示例的代码,但这并没有给我想要的布局。我已经添加了它,选项卡与工具栏是分开的,并且是灰色的,带有粗边框。我想要一个更像this(在左侧)的布局。如您所见,在该图像中,选项卡连接到工具栏并看起来是其中的一部分。我也喜欢选项卡下方的橙色扩展部分,但我不介意没有它。 【参考方案1】:

所以经过几天的大量研究,并浏览了 GitHub,我终于设法解决了我的问题。

使用 AppCompatActivity 将 ActionBar 选项卡更新为 Toolbar 选项卡的步骤:


更新:2015 年 5 月 29 日星期五之后:

谢天谢地,自从在 2015 年 Google I/O 上宣布 Android 设计支持库 以来,使用 TabLayoutToolbar 变得更加简单。 我们不再需要下载自定义视图类,这是 Google 很久以前真正应该做的事情。

来自Android Developers' Blogspot post on the Android Design Support Library:

标签

通过tabs 在您的应用程序中的不同视图之间切换并不是材料设计的新概念,它们与top level navigation pattern 或用于在您的应用程序中组织不同的内容分组(例如,不同类型的音乐)。

设计库的TabLayout 实现了两个固定选项卡,其中视图的宽度在所有选项卡之间平均分配,以及可滚动选项卡,其中选项卡的大小不统一并且可以水平滚动。可以通过编程方式添加标签:

TabLayout tabLayout = ...;tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));

但是,如果您使用ViewPager 在选项卡之间进行水平分页,则可以直接从PagerAdapter 的getPageTitle() 创建选项卡,然后使用setupWithViewPager() 将两者连接在一起。这可确保选项卡选择事件更新 ViewPager 并且页面更改更新选定的选项卡。


Google I/O 2015 之前:

首先,我从 GitHub 上的 Google I/O 会议应用程序下载了 SlidingTabLayout.javaSlidingTabStrip.java 文件。这些将是在选项卡布局中使用的视图,因此我创建了一个包含其他 Java 活动的文件夹,称为“视图”并将它们放在那里。

接下来,我编辑了我的活动布局.xml,看起来有点像这样:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context="com.mycompany.myapp.MyActivity" >

    <!-- This is the Toolbar with the tabs underneath -->
    <LinearLayout android:id="@+id/detail_headerBar"
        style="@style/HeaderBar"
        android:layout_
        android:layout_
        android:orientation="vertical">

        <include android:id="@+id/detail_toolbar" layout="@layout/toolbar" />

        <com.mycompany.myapp.view.SlidingTabLayout
            android:id="@+id/sliding_tabs"
            android:background="?attr/colorPrimary"
            android:layout_
            android:layout_ />
    </LinearLayout>

    <!-- This is the ViewPager (which I had used before) and 
         it would be responsible for the swiping to change layouts -->
    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_
        android:layout_
        android:layout_below="@id/detail_headerBar"
        android:layout_above="@+id/detail_adView" />

    <!-- I also had an AdView in my layout,
         but this is not necessary for creating tab layouts -->
    <com.google.android.gms.ads.AdView
        android:id="@+id/detail_adView"
        android:layout_
        android:layout_
        android:layout_alignParentBottom="true"
        ads:adSize="SMART_BANNER"
        ads:adUnitId="@string/banner_ad_unit_id" >
    </com.google.android.gms.ads.AdView>

</RelativeLayout>

引用Toolbar (&lt;include android:id="@+id/detail_toolbar" layout="@layout/toolbar" /&gt;) 的行引用了以下布局(对于那些还不确定如何使用Toolbar 的人):

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_
    android:layout_
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

在上面的两个 .xml 布局文件中,?attr/colorPrimary 指的是我的应用程序的原色(我在样式中定义了它)。

另外,在第一个布局中,我提到的样式为@style/HeaderBar 指的是以下内容:

<style name="HeaderBar">
    <item name="android:background">?colorPrimary</item>
    <item name="android:elevation">4dp</item>
    <!-- You may have to override this in a v21 version of this file -->
</style>

在我开始在 Java 中设置布局之前,我必须确保将 SlidingTabLayout.javaSlidingTabStrip.java 中的包名称更改为与它们所在的位置相对应。就我而言,我在这两个文件中都使用了:package com.mycompany.myapp.view;

现在,在我的Activity(扩展AppCompatActivity)中,我首先在onCreate 方法中添加了以下内容:

Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);

这将负责显示Toolbar

然后我设置ViewPagerSlidingTabLayout 部分:

mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));

mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setSelectedIndicatorColors(getResources().getColor(R.color.tab_line));   
mSlidingTabLayout.setDistributeEvenly(true);
mSlidingTabLayout.setViewPager(mViewPager);

颜色“tab_line”是我在color.xml 中声明的颜色,它是制表符行指示器的颜色。另请注意,上面的变量是我之前在此活动中定义的全局变量:

SlidingTabLayout mSlidingTabLayout;
ViewPager mViewPager;

最后要做的是设置ViewPagerAdapter,我称之为eariler。这将负责根据选择的选项卡更改页面。我使用了以下内容:

public class ViewPagerAdapter extends FragmentPagerAdapter 

    public ViewPagerAdapter(FragmentManager fm) 
        super(fm);
    

    @Override
    public int getCount() 
        // Returns the number of tabs
        return 3;
    

    @Override
    public Fragment getItem(int position) 
        // Returns a new instance of the fragment
        switch (position) 
            case 0:
                return new FragmentOne();
            case 1:
                return new FragmentTwo();
            case 2:
                return new FragmentThree();
        
        return null;
    

    @Override
    public CharSequence getPageTitle(int position) 
        Locale l = Locale.getDefault();
        switch (position) 
            case 0:
                return getString(R.string.title_section1).toUpperCase(l);
            case 1:
                return getString(R.string.title_section2).toUpperCase(l);
            case 2:
                return getString(R.string.title_section3).toUpperCase(l);
        
        return null;
    

我希望对于那些在从ActionBarActivity 切换到AppCompatActivity 并开始使用Toolbar 而不是ActionBar 时遇到同样问题的人来说,这是一个足够彻底的答案。如果有什么不清楚的地方,欢迎在下方评论。

【讨论】:

感谢您,它在大多数情况下都很好用。我遇到的唯一问题是我在屏幕顶部看不到任何实际的标签。我可以左右滚动到不同的视图页面,只是没有标签来指定我正在查看的内容。有任何想法吗? (我非常仔细地遵循了您提供的代码示例) @TheRedAgent 嗯。您是否在活动布局中包含了SlidingTabLayout @FarbodSalamat-Zadeh:感谢您的回答。有很大帮助。但现在我想在运行时更改选项卡的文本。该怎么做? @ManojFegde 如果您将ViewPager 与适配器一起使用,请在getPageTitle 方法中指定名称,如我的答案底部所述。如果您没有使用ViewPager,您应该使用tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));,根据您想要的名称更改“Tab 1”。我在上面的回答中给出了这两种解决方案的详细信息。 我试过 tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));但出现错误:对于 SlidingTabLayout 类型,方法 newTab() 未定义

以上是关于使用带有工具栏的滑动选项卡的主要内容,如果未能解决你的问题,请参考以下文章

在现有项目的 Android 开发人员工具中使用支持库 v7:21 和工具栏添加滑动选项卡

当通过手势识别器滑动切换到仅点击选项卡时,在 tabbarcontroller 中切换选项卡会给出不同的结果

使用带有新工具栏的选项卡 (AppCompat v7-21)

将 Google API 客户端对象从活动传递到滑动选项卡片段

mui中选项卡切换中怎么禁止页面左右滑动

我的带有标签的滑动视图的 Android 计算器应用程序崩溃了