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
不过好像有个是设置缓存页面数量的属性吧,一时半伙想不起来,如果有知道的读者欢迎指出,万分感激!
本节代码下载: