Fragment实现底部菜单栏

网上关于使用Fragment实现底部菜单栏的方法,总结一下以备后用。

1. TabHost + Activity:经典的搭配组合,从最早的TabHost + TabActivity演变而来。TabActivity灵活性很差,已经被抛弃了。

2. 自定义底部选项卡 + Fragment:灵活性大,实现起来也很简单。参考:

    http://blog.csdn.net/yangyu20121224/article/details/8995025

    http://my.eoe.cn/imesong/archive/21402.html

3. FragmentTabHost + Fragment:FragmentTabHost主要是实现底部的选项卡功能,Fragment负责内容显示和切换。参考:

    http://blog.csdn.net/yangyu20121224/article/details/9016223

    使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态,参考:

    http://blog.csdn.net/renpengben/article/details/12615487

4. RadioGroup + Fragment:RadioGroup主要是实现底部的选项卡功能,Fragment负责内容显示和切换。参考:

    http://blog.csdn.net/loongggdroid/article/details/9469935

    http://www.cnblogs.com/tiantianbyconan/p/3360938.html


看了来动动手,下面是我参考以上的文章做的两个demo,界面效果相同。


1. FragmentTabHost + Fragment,demo下载地址https://github.com/jessicass/fragment2.git

核心代码:首先是MainActivity,它需要继承FragmentActivity(3.0之前的继承FragmentActivity,3.0版本之后的继承Activity)。

public class MainActivity extends FragmentActivity {
	private FragmentTabHost mTabHost;
	private LayoutInflater layoutInflater;

	// 定义数组来存放Fragment界面
	private Class<?> fragmentArray[] = { HomeFragment.class,
			MessageFragment.class, SettingFragment.class };

	// 定义数组来存放按钮图片
	private int mImageViewArray[] = { R.drawable.tab_home_selector,
			R.drawable.tab_message_selector, R.drawable.tab_setting_selector };

	// Tab选项卡的文字
	private int mTextviewArray[] = { R.string.tab_home, R.string.tab_message,
			R.string.tab_setting };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
	}

	// 初始化组件
	private void initView() {
		// 实例化布局对象
		layoutInflater = LayoutInflater.from(this);

		// 实例化TabHost对象,得到TabHost
		mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
		mTabHost.setup(this, getSupportFragmentManager(), R.id.container);

		for (int i = 0; i < fragmentArray.length; i++) {
			// 为每一个Tab按钮设置图标、文字和内容
			TabSpec taSpec = mTabHost.newTabSpec(getString(mTextviewArray[i]))
					.setIndicator(getTabItemView(i));
			// 将Tab按钮添加进Tab选项卡中
			mTabHost.addTab(taSpec, fragmentArray[i], null);
		}
	}

	// 给Tab按钮设置图标和文字
	private View getTabItemView(int index) {
		View view = layoutInflater.inflate(R.layout.tab_item_view, null);
		ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
		imageView.setImageResource(mImageViewArray[index]);

		TextView textView = (TextView) view.findViewById(R.id.textview);
		textView.setText(getString(mTextviewArray[index]));

		return view;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}
我建了三个Fragment,代码差不多,下面只贴出HomeFragment。

public class HomeFragment extends Fragment {

	// 缓存Fragment的View
	private View rootView;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		if (rootView == null) {
			rootView = inflater.inflate(R.layout.fragment_home, container,
					false);
		} else {
			// 缓存的rootView需要判断是否已经被加过parent
			// 如果有parent需要从parent删除
			ViewGroup parent = (ViewGroup) rootView.getParent();
			if (parent != null) {
				parent.removeView(rootView);
			}
		}
		return rootView;
	}

}
然后来看看布局文件activity_main.xml。

<?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/container"
        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" >

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

</LinearLayout>
最后是每个选项卡的布局文件tab_item_view.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/tab_bg_selector"
    android:gravity="center"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:padding="3dp" >
    </ImageView>

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:textSize="12sp" >
    </TextView>

</LinearLayout>

2. RadioGroup + Fragment,demo下载地址https://github.com/jessicass/fragment3.git

核心代码:首先是MainActivity。

public class MainActivity extends FragmentActivity {

	// 底部选项卡
	private RadioGroup bottomRg;
	private FragmentManager fragmentManager;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		setFragmentIndicator();
	}

	private void setFragmentIndicator() {
		fragmentManager = getSupportFragmentManager();

		// 绑定Fragment页面和对应的RadioButton
		final BiMap<Fragment, Integer> biMap = HashBiMap.create();
		biMap.put(fragmentManager.findFragmentById(R.id.fragment_home),
				R.id.rb_home);
		biMap.put(fragmentManager.findFragmentById(R.id.fragment_message),
				R.id.rb_message);
		biMap.put(fragmentManager.findFragmentById(R.id.fragment_setting),
				R.id.rb_setting);

		// 默认显示HomeFragment
		showFragmentByBtnId(biMap, R.id.rb_home);

		bottomRg = (RadioGroup) findViewById(R.id.bottomRg);
		bottomRg.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				showFragmentByBtnId(biMap, checkedId);
			}
		});

	}

	private void showFragmentByBtnId(final BiMap<Fragment, Integer> biMap,
			int shownId) {
		FragmentTransaction fragmentTransaction = fragmentManager
				.beginTransaction();
		// 先隐藏所有的Fragment
		for (Fragment fragment : biMap.keySet()) {
			fragmentTransaction.hide(fragment);
		}
		// 显示对应的Fragment
		fragmentTransaction.show(biMap.inverse().get(shownId)).commit();
		// biMap.inverse().get(R.id.rb_home)通过biMap的Value获得Key
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}
和上面一样建了三个Fragment,代码差不多,只贴出HomeFragment。

public class HomeFragment extends Fragment {

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.fragment_home, container, false);  
        return view;
	}

}
然后来看看布局文件activity_main.xml。

<LinearLayout 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"
    android:orientation="vertical" >

    <!-- 上边主页面 -->

    <fragment
        android:id="@+id/fragment_home"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        class="com.example.fragment3.fragment.HomeFragment" />

    <fragment
        android:id="@+id/fragment_message"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        class="com.example.fragment3.fragment.MessageFragment" />

    <fragment
        android:id="@+id/fragment_setting"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        class="com.example.fragment3.fragment.SettingFragment" />

    <!-- 底部菜单页面 -->

    <RadioGroup
        android:id="@+id/bottomRg"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/rb_home"
            style="@style/rg_btn_style"
            android:checked="true"
            android:drawableTop="@drawable/tab_home_selector"
            android:text="@string/tab_home" >
        </RadioButton>

        <RadioButton
            android:id="@+id/rb_message"
            style="@style/rg_btn_style"
            android:drawableTop="@drawable/tab_message_selector"
            android:text="@string/tab_message" />

        <RadioButton
            android:id="@+id/rb_setting"
            style="@style/rg_btn_style"
            android:drawableTop="@drawable/tab_setting_selector"
            android:text="@string/tab_setting" />
    </RadioGroup>

</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值