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代码
//注意是继承 FragmentActivity
public 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)