`

打造自己的标签栏

阅读更多

作为Android新手,我当时只知道一种方法:

使用Android自带的TabHost容器。

传统的TabHost的使用效果大概是这样的(左图):

大众点评网Android客户端截图Twidroyd

这是大众点评网早期的Android客户端,标签栏使用了系统自带的控件。然而这个效果和我们看到的很多底部标签栏相差甚远(右图,twitter客户端Twidroyd截图)。

他们到底是怎么实现的呢?为此,我在网上查了不少资料,大致有以下种方案:

  1. Button Bar实现;
  2. 修改TabWidget。

1. Button Bar

基本思路:用一个Layout来呈现整个标签栏,在上面添加若干按钮作为标签,整个Layout作为一个部件include到各个界面的布局里去。当用户点击按钮时,切换到相应的界面(多个Activity间的切换)。

 

在Android 3.0以前的版本里,这种方案多用于制作动作栏。3.0后出现了ActionBar控件,为开发者省了不少事。希望手机版的Android也早点加入。

image

 

image

优点:实现了你想要的效果,外观很容易定制。

缺点:标签栏实际不是一个,有多个,他们分别属于不同的界面(从属关系)。这导致了在界面切换的时候,标签栏会随着他的界面(或者说Activity)“动”,而非常驻在底部。

改进:有一种改进方式是,用一个Activity来控制整个主界面,标签栏include在这个主界面的布局里,点击标签时显示相应的View(实际上是在一个Activity上多个View的切换)。这样就保证了标签栏只有一个,而且不会随着标签切换而动来动去。当然,缺点也是显而易见的,当标签过多的时候,这个Activity会变得相当复杂。呵呵~万一有个变动,你懂的。

2. 修改TabWidget

基本思路:在于既然Android是开源的,我们就能大改特该,让它听话。我们把TabWidget移到底部,然后修改它的外观。

 

优点:达到了目的,继承了TabWidget的基本功能,可复用,使用简单;

缺点:需要研究不少Android资料,查references 查到眼花,费九牛二虎之力去掉分割线,底部白线之类的东西,完成外观定制。

这个方法貌似有不少人用,这里有几篇中文资料(其实都差不多啦,中文圈你抄我我抄你的。。。唉):

3. 奇技淫巧

如你所见,前面说过的方法都能达到目的。但是,Button Bar的方式看上去太dirty了,修改TabWidget又太麻烦了。有什么方式能避免这些不必要的麻烦,把两者优点结合起来呢?

 

我想到了Android控件的一个属性: android:visibility=”gone”。这简直就是救命稻草!它可以让你的控件不显示,而且还不占地方。这有什么用呢?这意味着,我们可以照样用TabHost,可以照样放TabWidget,只是,只是我们不把TabWidget显示出来。它现在是隐形的标签栏,the real tabs。我们所要做的是:安置一个“傀儡”标签栏,让它来和用户接触。这是不是有点像Design Pattern里的“Proxy”呢?

这个方案算是投机取巧之作,很可惜,我不是第一个想到的,你可以看这里。历史总是惊人的相似啊!

标签容器布局,大致代码如下:
main.xml: 

<?xml version="1.0" encoding="utf-8"?> <!-- TabHost -->  
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent" android:layout_height="fill_parent"  
    android:id="@android:id/tabhost">  
    <LinearLayout android:orientation="vertical"  
        android:layout_width="fill_parent" android:layout_height="fill_parent">             
        <!-- 隐藏的TabWidget,visibility="gone" -->  
        <TabWidget android:id="@android:id/tabs"  
            android:layout_width="fill_parent" android:layout_height="wrap_content"  
            android:visibility="gone" />            
             <!-- 标签内容 -->  
        <FrameLayout android:id="@android:id/tabcontent"  
            android:layout_width="fill_parent" android:layout_height="0.0dip"  
            android:layout_weight="1.0" />             
        <!-- 用户可见的“tabs”实际上是一组按钮-->         
        <!-- 注意:checkedButton=“@+id/tab1“,这使得默认选中第一个按钮 -->  
        <RadioGroup android:id="@+id/tab_group"  
            android:layout_width="fill_parent" android:layout_height="50dp"  
            android:gravity="center_vertical" android:layout_gravity="bottom"  
            android:orientation="horizontal" android:background="@drawable/tab_bar_bg"  
            android:checkedButton="@+id/tab1">                 
           <!-- 第一个标签,注意button属性设置成null,以此去掉自带的radio button-->             
           <!-- 注意:id="@id/tab1",为什么不是+id呢?这个和加载先后有关系,Google一下吧 -->  
            <RadioButton android:id="@id/tab1" android:tag="tab1"  
                android:layout_width="fill_parent" android:layout_height="fill_parent"  
                android:layout_weight="1.0" android:layout_marginTop="1.0dip"  
                android:text="Tab 1" android:button="@null" android:gravity="center"  
                android:background="@drawable/tab_bg_selector" />  
            <RadioButton android:id="@+id/tab2" android:layout_width="fill_parent"  
                android:layout_height="fill_parent" android:layout_weight="1.0"  
                android:layout_marginTop="1.0dip" android:text="Tab 2"  
                android:button="@null" android:gravity="center" android:background="@drawable/tab_bg_selector" />  
            <RadioButton android:id="@+id/tab3" android:layout_width="fill_parent"  
                android:layout_height="fill_parent" android:layout_weight="1.0"  
                android:layout_marginTop="1.0dip" android:text="Tab 3"  
                android:button="@null" android:gravity="center" android:background="@drawable/tab_bg_selector" />  
        </RadioGroup>  
    </LinearLayout>   

 

RadioGroup就是底部的标签栏,背景进行了自定义。我在这边demo里用了9.png格式的图,嗯,你会经常用它的。
此外,标签被选中和未被选中的关键在于android:background=”@drawable/tab_bg_selector”这句。
selector:

xml version="1.0" encoding="utf-8"?>  
<selector xmlns:android="http://schemas.android.com/apk/res/android">  
    <item android:state_focused="true" android:drawable="@drawable/tab_bg_focused" />  
    <item android:state_pressed="true" android:drawable="@drawable/tab_bg_selected" />  
    <item android:state_checked="true" android:drawable="@drawable/tab_bg_selected" />  
</selector>   

 

下面列出加载它的Activity代码:
TabDemoActivity:

print?public class TabDemoActivity extends TabActivity {  
    private TabHost tabhost;  
    private RadioGroup tabGroup;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        tabhost = getTabHost();  
        tabGroup = (RadioGroup) findViewById(R.id.tab_group);  
        // 这里新建3个的Intent用于Activity的切换   
        Intent tab1 = new Intent(this, TabOneActivity.class);  
        Intent tab2 = new Intent(this, TabTwoActivity.class);  
        Intent tab3 = new Intent(this, TabThreeActivity.class);  
        // 向tabhost里添加tab   
        tabhost.addTab(tabhost.newTabSpec("TAB1").setIndicator("Tab 1")  
                .setContent(tab1));  
        tabhost.addTab(tabhost.newTabSpec("TAB2").setIndicator("Tab 2")  
                .setContent(tab2));  
        tabhost.addTab(tabhost.newTabSpec("TAB3").setIndicator("Tab 3")  
                .setContent(tab3));  
        // 给各个按钮设置监听   
        tabGroup.setOnCheckedChangeListener(new OnTabChangeListener());  
        }  
    private class OnTabChangeListener implements OnCheckedChangeListener {  
        @Override  
        public void onCheckedChanged(RadioGroup group, int id) {  
            // TODO Auto-generated method stub   
            //尤其需要注意这里,setCurrentTabByTag方法是纽带   
            switch (id) {  
            case R.id.tab1:  
                tabhost.setCurrentTabByTag("TAB1");  
                break;  
                case R.id.tab2:  
                    tabhost.setCurrentTabByTag("TAB2");  
                    break;  
                case R.id.tab3:  
                    tabhost.setCurrentTabByTag("TAB3");  
                    break;  
                        }  
            }  
        }     
      

 

最后,为演示起见我们写3个装入容器的Activity。TabOneActivity,TabTwoActivity,TabThreeActivity.
比如TabOneActivity:

public class TabOneActivity extends Activity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub   
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.content);  
        TextView text=(TextView)findViewById(R.id.text);  
        text.setText("This is tab 1.");  
    }  
}  

 


他们的layout很简单,在LinearLayout里就放了个TextView。。。这里就不贴了。
最终效果图:

Android自定义标签栏

Android自定义标签栏

 

当然这只是一个Demo,要做得更漂亮你需要在细节处好好作文章,譬如,美化文字,添加图标等等。




分享到:
评论

相关推荐

    Android 使用TabLayout打造滑动标签栏

    本文将深入探讨如何利用TabLayout来打造一个功能丰富的滑动标签栏。 首先,我们从基础开始。TabLayout是AppCompat库的一部分,因此在使用前需要在项目的build.gradle文件中添加对应的依赖。通常,我们会引入`...

    Android应用开发笔记-打造自己的标签栏.pdf

    Android应用开发笔记-打造自己的标签栏.pdf

    Flutter入门与实战:标签切换栏

    `TabBar`是`\widgets`库的一部分,它与`TabController`一起工作,提供了一个可触摸的标签栏,用户可以点击切换不同的内容视图。 ```dart TabBar( tabs: [ Tab(text: '标签1'), Tab(text: '标签2'), ], ...

    微信小程序自定义标签栏(TabBar) 组件.zip

    通过配置文件设定基本属性,使用WXSS调整样式,以及编写自定义组件实现复杂功能,开发者可以打造出与品牌形象相符、操作流畅的标签栏。理解并熟练运用这些技巧,对于微信小程序的开发至关重要。

    纯CSS打造的菜单栏

    最后,提供的文件"w3cfuns凤凰网导航效果"可能包含一个具体的菜单栏实现案例,你可以参考其中的代码,学习如何结合上述知识点来创建自己的CSS菜单栏。 通过不断实践和学习,你将能掌握创建高效、美观且具有良好兼容...

    android 打造炫酷导航栏(仿UC头条)

    在Android开发中,创建一个吸引用户的界面是至关重要的,尤其是导航栏,它是用户与应用交互的主要入口之一。...通过不断实践和优化,我们可以创建出符合自己应用风格的个性化导航栏,提升用户的使用体验。

    网易新闻排序标签

    在iOS开发中,标签栏(Tab Bar)是一种常见的用户界面元素,它允许用户在不同的功能模块之间快速切换。网易新闻的排序标签就是这样一个组件,它为用户提供了一个直观、易用的方式来浏览和组织新闻内容。本篇文章将...

    安卓标题栏

    "安卓标题栏"这个主题,聚焦于如何在Android应用中创建和定制自己的标题栏。下面我们将详细探讨相关的知识点。 1. **Android原生TitleBar** 在Android早期版本中,系统提供了默认的Title Bar,开发者可以通过设置...

    隐藏页面左侧标签导航栏.zip

    描述中提到的“纯CSS3手工打造”,意味着这个导航栏的实现完全依赖于CSS3的样式规则,没有使用JavaScript或者其他脚本语言。CSS3提供了许多新的选择器和属性,如动画(animations)、过渡(transitions)和伪类...

    工具栏小软件

    这为用户提供了更大的自由度,让他们能够完全按照自己的想法打造独一无二的工具栏界面。 总结起来,"工具栏小软件"是一款注重用户体验和个性化定制的桌面工具,它通过自定义工具栏、皮肤和插件功能,为用户提供了一...

    仿苹果dock栏

    【标题】"仿苹果Dock栏"指的是在非苹果操作系统中,使用类似苹果Mac OS系统Dock栏功能的应用程序。Dock栏是苹果操作系统中的一个重要...通过自定义设置,用户可以根据自己的习惯和喜好打造一个既实用又美观的桌面环境。

    用VB打造自己的Excel表格编辑器,用VB仿Excel,源代码

    总的来说,用VB打造自己的Excel表格编辑器是一项挑战性的工作,它涵盖了控件使用、数据处理、公式计算、图表绘制、文件操作等多个方面的VB编程知识。通过这个项目,开发者不仅可以深入理解VB的编程特性,还能提高...

    利用Visual C++打造自己的IE浏览器

    1. **浏览器外壳(Shell)**:这是用户与浏览器交互的界面,包括地址栏、标签页、前进/后退按钮等。在Visual C++中,可以使用MFC的窗口类和控件来实现这些功能。 2. **浏览器引擎**:负责处理用户的导航请求,管理...

    手把手教您优化360安全浏览器.docx

    2. 标签栏统一宽度:通过调整“限制”中的最小宽度和最大宽度为同一数值(如185),可以使标签栏保持一致,节省空间。 3. 自定义工具栏按钮:删除不常用或冗余的按钮,如右箭头、本页浏览记录、停止加载和刷新按钮...

    这是工具栏的图标 是个大集合 自己做C#窗体用了的

    "这是工具栏的图标 是个大集合 自己做C#窗体用了的" 这个标题表明,这个压缩包文件包含了一组丰富的图标资源,专门用于C#窗体应用的工具栏设计。工具栏图标是用户与软件交互时最直观的元素之一,它们通常代表各种...

    vs2008如何创建自定义工具栏

    总的来说,掌握VS2008自定义工具栏的方法,不仅可以优化个人的工作流程,还能提高团队协作的效率,因为每个人可以根据自己的习惯配置工作环境。而压缩包中的代码资源则提供了进一步探索和扩展工具栏功能的可能性,...

    Office工具栏图标

    至于标签中的"C#",这表明这些图标特别适用于C#开发环境,尽管它们也可以应用于其他支持图标资源的编程语言。同时,由于这些图标是为模仿MS Office设计的,因此开发者可以创建类似Word、Excel或PowerPoint的生产力...

    漂亮的导航栏漂亮的导航栏

    在IT行业中,网页设计是至关重要的一环,而导航栏作为用户与网站交互的首要元素,其美观性和功能性显得尤为关键。...在实践中,设计师和技术人员需要紧密合作,不断优化和完善,以打造出既美观又实用的导航栏。

    定制QWidget标题栏的示例,并含有qss配置QTabWidget样式的示例

    这段QSS使得标签栏背景变为淡灰色,标签有内嵌边框,选中或悬停时变为白色,并用深灰色文字表示。可以根据实际需求调整这些值以实现所需的效果。 至于如何显示一个不在状态栏出现的窗口,这是指创建无边框窗口或者...

    侧滑导航栏

    在Android应用开发中,侧滑导航栏是一种常见的用户...通过学习和实践"SlidingMenuDemo"这样的示例项目,开发者可以深入理解侧滑导航栏的工作原理,并将其应用到自己的项目中,打造更加现代和用户友好的Android应用。

Global site tag (gtag.js) - Google Analytics