Fragment实现底部菜单栏

本文总结了使用Fragment和不同方法实现底部菜单栏的方法,包括TabHost+Activity、自定义底部选项卡+Fragment、FragmentTabHost+Fragment、RadioGroup+Fragment等。详细介绍了每个方法的实现步骤和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上关于使用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)。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MainActivity extends FragmentActivity {  
  2.     private FragmentTabHost mTabHost;  
  3.     private LayoutInflater layoutInflater;  
  4.   
  5.     // 定义数组来存放Fragment界面  
  6.     private Class<?> fragmentArray[] = { HomeFragment.class,  
  7.             MessageFragment.class, SettingFragment.class };  
  8.   
  9.     // 定义数组来存放按钮图片  
  10.     private int mImageViewArray[] = { R.drawable.tab_home_selector,  
  11.             R.drawable.tab_message_selector, R.drawable.tab_setting_selector };  
  12.   
  13.     // Tab选项卡的文字  
  14.     private int mTextviewArray[] = { R.string.tab_home, R.string.tab_message,  
  15.             R.string.tab_setting };  
  16.   
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_main);  
  21.         initView();  
  22.     }  
  23.   
  24.     // 初始化组件  
  25.     private void initView() {  
  26.         // 实例化布局对象  
  27.         layoutInflater = LayoutInflater.from(this);  
  28.   
  29.         // 实例化TabHost对象,得到TabHost  
  30.         mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);  
  31.         mTabHost.setup(this, getSupportFragmentManager(), R.id.container);  
  32.   
  33.         for (int i = 0; i < fragmentArray.length; i++) {  
  34.             // 为每一个Tab按钮设置图标、文字和内容  
  35.             TabSpec taSpec = mTabHost.newTabSpec(getString(mTextviewArray[i]))  
  36.                     .setIndicator(getTabItemView(i));  
  37.             // 将Tab按钮添加进Tab选项卡中  
  38.             mTabHost.addTab(taSpec, fragmentArray[i], null);  
  39.         }  
  40.     }  
  41.   
  42.     // 给Tab按钮设置图标和文字  
  43.     private View getTabItemView(int index) {  
  44.         View view = layoutInflater.inflate(R.layout.tab_item_view, null);  
  45.         ImageView imageView = (ImageView) view.findViewById(R.id.imageview);  
  46.         imageView.setImageResource(mImageViewArray[index]);  
  47.   
  48.         TextView textView = (TextView) view.findViewById(R.id.textview);  
  49.         textView.setText(getString(mTextviewArray[index]));  
  50.   
  51.         return view;  
  52.     }  
  53.   
  54.     @Override  
  55.     public boolean onCreateOptionsMenu(Menu menu) {  
  56.         // Inflate the menu; this adds items to the action bar if it is present.  
  57.         getMenuInflater().inflate(R.menu.main, menu);  
  58.         return true;  
  59.     }  
  60.   
  61. }  
我建了三个Fragment,代码差不多,下面只贴出HomeFragment。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class HomeFragment extends Fragment {  
  2.   
  3.     // 缓存Fragment的View  
  4.     private View rootView;  
  5.   
  6.     @Override  
  7.     public void onActivityCreated(Bundle savedInstanceState) {  
  8.         super.onActivityCreated(savedInstanceState);  
  9.     }  
  10.   
  11.     @Override  
  12.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  13.             Bundle savedInstanceState) {  
  14.         if (rootView == null) {  
  15.             rootView = inflater.inflate(R.layout.fragment_home, container,  
  16.                     false);  
  17.         } else {  
  18.             // 缓存的rootView需要判断是否已经被加过parent  
  19.             // 如果有parent需要从parent删除  
  20.             ViewGroup parent = (ViewGroup) rootView.getParent();  
  21.             if (parent != null) {  
  22.                 parent.removeView(rootView);  
  23.             }  
  24.         }  
  25.         return rootView;  
  26.     }  
  27.   
  28. }  
然后来看看布局文件activity_main.xml。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <FrameLayout  
  8.         android:id="@+id/container"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="0dip"  
  11.         android:layout_weight="1" />  
  12.   
  13.     <android.support.v4.app.FragmentTabHost  
  14.         android:id="@android:id/tabhost"  
  15.         android:layout_width="fill_parent"  
  16.         android:layout_height="wrap_content" >  
  17.   
  18.         <FrameLayout  
  19.             android:id="@android:id/tabcontent"  
  20.             android:layout_width="0dp"  
  21.             android:layout_height="0dp"  
  22.             android:layout_weight="0" />              
  23.     </android.support.v4.app.FragmentTabHost>  
  24.   
  25. </LinearLayout>  
最后是每个选项卡的布局文件tab_item_view.xml。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="wrap_content"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="@drawable/tab_bg_selector"  
  6.     android:gravity="center"  
  7.     android:orientation="vertical" >  
  8.   
  9.     <ImageView  
  10.         android:id="@+id/imageview"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         android:focusable="false"  
  14.         android:padding="3dp" >  
  15.     </ImageView>  
  16.   
  17.     <TextView  
  18.         android:id="@+id/textview"  
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:textColor="#ffffff"  
  22.         android:textSize="12sp" >  
  23.     </TextView>  
  24.   
  25. </LinearLayout>  

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

核心代码:首先是MainActivity。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MainActivity extends FragmentActivity {  
  2.   
  3.     // 底部选项卡  
  4.     private RadioGroup bottomRg;  
  5.     private FragmentManager fragmentManager;  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.activity_main);  
  11.         setFragmentIndicator();  
  12.     }  
  13.   
  14.     private void setFragmentIndicator() {  
  15.         fragmentManager = getSupportFragmentManager();  
  16.   
  17.         // 绑定Fragment页面和对应的RadioButton  
  18.         final BiMap<Fragment, Integer> biMap = HashBiMap.create();  
  19.         biMap.put(fragmentManager.findFragmentById(R.id.fragment_home),  
  20.                 R.id.rb_home);  
  21.         biMap.put(fragmentManager.findFragmentById(R.id.fragment_message),  
  22.                 R.id.rb_message);  
  23.         biMap.put(fragmentManager.findFragmentById(R.id.fragment_setting),  
  24.                 R.id.rb_setting);  
  25.   
  26.         // 默认显示HomeFragment  
  27.         showFragmentByBtnId(biMap, R.id.rb_home);  
  28.   
  29.         bottomRg = (RadioGroup) findViewById(R.id.bottomRg);  
  30.         bottomRg.setOnCheckedChangeListener(new OnCheckedChangeListener() {  
  31.   
  32.             @Override  
  33.             public void onCheckedChanged(RadioGroup group, int checkedId) {  
  34.                 showFragmentByBtnId(biMap, checkedId);  
  35.             }  
  36.         });  
  37.   
  38.     }  
  39.   
  40.     private void showFragmentByBtnId(final BiMap<Fragment, Integer> biMap,  
  41.             int shownId) {  
  42.         FragmentTransaction fragmentTransaction = fragmentManager  
  43.                 .beginTransaction();  
  44.         // 先隐藏所有的Fragment  
  45.         for (Fragment fragment : biMap.keySet()) {  
  46.             fragmentTransaction.hide(fragment);  
  47.         }  
  48.         // 显示对应的Fragment  
  49.         fragmentTransaction.show(biMap.inverse().get(shownId)).commit();  
  50.         // biMap.inverse().get(R.id.rb_home)通过biMap的Value获得Key  
  51.     }  
  52.   
  53.     @Override  
  54.     public boolean onCreateOptionsMenu(Menu menu) {  
  55.         // Inflate the menu; this adds items to the action bar if it is present.  
  56.         getMenuInflater().inflate(R.menu.main, menu);  
  57.         return true;  
  58.     }  
  59.   
  60. }  
和上面一样建了三个Fragment,代码差不多,只贴出HomeFragment。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class HomeFragment extends Fragment {  
  2.   
  3.     @Override  
  4.     public void onActivityCreated(Bundle savedInstanceState) {  
  5.         super.onActivityCreated(savedInstanceState);  
  6.     }  
  7.   
  8.     @Override  
  9.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  10.             Bundle savedInstanceState) {  
  11.         View view = inflater.inflate(R.layout.fragment_home, container, false);    
  12.         return view;  
  13.     }  
  14.   
  15. }  
然后来看看布局文件activity_main.xml。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <!-- 上边主页面 -->  
  8.   
  9.     <fragment  
  10.         android:id="@+id/fragment_home"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="fill_parent"  
  13.         android:layout_weight="1"  
  14.         class="com.example.fragment3.fragment.HomeFragment" />  
  15.   
  16.     <fragment  
  17.         android:id="@+id/fragment_message"  
  18.         android:layout_width="fill_parent"  
  19.         android:layout_height="fill_parent"  
  20.         android:layout_weight="1"  
  21.         class="com.example.fragment3.fragment.MessageFragment" />  
  22.   
  23.     <fragment  
  24.         android:id="@+id/fragment_setting"  
  25.         android:layout_width="fill_parent"  
  26.         android:layout_height="fill_parent"  
  27.         android:layout_weight="1"  
  28.         class="com.example.fragment3.fragment.SettingFragment" />  
  29.   
  30.     <!-- 底部菜单页面 -->  
  31.   
  32.     <RadioGroup  
  33.         android:id="@+id/bottomRg"  
  34.         android:layout_width="fill_parent"  
  35.         android:layout_height="wrap_content"  
  36.         android:orientation="horizontal" >  
  37.   
  38.         <RadioButton  
  39.             android:id="@+id/rb_home"  
  40.             style="@style/rg_btn_style"  
  41.             android:checked="true"  
  42.             android:drawableTop="@drawable/tab_home_selector"  
  43.             android:text="@string/tab_home" >  
  44.         </RadioButton>  
  45.   
  46.         <RadioButton  
  47.             android:id="@+id/rb_message"  
  48.             style="@style/rg_btn_style"  
  49.             android:drawableTop="@drawable/tab_message_selector"  
  50.             android:text="@string/tab_message" />  
  51.   
  52.         <RadioButton  
  53.             android:id="@+id/rb_setting"  
  54.             style="@style/rg_btn_style"  
  55.             android:drawableTop="@drawable/tab_setting_selector"  
  56.             android:text="@string/tab_setting" />  
  57.     </RadioGroup>  
  58.   
  59. </LinearLayout>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值