<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    android Tabhost部件

    Posted on 2009-11-18 15:44 瘋狂 閱讀(28856) 評論(12)  編輯  收藏 所屬分類: android讀代碼

           本文結合源代碼和實例來說明TabHost的用法。

          使用TabHost 可以在一個屏幕間進行不同版面的切換,例如android自帶的撥號應用,截圖:
     

          查看tabhost的源代碼,主要實例變量有:
       

    private TabWidget mTabWidget;
        
    private FrameLayout mTabContent;
        
    private List<TabSpec> mTabSpecs 

       也就是說我們的tabhost必須有這三個東西,所以我們的.xml文件就會有規定:繼續查看源代碼:
       

    if (mTabWidget == null{
                
    throw new RuntimeException(
                        
    "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
            }




     mTabContent 
    = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
            
    if (mTabContent == null{
                
    throw new RuntimeException(
                        
    "Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
            }

         也就是說我們的.xml文件需要TabWidgetFrameLayout標簽。

    接下來構建我們自己的tab實例:

          有兩種方式可以實現:
          一種是繼承TabActivity 類,可以使用android的自己內部定義好的.xml資源文件作容器文件。也就是在我們的代碼中使用getTabHost(); , 而相應的后臺源碼是這樣的:

    this.setContentView(com.android.internal.R.layout.tab_content);

           在系統的資源文件中可以看見這個layout


          有了容器,然后我們就需要我們為每個tab分配內容,當然要可以是如何類型的標簽:
          例如我們構建一下.xml文件
      首先tab1.xml 是一個LinearLayout布局

    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id
    ="@+id/LinearLayout01" android:layout_width="wrap_content"
        android:layout_height
    ="wrap_content">
        
    <TextView android:text="tab1 with linear layout"
            android:id
    ="@+id/TextView01" android:layout_width="wrap_content"
            android:layout_height
    ="wrap_content">
        
    </TextView>
    </LinearLayout>


     
    然后是tab2.xml是一個FrameLayout布局

    <?xml version="1.0" encoding="utf-8"?>
        
    <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        
        android:id
    ="@+id/FrameLayout02"
            android:layout_width
    ="wrap_content"
            android:layout_height
    ="wrap_content">
            
    <LinearLayout android:id="@+id/LinearLayout02"
                android:layout_width
    ="wrap_content"
                android:layout_height
    ="wrap_content">
                
    <TextView android:text="tab2"
                    android:id
    ="@+id/TextView01" android:layout_width="wrap_content"
                    android:layout_height
    ="wrap_content">
                
    </TextView>
            
    </LinearLayout>
            
        
    </FrameLayout>

    接著要注冊這兩個FrameLayout為tabhost的Content,也就是接下來的代碼:

    LayoutInflater inflater_tab1 = LayoutInflater.from(this);   
            inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView());  
            inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView()); 

     
    然后需要構建前面說的tabhost的第三個實例變量對應得內容,源代碼中是這樣的:

    private List<TabSpec> mTabSpecs = new ArrayList<TabSpec>(2);

     初始化是兩個tab的空間然后會自動擴展:
    好 我們構建我們的tabspec:
     

    mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 11").setContent(R.id.LinearLayout01));  
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test1").setIndicator("TAB 11").setContent(R.id.FrameLayout02));    


    也就是把我們的2個layout作為他的content,當然FrameLayout中可以有其他的布局,來放我的組件。
    我們不需要在代碼里面設置setContentView();因為getTabHost(); 這個方法調用后就已經設置了,源代碼:
      

    if (mTabHost == null{
                
    this.setContentView(com.android.internal.R.layout.tab_content);
            }

    也就是把系統的tab_content當做view設置。
    運行后如下:
     
    完整代碼:

     TabHost mTabHost = getTabHost();
            LayoutInflater inflater_tab1 
    = LayoutInflater.from(this);   
            inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView());  
            inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());   
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test1").setIndicator("TAB 11").setContent(R.id.LinearLayout01));  
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test1").setIndicator("TAB 11").setContent(R.id.FrameLayout02)); 




     還有一種就是定義我們自己的tabhost:不用繼承TabActivity

     首先建立我們自己的.xml文件,當然要包含Tabhost,TabWidget,FrameLayout,著3個標簽:

    <?xml version="1.0" encoding="utf-8"?>  
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"  
        android:id
    ="@+id/tabhost"  
        android:layout_width
    ="fill_parent"  
        android:layout_height
    ="fill_parent">  
        
    <LinearLayout  
            android:orientation
    ="vertical"  
            android:layout_width
    ="fill_parent"  
            android:layout_height
    ="fill_parent">  
            
    <TabWidget  
                android:id
    ="@android:id/tabs"  
                android:layout_width
    ="fill_parent"  
                android:layout_height
    ="wrap_content" />  
            
    <FrameLayout  
                android:id
    ="@android:id/tabcontent"  
                android:layout_width
    ="fill_parent"  
                android:layout_height
    ="fill_parent">  
                 
            
    </FrameLayout>  
        
    </LinearLayout>  
    </TabHost>  

         注意的是:除了tabhost的id可以自定義外,其他的必須使用系統的id,為什么后面說,
           當然我們可以在FrameLayout里面添加view來作為tab的內容只需要在create tabspce時候添加就可以了,我們為了把每個tab的內容分開我們依然使用前面用到的兩個tab xml文件
     java代碼:
          獲取TabHost 通過findviewbyid,

    setContentView(R.layout.main);   
            TabHost mTabHost 
    = (TabHost)findViewById(R.id.tabhost);

        接下來很重要的一步是要使用TabHost.setup();
         作用是來初始化我們的TabHost容器:
        源代碼是這樣說的:
       

    <p>Call setup() before adding tabs if loading TabHost using findViewById(). <i><b>However</i></b>: You do
          
    * not need to call setup() after getTabHost() in {@link android.app.TabActivity TabActivity}.

      也就是說通過findviewbyid,方法獲得tabhost必須setup 而通過getTabHost則不用。
      setup干什么呢:源代碼
     

    mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
            
    if (mTabWidget == null{
                
    throw new RuntimeException(
                        
    "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
            }


    mTabContent 
    = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
            
    if (mTabContent == null{
                
    throw new RuntimeException(
                        
    "Your TabHost must have a FrameLayout whose id attribute is 'android.R.id.tabcontent'");
            }

       他主要是初始化了tabhost的兩個實例變量,這里也回答了為什么我們的id必須使用系統定義的id的原因
      接下來工作就和前面相同了:

    LayoutInflater inflater_tab1 = LayoutInflater.from(this);   
            inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView());  
            inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test1").setIndicator("TAB a").setContent(R.id.LinearLayout01));   
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test2").setIndicator("TAB b").setContent(R.id.FrameLayout02)); 


     完整代碼:

    setContentView(R.layout.main);   
            TabHost mTabHost 
    = (TabHost)findViewById(R.id.tabhost); 
            mTabHost.setup();
            LayoutInflater inflater_tab1 
    = LayoutInflater.from(this);   
            inflater_tab1.inflate(R.layout.tab1, mTabHost.getTabContentView());  
            inflater_tab1.inflate(R.layout.tab2, mTabHost.getTabContentView());
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test1").setIndicator("TAB a").setContent(R.id.LinearLayout01));   
            mTabHost.addTab(mTabHost.newTabSpec(
    "tab_test2").setIndicator("TAB b").setContent(R.id.FrameLayout02));  


      運行結果同上。 如有問題歡迎提出。

        轉載請說明出處。。。


    加上源代碼,有用了可以下載下:/Files/freeman1984/atab.rar


    評論

    # re: android Tabhost部件[未登錄]  回復  更多評論   

    2009-11-18 16:01 by 飛天
    說的透徹,先收藏!!

    # re: android Tabhost部件  回復  更多評論   

    2010-10-29 21:25 by Uling
    用第一種方法,建立后,如果tab1中和tab2中都有按鈕,將導致tab1中的按鈕動作可以實現,而tab2中的則會報錯。還請賜教。

    # re: android Tabhost部件  回復  更多評論   

    2011-06-03 17:48 by gyflyx
    讓人印象深刻,謝謝。。。。。。

    # re: android Tabhost部件  回復  更多評論   

    2011-08-27 09:50 by Thomas_ohuan
    受益了~~謝謝~~

    # re: android Tabhost部件  回復  更多評論   

    2011-10-12 17:29 by roider
    非常喜歡分析問題的角度,從源碼開始,講的很透徹,最近也想用到TabHost,但一直不會用,還需慢慢消化,希望我能在自己的博文中引用博主的連接供其他人學習。

    # re: android Tabhost部件  回復  更多評論   

    2011-10-12 17:37 by @joe
    @roider
    呵呵,表明出處就行了。可惜我荒廢了,09年得時候學了幾個月之后就再也沒學了,現在搞j2ee。不知道什么時候有動力能重新學起android。哎。

    # re: android Tabhost部件  回復  更多評論   

    2011-12-09 14:21 by 王雨良
    講得一個字 透徹啊~~~
    不是大段的貼代碼,這樣的講義能收費的哦,呵呵。

    # re: android Tabhost部件  回復  更多評論   

    2012-11-22 12:24 by 彼岸
    我擦你大爺,找的我好辛苦,文章要注明出處啊,我擦那些呆B,復制都不好好復制,格式全亂了,百度想找到原作者,結果尼瑪全是垃圾網站,擦。
    寫得不錯,希望作者直接保存成圖片,讓那些呆B復制。

    # re: android Tabhost部件  回復  更多評論   

    2012-11-22 12:26 by 彼岸
    @@joe
    2B,這些東西是學不完的,基本是現學現用。

    # re: android Tabhost部件  回復  更多評論   

    2013-06-09 14:36 by
    太好了,非常需要第二種實現方式.ty

    # re: android Tabhost部件  回復  更多評論   

    2014-01-27 16:56 by 愛的差距
    第二個方法老是出現:“Your content must have a TabHost whose id attribute is 'android.R.id.tabhost'”的錯誤

    # re: android Tabhost部件[未登錄]  回復  更多評論   

    2014-03-15 12:02 by 小白
    第二種方法的tab1.xml以及tab2.xml文件你的按鈕等等!的點擊方法執行不了!請幫助解決一下!謝謝!
    主站蜘蛛池模板: 一级做性色a爰片久久毛片免费| 亚洲www77777| 久久精品无码免费不卡| 亚洲А∨精品天堂在线| 日日狠狠久久偷偷色综合免费 | 看成年女人免费午夜视频| 成年女人午夜毛片免费看 | 黄色免费网址在线观看| 免费成人在线观看| 国产裸体美女永久免费无遮挡| 亚洲精品tv久久久久久久久久| 国产大片免费天天看| 国产精品亚洲片在线观看不卡| 免费国产成人α片| 亚洲国产高清视频在线观看| 性做久久久久久免费观看| 亚洲av最新在线观看网址| 亚洲国产人成精品| 久久这里只精品热免费99| 亚洲人成在线中文字幕| 日产乱码一卡二卡三免费| 国产免费牲交视频免费播放| 久久亚洲私人国产精品vA| 国语成本人片免费av无码| 美女被免费视频网站a| 亚洲精品~无码抽插| 免费福利网站在线观看| 美女视频黄a视频全免费网站一区| 精品国产亚洲一区二区在线观看| 两性色午夜免费视频| 亚洲成人在线免费观看| 免费a级毛片在线观看| 久久久久久久岛国免费播放 | 亚洲午夜无码AV毛片久久| 免费精品无码AV片在线观看| 一本色道久久88—综合亚洲精品| 亚洲日韩国产一区二区三区| 91精品啪在线观看国产线免费| 亚洲大码熟女在线观看| 亚洲精品国产精品乱码不99 | 亚洲性日韩精品国产一区二区|