android 底部导航总结

来源:互联网 发布:网络于柚子是什么意思 编辑:程序博客网 时间:2024/06/05 21:57

1BottomNavigationView实现

实现方式:
1.1 BottomNavigationView是放置在design包中的,所以,使用前需要先引入com.android.support:design:25.1.0包

1.2 xml布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <include layout="@layout/include_toolbar" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/tb_toolbar"        android:orientation="vertical">        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:padding="22dp"            tools:text="123524352" />    </LinearLayout>    <android.support.design.widget.BottomNavigationView        android:id="@+id/bnv_menu"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        app:itemIconTint="@color/selector_blue"        app:itemTextColor="@color/selector_blue"        app:menu="@menu/menu_bottom_navigation" />    <View        android:layout_width="match_parent"        android:layout_height="1dp"        android:layout_above="@id/bnv_menu"        android:background="@color/gray" /></RelativeLayout>

1.3 java代码

  • 基本实现
publicclassMainActivityextendsAppCompatActivityimplementsBottomNavigationView.OnNavigationItemSelectedListener{privateTextFragment fragment;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);FragmentManager fragmentManager = getSupportFragmentManager();fragment =newTextFragment();FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fragment_container, fragment);transaction.commit();BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation_view);bottomNavigationView.setOnNavigationItemSelectedListener(this);}@OverridepublicbooleanonNavigationItemSelected(@NonNull MenuItem item){@StringResinttext;switch(item.getItemId()) {caseR.id.recents:text = R.string.recents;break;caseR.id.favourites:text = R.string.favourites;break;caseR.id.nearby:text = R.string.nearby;break;default:returnfalse;}switchFragmentText(text);returntrue;}privatevoidswitchFragmentText(@StringResinttext){fragment.setText(text);}}}
  • 详细java代码
package com.song.wallpager;  import android.support.v4.app.Fragment;  import android.support.v4.app.FragmentActivity;  import android.support.v4.app.FragmentTransaction;  import android.os.Bundle;  import android.support.annotation.NonNull;  import android.support.design.widget.BottomNavigationView;  import android.view.MenuItem;  import android.widget.TextView;  public class MainActivity extends FragmentActivity {      private Fragment1 fragment1;      private Fragment2 fragment2;      private Fragment3 fragment3;      private Fragment[] fragments;      private int lastShowFragment = 0;      private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener              = new BottomNavigationView.OnNavigationItemSelectedListener() {          @Override          public boolean onNavigationItemSelected(@NonNull MenuItem item) {              switch (item.getItemId()) {                  case R.id.navigation_home:                      if (lastShowFragment != 0) {                          switchFrament(lastShowFragment, 0);                          lastShowFragment = 0;                      }                      return true;                  case R.id.navigation_dashboard:                      if (lastShowFragment != 1) {                          switchFrament(lastShowFragment, 1);                          lastShowFragment = 1;                      }                      return true;                  case R.id.navigation_notifications:                      if (lastShowFragment != 2) {                          switchFrament(lastShowFragment, 2);                          lastShowFragment = 2;                      }                      return true;              }              return false;          }      };      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);          navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);          initFragments();      }      /**       * 切换Fragment       *       * @param lastIndex 上个显示Fragment的索引       * @param index     需要显示的Fragment的索引       */      public void switchFrament(int lastIndex, int index) {          FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();          transaction.hide(fragments[lastIndex]);          if (!fragments[index].isAdded()) {              transaction.add(R.id.fragment_container, fragments[index]);          }          transaction.show(fragments[index]).commitAllowingStateLoss();      }      private void initFragments() {          fragment1 = new Fragment1();          fragment2 = new Fragment2();          fragment3 = new Fragment3();          fragments = new Fragment[]{fragment1, fragment2, fragment3};          lastShowFragment = 0;          getSupportFragmentManager()                  .beginTransaction()                  .add(R.id.fragment_container, fragment1)                  .show(fragment1)                  .commit();      }  }  

总结:

这种方式是google比较新的方式,实现的时候在MainActivity中使用frameLayout布局,标签tab是fragment,通过在activity中对fragment中add和hide实现或者replace(为了避免卡顿,add和hide整体上要好)。

2TabLayout+Viewpager+FragmentPagerAdapter实现

java代码

public class TabLayoutBottomActivity extends BaseActivity {    private TabLayout mTabTl;    private ViewPager mContentVp;    private List<String> tabIndicators;    private List<Fragment> tabFragments;    private ContentPagerAdapter contentAdapter;    public static void startActivity(Context context ){        Intent intent = new Intent(context, TabLayoutBottomActivity.class);        context.startActivity(intent);    }    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_tab_layout_bottom);        mTabTl = (TabLayout) findViewById(R.id.tl_tab);        mContentVp = (ViewPager) findViewById(R.id.vp_content);        initContent();        initTab();    }    private void initTab(){        mTabTl.setTabMode(TabLayout.MODE_FIXED);        mTabTl.setSelectedTabIndicatorHeight(0);        ViewCompat.setElevation(mTabTl, 10);        mTabTl.setupWithViewPager(mContentVp);        for (int i = 0; i < tabIndicators.size(); i++) {            TabLayout.Tab itemTab = mTabTl.getTabAt(i);            if (itemTab!=null){                itemTab.setCustomView(R.layout.item_tab_layout_custom);                TextView itemTv = (TextView) itemTab.getCustomView().findViewById(R.id.tv_menu_item);                itemTv.setText(tabIndicators.get(i));            }        }        mTabTl.getTabAt(0).getCustomView().setSelected(true);    }    private void initContent(){        tabIndicators = new ArrayList<>();        for (int i = 0; i < 4; i++) {            tabIndicators.add("Tab " + i);        }        tabFragments = new ArrayList<>();        for (String s : tabIndicators) {            tabFragments.add(TabContentFragment.newInstance(s));        }        contentAdapter = new ContentPagerAdapter(getSupportFragmentManager());        mContentVp.setAdapter(contentAdapter);    }    class ContentPagerAdapter extends FragmentPagerAdapter {        public ContentPagerAdapter(FragmentManager fm) {            super(fm);        }        @Override        public Fragment getItem(int position) {            return tabFragments.get(position);        }        @Override        public int getCount() {            return tabIndicators.size();        }        @Override        public CharSequence getPageTitle(int position) {            return tabIndicators.get(position);        }    }}

xml代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <include  layout="@layout/include_toolbar"/>    <android.support.v4.view.ViewPager        android:id="@+id/vp_content"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1">    </android.support.v4.view.ViewPager>    <android.support.design.widget.TabLayout        android:id="@+id/tl_tab"        android:layout_width="match_parent"        android:layout_height="@dimen/dp_56"        android:background="@color/white">    </android.support.design.widget.TabLayout></LinearLayout>

总结

这种方式实现起来比较简单,而且可以左右滑动,注意这种方式注意viewpager会预加载fragment。

3 通过FragmentManager+Fragment实现显示隐藏实现

  • java代码
/**  * 项目的主Activity,所有的Fragment都嵌入在这里。  *   */  public class MainActivity extends Activity implements OnClickListener {      /**      * 用于展示消息的Fragment      */      private MessageFragment messageFragment;      /**      * 用于展示联系人的Fragment      */      private ContactsFragment contactsFragment;      /**      * 用于展示动态的Fragment      */      private NewsFragment newsFragment;      /**      * 用于展示设置的Fragment      */      private SettingFragment settingFragment;      /**      * 消息界面布局      */      private View messageLayout;      /**      * 联系人界面布局      */      private View contactsLayout;      /**      * 动态界面布局      */      private View newsLayout;      /**      * 设置界面布局      */      private View settingLayout;      /**      * 在Tab布局上显示消息图标的控件      */      private ImageView messageImage;      /**      * 在Tab布局上显示联系人图标的控件      */      private ImageView contactsImage;      /**      * 在Tab布局上显示动态图标的控件      */      private ImageView newsImage;      /**      * 在Tab布局上显示设置图标的控件      */      private ImageView settingImage;      /**      * 在Tab布局上显示消息标题的控件      */      private TextView messageText;      /**      * 在Tab布局上显示联系人标题的控件      */      private TextView contactsText;      /**      * 在Tab布局上显示动态标题的控件      */      private TextView newsText;      /**      * 在Tab布局上显示设置标题的控件      */      private TextView settingText;      /**      * 用于对Fragment进行管理      */      private FragmentManager fragmentManager;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          requestWindowFeature(Window.FEATURE_NO_TITLE);          setContentView(R.layout.activity_main);          // 初始化布局元素          initViews();          fragmentManager = getFragmentManager();          // 第一次启动时选中第0个tab          setTabSelection(0);      }      /**      * 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。      */      private void initViews() {          messageLayout = findViewById(R.id.message_layout);          contactsLayout = findViewById(R.id.contacts_layout);          newsLayout = findViewById(R.id.news_layout);          settingLayout = findViewById(R.id.setting_layout);          messageImage = (ImageView) findViewById(R.id.message_image);          contactsImage = (ImageView) findViewById(R.id.contacts_image);          newsImage = (ImageView) findViewById(R.id.news_image);          settingImage = (ImageView) findViewById(R.id.setting_image);          messageText = (TextView) findViewById(R.id.message_text);          contactsText = (TextView) findViewById(R.id.contacts_text);          newsText = (TextView) findViewById(R.id.news_text);          settingText = (TextView) findViewById(R.id.setting_text);          messageLayout.setOnClickListener(this);          contactsLayout.setOnClickListener(this);          newsLayout.setOnClickListener(this);          settingLayout.setOnClickListener(this);      }      @Override      public void onClick(View v) {          switch (v.getId()) {          case R.id.message_layout:              // 当点击了消息tab时,选中第1个tab              setTabSelection(0);              break;          case R.id.contacts_layout:              // 当点击了联系人tab时,选中第2个tab              setTabSelection(1);              break;          case R.id.news_layout:              // 当点击了动态tab时,选中第3个tab              setTabSelection(2);              break;          case R.id.setting_layout:              // 当点击了设置tab时,选中第4个tab              setTabSelection(3);              break;          default:              break;          }      }      /**      * 根据传入的index参数来设置选中的tab页。      *       * @param index      *            每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。      */      private void setTabSelection(int index) {          // 每次选中之前先清楚掉上次的选中状态          clearSelection();          // 开启一个Fragment事务          FragmentTransaction transaction = fragmentManager.beginTransaction();          // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况          hideFragments(transaction);          switch (index) {          case 0:              // 当点击了消息tab时,改变控件的图片和文字颜色              messageImage.setImageResource(R.drawable.message_selected);              messageText.setTextColor(Color.WHITE);              if (messageFragment == null) {                  // 如果MessageFragment为空,则创建一个并添加到界面上                  messageFragment = new MessageFragment();                  transaction.add(R.id.content, messageFragment);              } else {                  // 如果MessageFragment不为空,则直接将它显示出来                  transaction.show(messageFragment);              }              break;          case 1:              // 当点击了联系人tab时,改变控件的图片和文字颜色              contactsImage.setImageResource(R.drawable.contacts_selected);              contactsText.setTextColor(Color.WHITE);              if (contactsFragment == null) {                  // 如果ContactsFragment为空,则创建一个并添加到界面上                  contactsFragment = new ContactsFragment();                  transaction.add(R.id.content, contactsFragment);              } else {                  // 如果ContactsFragment不为空,则直接将它显示出来                  transaction.show(contactsFragment);              }              break;          case 2:              // 当点击了动态tab时,改变控件的图片和文字颜色              newsImage.setImageResource(R.drawable.news_selected);              newsText.setTextColor(Color.WHITE);              if (newsFragment == null) {                  // 如果NewsFragment为空,则创建一个并添加到界面上                  newsFragment = new NewsFragment();                  transaction.add(R.id.content, newsFragment);              } else {                  // 如果NewsFragment不为空,则直接将它显示出来                  transaction.show(newsFragment);              }              break;          case 3:          default:              // 当点击了设置tab时,改变控件的图片和文字颜色              settingImage.setImageResource(R.drawable.setting_selected);              settingText.setTextColor(Color.WHITE);              if (settingFragment == null) {                  // 如果SettingFragment为空,则创建一个并添加到界面上                  settingFragment = new SettingFragment();                  transaction.add(R.id.content, settingFragment);              } else {                  // 如果SettingFragment不为空,则直接将它显示出来                  transaction.show(settingFragment);              }              break;          }          transaction.commit();      }      /**      * 清除掉所有的选中状态。      */      private void clearSelection() {          messageImage.setImageResource(R.drawable.message_unselected);          messageText.setTextColor(Color.parseColor("#82858b"));          contactsImage.setImageResource(R.drawable.contacts_unselected);          contactsText.setTextColor(Color.parseColor("#82858b"));          newsImage.setImageResource(R.drawable.news_unselected);          newsText.setTextColor(Color.parseColor("#82858b"));          settingImage.setImageResource(R.drawable.setting_unselected);          settingText.setTextColor(Color.parseColor("#82858b"));      }      /**      * 将所有的Fragment都置为隐藏状态。      *       * @param transaction      *            用于对Fragment执行操作的事务      */      private void hideFragments(FragmentTransaction transaction) {          if (messageFragment != null) {              transaction.hide(messageFragment);          }          if (contactsFragment != null) {              transaction.hide(contactsFragment);          }          if (newsFragment != null) {              transaction.hide(newsFragment);          }          if (settingFragment != null) {              transaction.hide(settingFragment);          }      }  }  
  • activity_tab 代码
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <include  layout="@layout/include_toolbar"/>    <android.support.v4.view.ViewPager        android:id="@+id/vp_content"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1">    </android.support.v4.view.ViewPager>    <android.support.design.widget.TabLayout        android:id="@+id/tl_tab"        android:layout_width="match_parent"        android:layout_height="@dimen/dp_56"        android:background="@color/white">    </android.support.design.widget.TabLayout></LinearLayout>
  • fragment中的布局
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:orientation="vertical" >        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_horizontal"            android:src="@drawable/contacts_selected" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_horizontal"            android:padding="10dp"            android:text="这是联系人界面"            android:textSize="20sp" />    </LinearLayout></RelativeLayout>

总结
这种方式是非常清晰的方式,没有预加载,类似QQ 微信中的效果,美中不足的是所有fragment中的代码放在activity中,有点臃肿。

4 ViewPager+FragmentPagerAdapter

参考链接
https://www.kancloud.cn/digest/protectyoureyes/122210

  • java 代码
public class MainActivity extends FragmentActivity        implements View.OnClickListener {    private ViewPager viewPager;    private Button one;    private Button two;    private Button three;    private Button four;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化ViewPager        InitViewPager();        //初始化布局        InitView();    }    private void InitViewPager() {        //获取ViewPager        //创建一个FragmentPagerAdapter对象,该对象负责为ViewPager提供多个Fragment        viewPager = (ViewPager) findViewById(R.id.pager);        FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(                getSupportFragmentManager()) {            //获取第position位置的Fragment            @Override            public Fragment getItem(int position) {                Fragment fragment = null;                switch (position) {                    case 0:                        fragment = new OneFragment();                        break;                    case 1:                        fragment = new TwoFragment();                        break;                    case 2:                        fragment = new ThreeFragment();                        break;                    case 3:                        fragment = new FourFragment();                        break;                }                return fragment;            }            //该方法的返回值i表明该Adapter总共包括多少个Fragment            @Override            public int getCount() {                return 4;            }        };        //为ViewPager组件设置FragmentPagerAdapter        viewPager.setAdapter(pagerAdapter);        //为viewpager组件绑定时间监听器        viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {            //当ViewPager显示的Fragment发生改变时激发该方法            @Override            public void onPageSelected(int position) {                switch (position) {                    //如果是点击的第一个button,那么就让第一个button的字体变为蓝色                    //其他的button的字体的颜色变为黑色                    case 0:                        one.setTextColor(Color.BLUE);                        two.setTextColor(Color.BLACK);                        three.setTextColor(Color.BLACK);                        four.setTextColor(Color.BLACK);                        break;                    case 1:                        one.setTextColor(Color.BLACK);                        two.setTextColor(Color.BLUE);                        three.setTextColor(Color.BLACK);                        four.setTextColor(Color.BLACK);                        break;                    case 2:                        one.setTextColor(Color.BLACK);                        two.setTextColor(Color.BLACK);                        three.setTextColor(Color.BLUE);                        four.setTextColor(Color.BLACK);                        break;                    case 3:                        one.setTextColor(Color.BLACK);                        two.setTextColor(Color.BLACK);                        three.setTextColor(Color.BLACK);                        four.setTextColor(Color.BLUE);                        break;                }                super.onPageSelected(position);            }        });    }    private void InitView() {        one = (Button) findViewById(R.id.bt_one);        two = (Button) findViewById(R.id.bt_two);        three = (Button) findViewById(R.id.bt_three);        four = (Button) findViewById(R.id.bt_four);        //设置点击监听        one.setOnClickListener(this);        two.setOnClickListener(this);        three.setOnClickListener(this);        four.setOnClickListener(this);        //将button中字体的颜色先按照点击第一个button的效果初始化        one.setTextColor(Color.BLUE);        two.setTextColor(Color.BLACK);        three.setTextColor(Color.BLACK);        four.setTextColor(Color.BLACK);    }    //点击主界面上面的button后,将viewpager中的fragment跳转到对应的item    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.bt_one:                viewPager.setCurrentItem(0);                break;            case R.id.bt_two:                viewPager.setCurrentItem(1);                break;            case R.id.bt_three:                viewPager.setCurrentItem(2);                break;            case R.id.bt_four:                viewPager.setCurrentItem(3);                break;        }    }}OneFragment:(由于4个fragment的布局都一样,在此就只放上第一个了)public class OneFragment extends Fragment {    @Override    public void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @Override    @Nullable    public View onCreateView(LayoutInflater inflater,                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View rootView = inflater.inflate(R.layout.one, container, false);//关联布局文件        //设置在OneFragment中的点击效果        Button bt_frg_one = (Button) rootView.findViewById(R.id.bt_frg_one);        bt_frg_one.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(getActivity().getApplicationContext(), "这是第一页按钮的点击效果", Toast.LENGTH_SHORT).show();            }        });        return rootView;    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);    }}
  • xml 布局代码

activity_main

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v4.view.ViewPager        android:id="@+id/pager"        android:layout_width="match_parent"        android:layout_height="match_parent"></android.support.v4.view.ViewPager>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true">        <Button            android:id="@+id/bt_one"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="one"            android:textSize="20sp" />        <Button            android:id="@+id/bt_two"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="two"            android:textSize="20sp" />        <Button            android:id="@+id/bt_three"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="three"            android:textSize="20sp" />        <Button            android:id="@+id/bt_four"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="four"            android:textSize="20sp" />    </LinearLayout></RelativeLayout>

one

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/bt_frg_one"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="one"        android:textSize="30dp" /></LinearLayout>

总结
这种方式跟2的方式唯一不同的是第二个用到tabLayout这种方式用的是LinerLayout布局,其他的是一样的。

5 TabPageIndicator+ViewPager+ FragmentPagerAdapter实现

总结这种方式跟2和4类似

6 FragmentTabHost+Fragment实现

  • java 代码
public class MainActivity extends FragmentActivity {          private FragmentTabHost mTabHost;          private LayoutInflater mInflater;          private ArrayList<Tab> mTabs= new ArrayList<Tab>(5);    @Override         protected void onCreate(Bundle savedInstanceState) {                        super.onCreate(savedInstanceState);                  setContentView(R.layout.activity_main);                 initTab();    }          private void initTab() {                  //实例化5个Tab类的对象                  Tab Tab_home = new Tab(R.drawable.selector_home,R.string.home,HomeFragment.class);                  Tab Tab_hot = new Tab(R.drawable.selector_hot,R.string.hot, HotFragment.class);                  Tab Tab_discover = new Tab(R.drawable.selector_discover,R.string.discover, DiscoverFragment.class);                  Tab Tab_cart = new Tab(R.drawable.selector_cart,R.string.cart, CartFragment.class);                    Tab Tab_user = new Tab(R.drawable.selector_user,R.string.user, UserFragment.class);                 //将这5个对象加到一个List中                  mTabs.add(Tab_home);                  mTabs.add(Tab_hot);                  mTabs.add(Tab_discover);                  mTabs.add(Tab_cart);                  mTabs.add(Tab_user);                  mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);                  mTabHost.setup(this, getSupportFragmentManager(), R.id.realcontent);                  mInflater = LayoutInflater.from(this);                  //通过循环实例化一个个TabSpec                  //并调用其中setIndicator方法                  //然后将TabSpec加到TabHost中                  for (Tab tab  :mTabs) {                          TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText()));                                tabSpec.setIndicator(buildView(tab));                          mTabHost.addTab(tabSpec,tab.getFragment(), null);                    }                   //通过这行代码可以去除掉底部菜单5个图表之间的分割线           mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);    }              //设置Indicator中的View              private View buildView(Tab tab) {                  View view = mInflater.inflate(R.layout.tab_indicator,null);                  ImageView Tab_img = (ImageView) view.findViewById(R.id.tab_img);                  TextView Tab_txt = (TextView) view.findViewById(R.id.tab_txt);                  Tab_img.setBackgroundResource(tab.getImage());                  Tab_txt.setText(tab.getText());                  return view;            }      }
public class Tab {         private int Image;          private int Text;          private Class Fragment;          public Tab(int image, int text, Class fragment) {                      Image = image;                     Text = text;                     Fragment = fragment;    }          public int getImage() {        return Image;    }          public void setImage(int image) {        Image = image;    }                public int getText() {        return Text;    }          public void setText(int text) {        Text = text;    }          public Class getFragment() {        return Fragment;    }          public void setFragment(Class fragment) {        Fragment = fragment;    }}

  • 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"                            tools:context=".MainActivity">       <FrameLayout                      android:id="@+id/realcontent"                      android:layout_width="match_parent"                      android:layout_height="0dp"                      android:layout_weight="1">        </FrameLayout>        <android.support.v4.app.FragmentTabHost                      android:id="@android:id/tabhost"                        android:layout_width="match_parent"                      android:layout_height="wrap_content"                      android:background="#ffffff" >               <FrameLayout                        android:id="@android:id/tabcontent"                           android:layout_width="0dp"                           android:layout_height="0dp"                           android:layout_weight="0" >         </FrameLayout>         </android.support.v4.app.FragmentTabHost></LinearLayout>

7 ViewPager+Fragment+FragmentTabHost实现底部菜单

具体实现:

  • 每个fragment布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"     android:gravity="center">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="fragment1"         android:textSize="20dp"/></LinearLayout>
  • Activity布局
<?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" >     <android.support.v4.view.ViewPager        android:id="@+id/pager"        android:layout_width="match_parent"        android:layout_height="0dp"        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="@android:color/black" >    </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="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical" >    <ImageView        android:id="@+id/tab_imageview"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/tab_textview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="@android:color/white" /></LinearLayout>

activity_main 中的java代码

//注意是继承 FragmentActivitypublic class MainActivity extends FragmentActivity{    // FragmentTabHost    private FragmentTabHost mTabHost;    // layoutInflater    private LayoutInflater layoutInflater;    // imageViewArray数组,用于显示底部菜单    private int imageViewArray[] = { R.drawable.mywork, R.drawable.mypatient,            R.drawable.infusion, R.drawable.personal };    // textViewArray数组    private String textViewArray[] = { "工作", "回家", "互动", "我的" };    // Fragment数组    private List<Fragment> list = new ArrayList<Fragment>();    // ViewPager    private ViewPager vp;    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.main_tab_layout);        initView();    }    /**     * 控件初始化     */    private void initView()    {        vp = (ViewPager) findViewById(R.id.pager);        layoutInflater = LayoutInflater.from(this);        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);        mTabHost.setup(this, getSupportFragmentManager(), R.id.pager);        Fragment1 fragment1 = new Fragment1();        Fragment2 fragment2 = new Fragment2();        Fragment3 fragment3 = new Fragment3();        Fragment4 fragment4 = new Fragment4();        list.add(fragment1);        list.add(fragment2);        list.add(fragment3);        list.add(fragment4);        int count = textViewArray.length;        // 添加菜单内容        for (int i = 0; i < count; i++)        {            // 一个菜单就是一个TabSpec,然后添加到FragmentTabHost中            TabSpec tabSpec = mTabHost.newTabSpec(textViewArray[i])                    .setIndicator(getTabItemView(i));            mTabHost.addTab(tabSpec, list.get(i).getClass(), null);            // 默认让第一个选中            mTabHost.getTabWidget().getChildAt(0)                    .setBackgroundResource(R.drawable.selector_tab_background);        }        // ViewPager添加Adapter,这里用FragmentPagerAdapter        vp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager())        {            @Override            public int getCount()            {                return list.size();            }            @Override            public android.support.v4.app.Fragment getItem(int arg0)            {                return list.get(arg0);            }        });    }    private View getTabItemView(int i)    {        View view = layoutInflater.inflate(R.layout.tab_content, null);        ImageView mImageView = (ImageView) view                .findViewById(R.id.tab_imageview);        TextView mTextView = (TextView) view.findViewById(R.id.tab_textview);        mImageView.setBackgroundResource(imageViewArray[i]);        mTextView.setText(textViewArray[i]);        return view;    }}
  • 当viewpager滑动的时候关联viewpager与底部菜单
vp.setOnPageChangeListener(new OnPageChangeListener()        {            @Override            public void onPageScrollStateChanged(int arg0)            {            }            @Override            public void onPageScrolled(int arg0, float arg1, int arg2)            {            }            @Override            public void onPageSelected(int arg0)            {                // 选中菜单                mTabHost.setCurrentTab(arg0);                // 设置对应菜单高亮                mTabHost.getTabWidget()                        .getChildAt(arg0)                        .setBackgroundResource(                                R.drawable.selector_tab_background);            }        });
  • FragmentTabHost实现setOnTabChangedListener,目的是当点击了下面的菜单时,上面的ViewPager应该滑动到对应的Fragment
mTabHost.setOnTabChangedListener(new OnTabChangeListener()        {            @Override            public void onTabChanged(String tabId)            {                // 获取点击的菜单的位置                int position = mTabHost.getCurrentTab();                // ViewPager滑动到对应的位置                vp.setCurrentItem(position);            }        });

总结
基本原理都是viewPager+FragmentPagerAdapter.如果要求内容不需要滑动,如微信、支付宝那种,只有底部点击切换Fragment的功能,那么只需要将Activity布局中的ViewPager换成一个FrameLayout占位,然后在程序替换Fragment即可~~

对以上几种实现方式的建议:
在项目中用的话
简便实用性: 3和6
如果需要左右滑动则 2 4 5
第一个是比较新的特性 我自己用的少,根据个人情况来选择。

参考链接
https://juejin.im/entry/583414ce61ff4b006b8cf338 (第一条)
http://blog.csdn.net/qq_35366908/article/details/72457909(第一条)
http://www.jianshu.com/p/f7351d4ee903 (第五条)
http://www.jianshu.com/p/491386d6435c (FragmentTabHost)

原创粉丝点击