Android Tab导航菜单栏--FragmentTabHost+Fragment实现(基础篇)


      FragmentTabHost继承TabHost,增加了对Fragment的支持。

      Fragment是从Android3.0才引入,Fragment有自己单独的生命周期,在Activity运行的时候可以很方便的使用。
这里只是介绍FragmentTabHost的用法。
 

      1.  先看看谷歌官方文档上的两个例子:

import com.example.android.supportv4.R;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;

/**
 * This demonstrates how you can implement switching between the tabs of a
 * TabHost through fragments, using FragmentTabHost.
 */
public class FragmentTabs extends FragmentActivity {
    private FragmentTabHost mTabHost;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragment_tabs);
        mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

        mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
                FragmentStackSupport.CountingFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
                LoaderCursorSupport.CursorLoaderListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
                LoaderCustomSupport.AppListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
                LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
    }
}

import com.example.android.supportv4.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTabsFragmentSupport extends Fragment {
    private FragmentTabHost mTabHost;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mTabHost = new FragmentTabHost(getActivity());
        mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1);

        mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
                FragmentStackSupport.CountingFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
                LoaderCursorSupport.CursorLoaderListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
                LoaderCustomSupport.AppListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
                LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);

        return mTabHost;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mTabHost = null;
    }
}


      第一个例子是在Activity中使用,直接在XML文件中定义,通过setup(Context, FragmentManager, int) 完成TabHost的初始化,再依次添加Tab。

      第二个例子是在Fragment中使用,通过构造函数 mTabHost = new FragmentTabHost(getActivity())和setup(Context, FragmentManager, int) 完成TabHost的初始化,再依次添加Tab。

     注意:

     getFragmentManager拿到的是activity对所包含fragment的Manager;

     getChildFragmentManager()拿到fragment嵌套fragment的Manager;

     引用android-support-v4的话,要使用 getSupportFragmentManager();


     2.  FragmentTabHost常见用法:


     2.1 如果是在XML文件中定义,通过 mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost)拿到FragmentTabHost,
也可以像第二个例子中使用构造函数拿到FragmentTabHost     
     再看一下FragmentTabHost的构造函数:
     FragmentTabHost(Context context)  
     FragmentTabHost(Context context, AttributeSet attrs) 
     直接使用接行了。     
  
   2.2 FragmentTabHost做初始化的操作
     public void setup () 
     public void setup (Context context, FragmentManager manager) 
     public void setup (Context context, FragmentManager manager, int containerId) args)Bundle  
     2.3 添加tabSpec标签和Fragment类
      addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) 
     2.4 设置Tab样式,三个方法
     setIndicator(CharSequence label);第一种为系统样式,使用要文字标识tab
     setIndicator(CharSequence label, Drawable icon);第二种可以使用文字+icon标识tab      
     setIndicator(View view) 第三种为tab自定义View样式,可以这样使用:

   View v = getLayoutInflater().inflate( R.layout.tab_main_first, null);
 //设置自定义Tab视图  
  TabSpec spec1 = mTabHost.newTabSpec(TabTag[i]).setIndicator(v);  
//将Tab按钮添加进Tab选项卡中  
 mTabHost.addTab(spec1,ClassTab[i], b );
    2.5 设置tab之间分割线颜色

    mTabHost.getTabWidget().setDividerDrawable(R.color.white)

    注意:不设置的话,Tab选项之间会有分隔线

     2.6 设置Tab按钮的背景,当然也可以在XML文件中指定   

mTabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.selector_tab_background);  

     2.7  关于XML

     2.7.1  兼容3.0以下使用 android.support.v4.app.FragmentTabHost命名空间;
     2.7.2  使用android:id="@android:id/tabhost"系统命名
     2.7.3  tab选项卡的内容FrameLayout使用  android:id="@android:id/tabcontent"系统命名
     2.7.4  TabWidget使用  android:id="@android:id/tabs"系统命名


     常见布局,最常见的就是这种

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:background="@drawable/maintab_toolbar_bg">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />            
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

     使用tabwidget,很多人说这种用法会报错,其实用法大同小异,上面的布局 setup时使用 R.id.realtabcontent,而这种使用android.R.id.tabcontent,下面的Demo中就使用这种

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
 
        <!-- 这里是tab选项卡的内容 ,宽度要填满,高度自动适应 -->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1" >
        </FrameLayout>

        <!-- tabhost上面一条黑色分割 @drawable/line_shop -->
        <View
            android:id="@+id/view_2"
            android:layout_width="fill_parent"
            android:layout_height="0.1dip"
            android:background="#D1D1D1" >
        </View>

        <!-- 调换framelayout和tabwidget的前后顺序可以分别实现tab的top和在底下的效果 -->
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >
        </TabWidget>
    </LinearLayout>

</android.support.v4.app.FragmentTabHost>

     使用RadioGroup和 RadioButton定义Tab,这种需要给RadioGroup添加setOnCheckedChangeListener事件,不推荐

  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:checked="true"
            android:gravity="center_horizontal"
            android:textColor="@color/font_selector"
            android:textSize="18dp"
            android:text="首页" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center_horizontal"
            android:textSize="18dp"
            android:textColor="@color/font_selector"
            android:text="消息" />

        <RadioButton
            android:id="@+id/radio2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center_horizontal"
            android:textSize="18dp"
            android:textColor="@color/font_selector"
            android:text="我的" />
    </RadioGroup>

</LinearLayout>

3.  FragmentTabHost  DEMO效果图和代码

 


  3.1 定义主Tabmaintabs.xml

  

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
 
        <!-- 这里是tab选项卡的内容 ,宽度要填满,高度自动适应 -->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1" >
        </FrameLayout>

        <!-- tabhost上面一条黑色分割 @drawable/line_shop -->
        <View
            android:id="@+id/view_2"
            android:layout_width="fill_parent"
            android:layout_height="0.1dip"
            android:background="#D1D1D1" >
        </View>

        <!-- 调换framelayout和tabwidget的前后顺序可以分别实现tab的top和在底下的效果 -->
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >
        </TabWidget>
    </LinearLayout>

</android.support.v4.app.FragmentTabHost>

  3.2 Tab按钮 tab_main_home.xml

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_back"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center" >

   
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="4dip"
        android:drawableTop="@drawable/selector_home"
        android:focusable="true"
        android:gravity="center_horizontal"
        android:text="首页"
        android:textColor="@drawable/tab_txt_sel"
        android:textSize="14sp" />

</LinearLayout>

  3.3 selector_home.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Non focused states -->
    <item android:drawable="@drawable/icon_1_n" android:state_focused="false" android:state_pressed="false" android:state_selected="false"/>
    <item android:drawable="@drawable/icon_1_d" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
    <!-- Focused states -->
    <item android:drawable="@drawable/icon_1_d" android:state_focused="true" android:state_pressed="false" android:state_selected="false"/>
    <item android:drawable="@drawable/icon_1_d" android:state_focused="true" android:state_pressed="false" android:state_selected="true"/>
    <!-- Pressed -->
    <item android:drawable="@drawable/icon_1_d" android:state_pressed="true" android:state_selected="true"/>
    <item android:drawable="@drawable/icon_1_d" android:state_pressed="true"/>

</selector>

  3.4 tab_txt_sel.xml

  

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >	
	<!-- Non focused states -->
	<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:color="#1CBB9D" />
	<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:color="#32A5E7" />
	<!-- Focused states -->
	<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:color="#32A5E7" />
	<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:color="#32A5E7" />
	<!-- Pressed -->
	<item android:state_selected="true" android:state_pressed="true" android:color="#32A5E7" />
	<item android:state_pressed="true" android:color="#32A5E7" />
</selector>

  3.5  fragment_home.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <TextView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="Fragment Home" />

</RelativeLayout>


  3.6  MainTab,太简单了,不作说明……

  

public class MainTab extends FragmentActivity {
	private String TAG = MainTab.class.getName();

	public FragmentTabHost mTabHost;
	// 标签
	private String[] TabTag = { "tab1", "tab2", "tab3" };
	// 自定义tab布局显示文本和顶部的图片
	private Integer[] ImgTab = { R.layout.tab_main_home,
			R.layout.tab_main_message, R.layout.tab_main_my };

	// tab 选中的activity
	private Class[] ClassTab = { FragmentHome.class, FragmentMessage.class,
			FragmentMy.class };

	// tab选中背景 drawable 样式图片 背景都是同一个,背景颜色都是 白色。。。
	private Integer[] StyleTab = { R.color.white, R.color.white, R.color.white,
			R.color.white };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.maintabs);
		setupView();
		initValue();
		setLinstener();
		fillData();

	}

	private void setupView() {

		// 实例化framentTabHost
		mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
		mTabHost.setup(this, getSupportFragmentManager(),
				android.R.id.tabcontent);

	}

	private void initValue() {

		// 初始化tab选项卡
		InitTabView();
	}

	private void setLinstener() {
		// imv_back.setOnClickListener(this);

	}

	private void fillData() {
		// TODO Auto-generated method stub

	}

	// 初始化 tab 自定义的选项卡 ///
	private void InitTabView() {

		// 可以传递参数 b;传递公共的userid,version,sid
		Bundle b = new Bundle();
		// 循环加入自定义的tab
		for (int i = 0; i < TabTag.length; i++) {
			// 封装的自定义的tab的样式
			View indicator = getIndicatorView(i);
			mTabHost.addTab(
					mTabHost.newTabSpec(TabTag[i]).setIndicator(indicator),
					ClassTab[i], b);// 传递公共参数

		}
		mTabHost.getTabWidget().setDividerDrawable(R.color.white);
	}

	// 设置tab自定义样式:注意 每一个tab xml子布局的linearlayout 的id必须一样
	private View getIndicatorView(int i) {
		// 找到tabhost的子tab的布局视图
		View v = getLayoutInflater().inflate(ImgTab[i], null);
		LinearLayout tv_lay = (LinearLayout) v.findViewById(R.id.layout_back);
		tv_lay.setBackgroundResource(StyleTab[i]);

		return v;
	}
}

Demo 下载地址:http://download.csdn.net/detail/yalinfendou/8538361

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值