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);}@Overrideprotected 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);}@Overridepublic Fragment getItem(int position) {return tabFragments.get(position);}@Overridepublic int getCount() {return tabIndicators.size();}@Overridepublic 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.ViewPagerandroid: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.TabLayoutandroid: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.ViewPagerandroid: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.TabLayoutandroid: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 FragmentActivityimplements View.OnClickListener {private ViewPager viewPager;private Button one;private Button two;private Button three;private Button four;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化ViewPagerInitViewPager();//初始化布局InitView();}private void InitViewPager() {//获取ViewPager//创建一个FragmentPagerAdapter对象,该对象负责为ViewPager提供多个FragmentviewPager = (ViewPager) findViewById(R.id.pager);FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {//获取第position位置的Fragment@Overridepublic 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@Overridepublic int getCount() {return 4;}};//为ViewPager组件设置FragmentPagerAdapterviewPager.setAdapter(pagerAdapter);//为viewpager组件绑定时间监听器viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {//当ViewPager显示的Fragment发生改变时激发该方法@Overridepublic 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@Overridepublic 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 {@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Override@Nullablepublic 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() {@Overridepublic void onClick(View v) {Toast.makeText(getActivity().getApplicationContext(), "这是第一页按钮的点击效果", Toast.LENGTH_SHORT).show();}});return rootView;}@Overridepublic 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代码

//注意是继承 FragmentActivity
public class MainActivity extends FragmentActivity
{// FragmentTabHostprivate FragmentTabHost mTabHost;// layoutInflaterprivate 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>();// ViewPagerprivate ViewPager vp;@Overrideprotected 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,这里用FragmentPagerAdaptervp.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()){@Overridepublic int getCount(){return list.size();}@Overridepublic 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(){@Overridepublic void onPageScrollStateChanged(int arg0){}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2){}@Overridepublic 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(){@Overridepublic 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)

android 底部导航总结相关推荐

  1. android 固定底部导航,如何设置android底部导航栏位置固定在android

    请帮我设置底部导航栏位置固定在底部, ,因为我在输入editText字段时遇到问题,底部导航栏向上移动并覆盖其他领域如何设置android底部导航栏位置固定在android 代码: xmlns:and ...

  2. VS 2015 开发Android底部导航条----[实例代码,多图]

    1.废话背景介绍  在Build 2016开发者大会上,微软宣布,Xamarin将被整合进所有版本的Visual Studio之中. 这也就是说,Xamarin将免费提供给所有购买了Visual St ...

  3. android fragment 底部菜单栏,一句话搞定Android底部导航栏,一键绑定Fragment、ViewPager...

    现在大多数App都会用到底部导航栏,比如常见的聊天工具QQ.微信.购物App等等,有了底部导航栏,用户可以随时切换界面,查看不同的内容.它的实现方式也很多,以前大多使用TabHost来实现,但是现在我 ...

  4. 转载:Android底部导航栏,三种风格和实现

    原文出处 标题:Android底部导航栏,三种风格和实现 作者:阿飞__ 原文链接:Android底部导航栏,三种风格和实现_阿飞__的博客-CSDN博客_android导航栏 一.效果图展示 如果动 ...

  5. Android底部导航栏的三种风格实现

    一.效果图展示 如果动图没有动的话,也可以看下面这个静态图 以下挨个分析每个的实现,这里只做简单的效果展示,大家可以基于目前代码做二次开发. 二.BottomNavigationView 这是 Goo ...

  6. Android底部导航栏切换页面填坑

    ** Android底部导航栏切换页面填坑 ** 这个效果的实现关键点就是给选项赋予两种状态,focused和normal,在主程序中用监听判断是否被选中,就给被选中的选项设focused为true, ...

  7. Android底部导航框架(解决fragment界面重现,getActivity空指针)

    android底部导航框架可以说是目前最常用的框架,看似非常简单的框架如果搭建不好后期会出现各种意想不到问题: 比如我前面两篇写的每次点击底部图标fragment之间会来回替换,这样肯定不实用:这个d ...

  8. Android底部导航栏最常用的两种写法

    先来看看底部导航栏的效果 Android 底部导航栏有很多种写法,例如: RadioGroup , Tablayout, TabHost  , LinearLayout + ImageView + T ...

  9. Android底部导航栏+消息提醒

    Android底部导航栏+消息提醒 最近想在网上找一些Android底部导航栏切换并能提供消息提醒的案例,虽然有很多案例但都不是我想要的.我就开始自己瞎研究了,废话不多说了,直接上代码. 1.先创建一 ...

  10. Android 底部导航栏添加消息数目提示

    效果图 写一篇短小精悍,好用的知识积累吧.开发中时常会出现信息提醒,新内容提示等等一堆问题.其实就是在各种控件或者是item上面加"小圆点".网上一搜一大堆...但是感觉说的好多. ...

最新文章

  1. HDU2675(二分算法)
  2. 如何更加简单的理解JS中的原型原型链概念
  3. 方立勋_30天掌握JavaWeb_MySQL和表约束
  4. java8 函数式编程_如何使用Java 8函数式编程生成字母序列
  5. java的sql的like_[Java教程]SQL like 模糊查询, in
  6. 截取AVI格式的视频C语言代码
  7. Entity Framework 4中的Code-First, Model-First和Database-First模式(转)
  8. 60-40-030-序列化-传统Avro序列化
  9. Android Service是如何启动的?
  10. 设备的开发【WP7学习札记之五】
  11. 多域名环境,页面获取url的一种方案
  12. 简述redux(1)
  13. 1223 Dice Roll Simulation
  14. python ccf题解 201903-2 二十四点
  15. 路由器和三层交换机的基本实验操作
  16. AMiner背后的技术细节与挑战
  17. PHP无限极分类两种写法
  18. 大数据城市规划餐饮选址
  19. 用于图像语义分割的GAU与PPM
  20. Python运用蒙特卡洛算法模拟植物生长

热门文章

  1. java quartz job_用 Quartz 进行作业调度
  2. java 中方法的使用,两个实例教你学会java中方法的使用
  3. mysql账户最小授权_mysql 创建帐号并授权
  4. [Unity脚本运行时更新]C#7.2新特性
  5. 未来计算机的景象,科幻场景即将实现,未来云电脑!
  6. OpenShift Security (1) - 红帽多集群安全管理 RHACS 的主要功能和技术架构
  7. 具有数据库依赖性的.NET Core应用程序的集成测试
  8. ASP.NET核心之路微服务第02部分:查看组件
  9. python字符串相加_谁说python字符串相加效率低
  10. parallels desktop 启动过失败_使用u启动软件制作启动盘时注意哪些【详细介绍】...