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)
- android 底部导航总结
- Android底部导航总结
- Android底部导航总结
- android 底部导航总结
- android底部导航栏
- Android 通用底部导航
- android底部导航栏
- android之底部导航
- Android底部导航栏
- android 底部导航栏
- android底部导航栏
- Android BottomNavigationView 底部导航
- Android仿微信底部导航
- Android App之底部tab导航常用实现方案总结
- Android 实现底部导航栏
- Android仿微信底部导航菜单
- Android Fragment实现底部导航
- Android底部导航中间突起
- mysql外键创建失败的问题
- tensorflow:name&variable scope
- 学了2天的Python,自己写了个简单的爬虫,可是爬虫有什么用呢?
- Makefile的编写规则
- 【深入Java虚拟机】之一:Javac编译与JIT编译
- android 底部导航总结
- leetcode69---Sqrt(x)
- Middleware 中间件
- win7,win10右键添加“获取管理员的所有权限”的菜单
- 利用Python画小树和森林(宽度优先绘制+深度优先绘制)
- for 的用法
- 在Ubuntu系统中配置DHCP服务
- 安卓动画 补间动画
- jquery获取动态添加的标签对象