网上关于使用Fragment实现底部菜单栏的方法,总结一下以备后用。
1. TabHost + Activity:经典的搭配组合,从最早的TabHost + TabActivity演变而来。TabActivity灵活性很差,已经被抛弃了。
2. 自定义底部选项卡 + Fragment:灵活性大,实现起来也很简单。参考:
http://blog.youkuaiyun.com/yangyu20121224/article/details/8995025
http://my.eoe.cn/imesong/archive/21402.html
3. FragmentTabHost + Fragment:FragmentTabHost主要是实现底部的选项卡功能,Fragment负责内容显示和切换。参考:
http://blog.youkuaiyun.com/yangyu20121224/article/details/9016223
使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态,参考:
http://blog.youkuaiyun.com/renpengben/article/details/12615487
4. RadioGroup + Fragment:RadioGroup主要是实现底部的选项卡功能,Fragment负责内容显示和切换。参考:
http://blog.youkuaiyun.com/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;
- }
- }
- 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;
- }
- }
- <?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>
- <?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;
- }
- }
- 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;
- }
- }
- <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>