• Android UI开发第三十九篇——Tab界面实现汇总及比较


    Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,《Android UI开发第十八篇——ActivityGroup实现tab功能》。这篇文章总结几种Tab的实现。

     

    1)继承自TabActivity,TabActivity已在API Level 13中不建议使用,所有作者不建议在新开发的应用中使用TabActivity,关于Tabactivity的一些分析可以参考Android TabActivity之感叹,英雄暮路,美人辞暮,昔日的英雄再见

     

    2)继承自Activity,布局使用TabHost,这个其实和上面的TabActivity一样,只不过是这里使用findViewById( )获取TabHost对象,而TabActivity使用getTabHost()获得TabHost对象。

     

    3)使用ActivityGroup,《Android UI开发第十八篇——ActivityGroup实现tab功能》中有介绍,当然,下面的button布局会有更多的实现方式,各位也可以自己扩展。ActivityGroup也在API Level 13中不建议使用。

     

    4)使用ActionBar的ActionBar.NAVIGATION_MODE_TABS模式,参考ActionBar的添加导航选项标签介绍。ActionBar是Android 3.0后出现的,为了兼容更多的Android版本,可以参考《Android UI开发第三十五篇——AppCompat实现Action Bar》。

     

    5)继承自FragmentActivity,使用FragmentTabHost。具体实现可以参考FragmentTabHost。当然也可以直接继承自Fragment,使用FragmentTabHost。

     

    6)可以制作更高级的Tab界面,手势滑动的Tab,参考《Creating Swipe Views With Tabs》. 手势滑动切换Tab可以使用ViewPage单独实现。

     

    7)实现Tab界面的方法有很多,每个开发者都可能有不同的方法,尤其对付Tab的下面的Button,开发者可以各种自定义,我见过使用Button实现的也有使用ImageView实现的,也有RadioButton实现的,也有混合布局实现的,这些可以充分发挥开发者想象力。

     

        自TabActivity过期,不建议使用,很多开发者试图把原先的TabActivity修改为FragmentTabHost,使用官方提供的方法不能把Tab的button放到下面。

    1. <android.support.v4.app.FragmentTabHost  
    2.     xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:id="@android:id/tabhost"  
    4.     android:layout_width="match_parent"  
    5.     android:layout_height="match_parent">  
    6.   
    7.     <LinearLayout  
    8.         android:orientation="vertical"  
    9.         android:layout_width="match_parent"  
    10.         android:layout_height="match_parent">  
    11.   
    12.         <TabWidget  
    13.             android:id="@android:id/tabs"  
    14.             android:orientation="horizontal"  
    15.             android:layout_width="match_parent"  
    16.             android:layout_height="wrap_content"  
    17.             android:layout_weight="0"/>  
    18.   
    19.         <FrameLayout  
    20.             android:id="@android:id/tabcontent"  
    21.             android:layout_width="0dp"  
    22.             android:layout_height="0dp"  
    23.             android:layout_weight="0"/>  
    24.   
    25.         <FrameLayout  
    26.             android:id="@+id/realtabcontent"  
    27.             android:layout_width="match_parent"  
    28.             android:layout_height="0dp"  
    29.             android:layout_weight="1"/>  
    30.   
    31.     </LinearLayout>  
    32. </android.support.v4.app.FragmentTabHost>  

    理论上,我们修改一下上面的布局即可使实现tab的button下面。

    1. <android.support.v4.app.FragmentTabHost  
    2.     xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:id="@android:id/tabhost"  
    4.     android:layout_width="match_parent"  
    5.     android:layout_height="match_parent">  
    6.     <LinearLayout  
    7.         android:orientation="vertical"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="match_parent">    
    10.         <FrameLayout  
    11.             android:id="@android:id/tabcontent"  
    12.             android:layout_width="0dp"  
    13.             android:layout_height="0dp"  
    14.             android:layout_weight="0"/>  
    15.         <FrameLayout  
    16.             android:id="@+id/realtabcontent"  
    17.             android:layout_width="match_parent"  
    18.             android:layout_height="0dp"  
    19.             android:layout_weight="1"/>  
    20.   <TabWidget  
    21.             android:id="@android:id/tabs"  
    22.             android:orientation="horizontal"  
    23.             android:layout_width="match_parent"  
    24.             android:layout_height="wrap_content"  
    25.             android:layout_weight="0"/>  
    26.   
    27.     </LinearLayout>  
    28. </android.support.v4.app.FragmentTabHost>  

    我们改变了布局以后,发现我错了,显示没有变化,最终发现是FragmentTabHost的一个bug。参考  

    I change TabWidget down, but it will never be used xml in FragmentTabHost.
    
    I search Bug in support.v4 library:
    Copy FragmentTabHost.java to your own project and Comment line 153 to 175 or change initFragmentTabHost:
    
    
     private void initFragmentTabHost(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(attrs,
                    new int[] { android.R.attr.inflatedId }, 0, 0);
            mContainerId = a.getResourceId(0, 0);
            a.recycle();
    
            super.setOnTabChangedListener(this);
    
            // If owner hasn't made its own view hierarchy, then as a convenience
            // we will construct a standard one here.
    
    
    /***** HERE COMMENT CODE BECAUSE findViewById(android.R.id.tabs) EVERY TIME IS NULL WE HAVE OWN LAYOUT ******//
    
    
    //        if (findViewById(android.R.id.tabs) == null) {
    //            LinearLayout ll = new LinearLayout(context);
    //            ll.setOrientation(LinearLayout.VERTICAL);
    //            addView(ll, new FrameLayout.LayoutParams(
    //                    ViewGroup.LayoutParams.FILL_PARENT,
    //                    ViewGroup.LayoutParams.FILL_PARENT));
    //
    //            TabWidget tw = new TabWidget(context);
    //            tw.setId(android.R.id.tabs);
    //            tw.setOrientation(TabWidget.HORIZONTAL);
    //            ll.addView(tw, new LinearLayout.LayoutParams(
    //                    ViewGroup.LayoutParams.FILL_PARENT,
    //                    ViewGroup.LayoutParams.WRAP_CONTENT, 0));
    //
    //            FrameLayout fl = new FrameLayout(context);
    //            fl.setId(android.R.id.tabcontent);
    //            ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));
    //
    //            mRealTabContent = fl = new FrameLayout(context);
    //            mRealTabContent.setId(mContainerId);
    //            ll.addView(fl, new LinearLayout.LayoutParams(
    //                    LinearLayout.LayoutParams.FILL_PARENT, 0, 1));
    //        }
        }

     

    这样解决了使用FragmentTabHost实现Tab界面button不能在下面的问题。

     

          上面提到的Tab界面的实现方式,归根结底也就分成两大类,前三个为一类,我们统称为Old Tab;后三个为一类,我们统称New Tab。Old Tab可以加载Activity,New Tab加载的是Fragment,这时他们的生命周期是不同的。Old Tab加载的Activtiy再次回来时是从onResume开始的,而New Tab加载的Fragment(Fragment的生命周期)再次回来时是从 onCreateView开始的。

     

    实现Tab界面不止上面介绍的,因为众多开发者的创造力是无穷的,希望这篇能起到抛砖引玉的功效。

     

    /**
    * @author 张兴业
    *  iOS入门群:83702688
    *  android开发进阶群:241395671
    *  我的新浪微博:@张兴业TBOW
    */



    参考:

    http://developer.android.com/reference/android/support/v4/app/FragmentTabHost.html

    http://developer.android.com/training/implementing-navigation/lateral.html

  • 相关阅读:
    数据结构与算法分析-Code Blocks中出现的找不到头文件的问题
    数据结构与算法分析-用C语言实现栈(数组方式)
    数据结构与算法分析-用C语言实现栈(链表方式)
    数据结构与算法分析-用C语言实现单链表
    C语言经典算法100例-结束语
    C++ Primer 7.33 练习编写成员函数
    C语言经典算法100例-073-链表逆序插入节点
    C语言经典算法100例-072-创建一个链表
    LintCode-编辑距离
    LintCode-乘积最大子序列
  • 原文地址:https://www.cnblogs.com/xyzlmn/p/3418247.html
Copyright © 2020-2023  润新知