Android实习札记(8)---ViewPager+Fragment实例讲解
——转载请注明出处:coder-pig
在札记(5)中我们就说过要弄一个模仿微信页面切换的东东,就是ViewPager+Fragment
实现的一个东西,札记(6)中也学习了一下ViewPager的一些基本用法,本节就来将两者
结合以实现我们想要的效果!
1.ViewPager关于Fragment的说法?
先看下Google官网怎么说:
大概意思就是:
ViewPager更多的时候是与Fragment协同使用,这样可以更加方便地去创建Page和管理
Page的生命周期,但是使用的不再是PageAdapter适配器,而是他的子类:FragmentPagerAdapter
和FragmentStatePagerAdapter,他们提供了更加简单代码来构建我们的用户界面!
看完这段话,可能会有下面的疑问:
1)FragmentPagerAdapter和FragmentStatePagerAdapter有什么区别,用哪个?
答:前者适用于页面较少的情况,后者对应页面较多的情况,现在只能这样告诉你;貌似这个和他们缓存
page的问题有关,以后再研究吧,通常用的都是FragmentPagerAdapter较多!
2)提供更加简单的代码...怎么简单法?
答:如官方文档所述,只需要实现getItem()与getCount()两个方法即可!相比起PagerAdapter要实现四个
方法简单多了
2.ViewPager对应Fragment的适配器——FragmentPagerAdapter
必须要实现的两个方法:getItem( )与getCount( )
意思:返回与特定postion(下标)有关联的Fragment!
意思:返回有效的View的数目,就是View集合中的View的个数
3)代码实现微信页面切换效果:
什么都别说,先看下效果图:
上面的实现其实还是蛮简单的,核心就是ViewPager + Fragment来实现的,那么现在
就来讲解下如何实现上面的效果:
step 1:首先肯定是先弄我们的主布局文件啦:
一条装逼的顶部标题栏+可切换Page的ViewPager+底部导航栏
底部导航栏和札记6中的实现方法是一致的,就不讲了
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#22292C" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="18dp" android:text="微信(4)" android:textColor="#ffffff" android:textSize="18sp" /> <Button android:id="@+id/btnadd" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginRight="15dp" android:layout_centerVertical="true" android:layout_alignBaseline="@+id/textView1" android:layout_alignBottom="@+id/textView1" android:layout_alignParentRight="true" android:background="@drawable/ap9" /> <Button android:layout_width="30dp" android:layout_height="30dp" android:layout_marginRight="15dp" android:layout_toLeftOf="@id/btnadd" android:layout_centerVertical="true" android:background="@drawable/alt"/> </RelativeLayout> <android.support.v4.view.ViewPager android:id="@+id/vPager" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_gravity="center" android:layout_weight="1.0" android:background="#000000" android:flipInterval="30" android:persistentDrawingCache="animation" /> <ImageView android:layout_width="match_parent" android:layout_height="1dp" android:src="@drawable/aoc" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="55dp" android:background="#FCFCFC" > <RelativeLayout android:id="@+id/weixin_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" > <ImageView android:id="@+id/weixin_img" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center_horizontal" android:src="@drawable/ahk" /> <TextView android:id="@+id/weixin_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="微信" android:textColor="#999999" /> </LinearLayout> </RelativeLayout> <RelativeLayout android:id="@+id/tongxunlu_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" > <ImageView android:id="@+id/tongxunlu_img" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center_horizontal" android:src="@drawable/ahi" /> <TextView android:id="@+id/tongxunlu_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="通讯录" android:textColor="#999999" /> </LinearLayout> </RelativeLayout> <RelativeLayout android:id="@+id/faxian_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" > <ImageView android:id="@+id/faxian_img" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center_horizontal" android:src="@drawable/ahm" /> <TextView android:id="@+id/faxian_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="发现" android:textColor="#999999" /> </LinearLayout> </RelativeLayout> <RelativeLayout android:id="@+id/me_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" > <ImageView android:id="@+id/me_img" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center_horizontal" android:src="@drawable/aho" /> <TextView android:id="@+id/me_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="我" android:textColor="#999999" /> </LinearLayout> </RelativeLayout> </LinearLayout> </LinearLayout>
step 2:主布局写完了,接着就写每个Fragment的布局和对应的Fragment类咯,这里
每个Fragment就是一个简单的TextView + 不同的背景颜色,一式四份就可以了!
fg1.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:gravity="center" android:background="#FAEBD7" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="微信Fragment" /> </LinearLayout>
Fg1.java:
package com.jay.example.viewpagerfragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Fg1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fg1, container,false); return view; } }
step 3:接着就要自定义我们的FragmentPagerAdapter,这个也很简单,只要重写那两个基本
方法就可以了,分别是getItem( )和getCount( )
MyFragmentPagerAdapter.java
package com.jay.example.viewpagerfragment; import java.util.ArrayList; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; public class MyFragmentPageAadpter extends FragmentPagerAdapter { private ArrayList<Fragment> fragmentsList; public MyFragmentPageAadpter(FragmentManager fm) {super(fm);} public MyFragmentPageAadpter(FragmentManager fm, ArrayList<Fragment> fragments) { super(fm); this.fragmentsList = fragments; } @Override public Fragment getItem(int index) { return fragmentsList.get(index); } @Override public int getCount() { return fragmentsList.size(); } }
step 4:接着就到我们最后一步MainActivity的编写了,同样也是不复杂的,要做什么呢?
①实例化四个Fragment对象后,把他们放到View集合中,通过Adapter适配器与ViewPager
进行绑定咯!然后就可以滑动ViewPager进行页面的切换了
②当我们点击底部导航条的按钮时,我们需要切换ViewPager中显示的Fragment,这怎么搞?
答:对点击的按钮的id进行判断,判断点击的是第几个,调用viewpager.setCurrentItem(index)即可
③当我们滑动页面时,底部导航条的图标也要跟着变换,这又怎么搞?
答这个也很简单,重写ViewPager的OnPageChangeListener的onPageScrollStateChanged()方法
当参数等于2时,说明此时滑动完毕,viewpager.getCurrentItem( )获得当前页面序号,从而设置第几个
按钮处于选中状态!
MainActivity.java:
package com.jay.example.viewpagerfragment; import java.util.ArrayList; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; public class MainActivity extends FragmentActivity { //定义四个Fragment private Fg1 fg1; private Fg2 fg2; private Fg3 fg3; private Fg4 fg4; //定义一个ViewPager容器 private ViewPager mPager; private ArrayList<Fragment> fragmentsList; private MyFragmentPageAadpter mAdapter; //下面每个Layout对象 private RelativeLayout weixin_layout; private RelativeLayout tongxunlu_layout; private RelativeLayout faxian_layout; private RelativeLayout me_layout; //依次获得ImageView与TextView private ImageView weixin_img; private ImageView tongxunlu_img; private ImageView faxian_img; private ImageView me_img; private TextView weixin_txt; private TextView tongxunlu_txt; private TextView faxian_txt; private TextView me_txt; //定义颜色值 private int Gray = 0xFF999999; private int Green =0xFF45C01A; //定义FragmentManager对象 public FragmentManager fManager; //定义一个Onclick全局对象 public MyOnClick myclick; public MyPageChangeListener myPageChange; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getActionBar().hide(); fManager = getSupportFragmentManager(); initViewPager(); initViews(); initState(); } private void initViews() { myclick = new MyOnClick(); myPageChange = new MyPageChangeListener(); mPager = (ViewPager) findViewById(R.id.vPager); weixin_layout = (RelativeLayout) findViewById(R.id.weixin_layout); tongxunlu_layout = (RelativeLayout) findViewById(R.id.tongxunlu_layout); faxian_layout = (RelativeLayout) findViewById(R.id.faxian_layout); me_layout = (RelativeLayout) findViewById(R.id.me_layout); weixin_img = (ImageView) findViewById(R.id.weixin_img); tongxunlu_img = (ImageView) findViewById(R.id.tongxunlu_img); faxian_img = (ImageView) findViewById(R.id.faxian_img); me_img = (ImageView) findViewById(R.id.me_img); weixin_txt = (TextView) findViewById(R.id.weixin_txt); tongxunlu_txt = (TextView) findViewById(R.id.tongxunlu_txt); faxian_txt = (TextView) findViewById(R.id.faxian_txt); me_txt = (TextView) findViewById(R.id.me_txt); mPager.setAdapter(mAdapter); mPager.setOnPageChangeListener(myPageChange); weixin_layout.setOnClickListener(myclick); tongxunlu_layout.setOnClickListener(myclick); faxian_layout.setOnClickListener(myclick); me_layout.setOnClickListener(myclick); } private void initViewPager() { fragmentsList = new ArrayList<Fragment>(); fg1 = new Fg1(); fg2 = new Fg2(); fg3 = new Fg3(); fg4 = new Fg4(); fragmentsList.add(fg1); fragmentsList.add(fg2); fragmentsList.add(fg3); fragmentsList.add(fg4); mAdapter = new MyFragmentPageAadpter(fManager,fragmentsList); } //定义一个设置初始状态的方法 private void initState() { weixin_img.setImageResource(R.drawable.ahj); weixin_txt.setTextColor(Green); mPager.setCurrentItem(0); } public class MyOnClick implements OnClickListener { @Override public void onClick(View view) { clearChioce(); iconChange(view.getId()); } } public class MyPageChangeListener implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int arg0) { if(arg0 == 2) { int i = mPager.getCurrentItem(); clearChioce(); iconChange(i); } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) {} @Override public void onPageSelected(int index){} } //建立一个清空选中状态的方法 public void clearChioce() { weixin_img.setImageResource(R.drawable.ahk); weixin_txt.setTextColor(Gray); tongxunlu_img.setImageResource(R.drawable.ahi); tongxunlu_txt.setTextColor(Gray); faxian_img.setImageResource(R.drawable.ahm); faxian_txt.setTextColor(Gray); me_img.setImageResource(R.drawable.aho); me_txt.setTextColor(Gray); } //定义一个底部导航栏图标变化的方法 public void iconChange(int num) { switch (num) { case R.id.weixin_layout:case 0: weixin_img.setImageResource(R.drawable.ahj); weixin_txt.setTextColor(Green); mPager.setCurrentItem(0); break; case R.id.tongxunlu_layout:case 1: tongxunlu_img.setImageResource(R.drawable.ahh); tongxunlu_txt.setTextColor(Green); mPager.setCurrentItem(1); break; case R.id.faxian_layout:case 2: faxian_img.setImageResource(R.drawable.ahl); faxian_txt.setTextColor(Green); mPager.setCurrentItem(2); break; case R.id.me_layout:case 3: me_img.setImageResource(R.drawable.ahn); me_txt.setTextColor(Green); mPager.setCurrentItem(3); break; } } }
最后说几句:
代码还是比较简单的哈,没什么高大上的技术,只是希望可以帮到和我一样的初学者....
另外viewPager好像有缓冲page的功能
就是保存Page的状态,不过是相邻的两个,比如,你现在在2号页,此时1号和3号是缓存
在内存当中的,但是上面如果我们是1然后切换到4页面的话,会发现,2,3两个界面也加载了!
流程如下:
1 --> 2(此时缓存1,2和3) -->3(此时缓存2,3和4) -->4(此时缓存3和4);
总结来说就是:ViewPager会缓存当前页面相邻的两个Page
不过好像有个是设置缓存页面数量的属性吧,一时半伙想不起来,如果有知道的读者欢迎指出,万分感激!
本节代码下载:
http://pan.baidu.com/s/1dDcTNFj