[关闭]
@coder-pig 2015-08-31T15:41:13.000000Z 字数 8266 阅读 1628

Android基础入门教程——5.2.4 Fragment实例精讲——底部导航栏+ViewPager滑动切换页面

Android基础入门教程


本节引言:

前三节我们分别用不同的方式实现了普通底部导航栏的效果,而本节我们将会在第二个实例的基础上
加上ViewPager来实现滑动切换页面的效果!大部分朋友都知道这个ViewPager是什么东西吧,如果
不知道没关系,下面我们简单的来介绍一个这个控件!


1.ViewPager简单介绍


1)是怎么样的一个控件?

答:一个页面切换的组件,我们可以往里面填充多个View,然后我们可以通过触摸屏幕左右滑动
切换不同的View,和前面学习的ListView一样,我们需要一个Adapter(适配器),将要显示的View和
我们的ViewPager进行绑定,而ViewPager有他自己特定的Adapter——PagerAdapter!另外,Google
官方是建议我们使用Fragment来填充ViewPager的,这样可以更加方便的生成每个Page以及管理
每个Page的生命周期!当然它给我们提供了两个不同的Adapter,他们分别是:
FragmentPageAdapterFragmentStatePagerAdapter
而我们本节用到的则是前者:FragmentPageAdapter!
另外要说一点的是ViewPager的缓存机制
ViewPager会缓存当前页,前一页,以及后一页,比如有1,2,3,4这四个页面:
当我们处于第一页:缓存1,2
——> 处于第二页:缓存 1,2,3
——> 处于第三页:缓存2,3,4
——> 处于第四页缓存3,4这样!

2)使用PagerAdapter要重写相关方法:

  • getCount( ):获得viewpager中有多少个view
  • destroyItem( ):移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保
    在finishUpdate(viewGroup)返回时视图能够被移除。
  • instantiateItem( ):①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来
    ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,
    当然你也可以自定义自己的key,但是key和每个view要一一对应的关系
  • isViewFromObject( ):判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是
    代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写
    return view == object;就可以了,至于为什么要这样讲起来比较复杂,后面有机会进行了解吧
    貌似是ViewPager中有个存储view状态信息的ArrayList,根据View取出对应信息的吧!

PS:不一定要重写所有方法~


2.实现效果图以及工程目录结构:

先来看下我们要实现的效果吧

接下来看下我们的项目结构:


3.代码实现:


Step 1:相关资源文件的准备:

PS:我们是在实现底部导航栏方法2的基础上来写的,所以资源文件照搬即可!
这里就不贴多次了~!

Step 2:编写activity_main.xml的布局文件:

PS:只是把前面的FrameLayout替换成了:android.support.v4.view.ViewPager而已:

activity_mian.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity">
  6. <RelativeLayout
  7. android:id="@+id/ly_top_bar"
  8. android:layout_width="match_parent"
  9. android:layout_height="48dp"
  10. android:background="@color/bg_topbar">
  11. <TextView
  12. android:id="@+id/txt_topbar"
  13. android:layout_width="match_parent"
  14. android:layout_height="match_parent"
  15. android:layout_centerInParent="true"
  16. android:gravity="center"
  17. android:text="提醒"
  18. android:textColor="@color/text_topbar"
  19. android:textSize="18sp" />
  20. <View
  21. android:layout_width="match_parent"
  22. android:layout_height="2px"
  23. android:layout_alignParentBottom="true"
  24. android:background="@color/div_white" />
  25. </RelativeLayout>
  26. <RadioGroup
  27. android:id="@+id/rg_tab_bar"
  28. android:layout_width="match_parent"
  29. android:layout_height="56dp"
  30. android:layout_alignParentBottom="true"
  31. android:background="@color/bg_white"
  32. android:orientation="horizontal">
  33. <RadioButton
  34. android:id="@+id/rb_channel"
  35. style="@style/tab_menu_item"
  36. android:drawableTop="@drawable/tab_menu_channel"
  37. android:text="@string/tab_menu_alert" />
  38. <RadioButton
  39. android:id="@+id/rb_message"
  40. style="@style/tab_menu_item"
  41. android:drawableTop="@drawable/tab_menu_message"
  42. android:text="@string/tab_menu_profile" />
  43. <RadioButton
  44. android:id="@+id/rb_better"
  45. style="@style/tab_menu_item"
  46. android:drawableTop="@drawable/tab_menu_better"
  47. android:text="@string/tab_menu_pay" />
  48. <RadioButton
  49. android:id="@+id/rb_setting"
  50. style="@style/tab_menu_item"
  51. android:drawableTop="@drawable/tab_menu_setting"
  52. android:text="@string/tab_menu_setting" />
  53. </RadioGroup>
  54. <View
  55. android:id="@+id/div_tab_bar"
  56. android:layout_width="match_parent"
  57. android:layout_height="2px"
  58. android:layout_above="@id/rg_tab_bar"
  59. android:background="@color/div_white" />
  60. <android.support.v4.view.ViewPager
  61. android:id="@+id/vpager"
  62. android:layout_width="match_parent"
  63. android:layout_height="match_parent"
  64. android:layout_above="@id/div_tab_bar"
  65. android:layout_below="@id/ly_top_bar" />
  66. </RelativeLayout>

Step 3:编写Fragment的布局以及代码:

PS:这里为了顺便演示ViewPager的机制,特意写成了四个Fragment!在onCreateView中打印创建Log!

fg_content.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@color/bg_white"
  6. android:orientation="vertical">
  7. <TextView
  8. android:id="@+id/txt_content"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:gravity="center"
  12. android:text="呵呵"
  13. android:textColor="@color/text_yellow"
  14. android:textSize="20sp" />
  15. </LinearLayout>

MyFragment1.java:

  1. /**
  2. * Created by Jay on 2015/8/28 0028.
  3. */
  4. public class MyFragment1 extends Fragment {
  5. public MyFragment1() {
  6. }
  7. @Override
  8. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  9. View view = inflater.inflate(R.layout.fg_content, container, false);
  10. TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
  11. txt_content.setText("第一个Fragment");
  12. Log.e("HEHE", "1日狗");
  13. return view;
  14. }
  15. }

其他三个照葫芦画瓢,换点东西就好!

Step 4:自定义FragmentPagerAdapter类:

代码很简单,只需传递一个FragmentManager过来,其他都在这里完成!

  1. /**
  2. * Created by Jay on 2015/8/31 0031.
  3. */
  4. public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
  5. private final int PAGER_COUNT = 4;
  6. private MyFragment1 myFragment1 = null;
  7. private MyFragment2 myFragment2 = null;
  8. private MyFragment3 myFragment3 = null;
  9. private MyFragment4 myFragment4 = null;
  10. public MyFragmentPagerAdapter(FragmentManager fm) {
  11. super(fm);
  12. myFragment1 = new MyFragment1();
  13. myFragment2 = new MyFragment2();
  14. myFragment3 = new MyFragment3();
  15. myFragment4 = new MyFragment4();
  16. }
  17. @Override
  18. public int getCount() {
  19. return PAGER_COUNT;
  20. }
  21. @Override
  22. public Object instantiateItem(ViewGroup vg, int position) {
  23. return super.instantiateItem(vg, position);
  24. }
  25. @Override
  26. public void destroyItem(ViewGroup container, int position, Object object) {
  27. System.out.println("position Destory" + position);
  28. super.destroyItem(container, position, object);
  29. }
  30. @Override
  31. public Fragment getItem(int position) {
  32. Fragment fragment = null;
  33. switch (position) {
  34. case MainActivity.PAGE_ONE:
  35. fragment = myFragment1;
  36. break;
  37. case MainActivity.PAGE_TWO:
  38. fragment = myFragment2;
  39. break;
  40. case MainActivity.PAGE_THREE:
  41. fragment = myFragment3;
  42. break;
  43. case MainActivity.PAGE_FOUR:
  44. fragment = myFragment4;
  45. break;
  46. }
  47. return fragment;
  48. }
  49. }

Step 5:MainActivity的编写:

逻辑很简单,自己看~

MainActivity.java:

  1. package com.jay.fragmentdemo4;
  2. import android.os.Bundle;
  3. import android.support.v4.view.ViewPager;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.widget.RadioButton;
  6. import android.widget.RadioGroup;
  7. import android.widget.TextView;
  8. /**
  9. * Created by Coder-pig on 2015/8/28 0028.
  10. */
  11. public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener,
  12. ViewPager.OnPageChangeListener {
  13. //UI Objects
  14. private TextView txt_topbar;
  15. private RadioGroup rg_tab_bar;
  16. private RadioButton rb_channel;
  17. private RadioButton rb_message;
  18. private RadioButton rb_better;
  19. private RadioButton rb_setting;
  20. private ViewPager vpager;
  21. private MyFragmentPagerAdapter mAdapter;
  22. //几个代表页面的常量
  23. public static final int PAGE_ONE = 0;
  24. public static final int PAGE_TWO = 1;
  25. public static final int PAGE_THREE = 2;
  26. public static final int PAGE_FOUR = 3;
  27. @Override
  28. protected void onCreate(Bundle savedInstanceState) {
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31. mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
  32. bindViews();
  33. rb_channel.setChecked(true);
  34. }
  35. private void bindViews() {
  36. txt_topbar = (TextView) findViewById(R.id.txt_topbar);
  37. rg_tab_bar = (RadioGroup) findViewById(R.id.rg_tab_bar);
  38. rb_channel = (RadioButton) findViewById(R.id.rb_channel);
  39. rb_message = (RadioButton) findViewById(R.id.rb_message);
  40. rb_better = (RadioButton) findViewById(R.id.rb_better);
  41. rb_setting = (RadioButton) findViewById(R.id.rb_setting);
  42. rg_tab_bar.setOnCheckedChangeListener(this);
  43. vpager = (ViewPager) findViewById(R.id.vpager);
  44. vpager.setAdapter(mAdapter);
  45. vpager.setCurrentItem(0);
  46. vpager.addOnPageChangeListener(this);
  47. }
  48. @Override
  49. public void onCheckedChanged(RadioGroup group, int checkedId) {
  50. switch (checkedId) {
  51. case R.id.rb_channel:
  52. vpager.setCurrentItem(PAGE_ONE);
  53. break;
  54. case R.id.rb_message:
  55. vpager.setCurrentItem(PAGE_TWO);
  56. break;
  57. case R.id.rb_better:
  58. vpager.setCurrentItem(PAGE_THREE);
  59. break;
  60. case R.id.rb_setting:
  61. vpager.setCurrentItem(PAGE_FOUR);
  62. break;
  63. }
  64. }
  65. //重写ViewPager页面切换的处理方法
  66. @Override
  67. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  68. }
  69. @Override
  70. public void onPageSelected(int position) {
  71. }
  72. @Override
  73. public void onPageScrollStateChanged(int state) {
  74. //state的状态有三个,0表示什么都没做,1正在滑动,2滑动完毕
  75. if (state == 2) {
  76. switch (vpager.getCurrentItem()) {
  77. case PAGE_ONE:
  78. rb_channel.setChecked(true);
  79. break;
  80. case PAGE_TWO:
  81. rb_message.setChecked(true);
  82. break;
  83. case PAGE_THREE:
  84. rb_better.setChecked(true);
  85. break;
  86. case PAGE_FOUR:
  87. rb_setting.setChecked(true);
  88. break;
  89. }
  90. }
  91. }
  92. }

PS:嘿嘿,上面我把导包部分的代码也贴出来了,就是害怕你们导错包,然后出现一些莫名其妙的错误!
因为ViewPager是v4包下面的,所以Fragment,FragmentManager,FragmentTransaction都是需要使用
V4包下的哦!另外获取FragmentManager的方法不是直接用getFragmentManager()而是使用
getSupportFragmentManager()哦!


4.代码下载:

FragmentDemo4http://pan.baidu.com/s/1o6kV4RC


本节小结:

好的,上面就是底部导航栏 + ViewPager实现简单滑动切换Fragment的实现过程了!
就说这么多,谢谢~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注