• Android ViewPager使用详解


    这是谷歌官方给我们提供的一个兼容低版本安卓设 备的软件包,里面包囊了只有在安卓3.0以上可以使用的api。而viewpager就是其中之一利用它,我们可以做很多事情,从最简单的导航,到页面菜 单等等。那如何使用它呢,与LisstView类似,我们也需要一个适配器,他就是PagerAdapter。看一下api的图片,



    ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样。分三个步骤来使用它:
    1.在住布局文件里加入
    [mw_shl_code=java,true]

    1. <android.support.v4.view.ViewPager    这个组件,注意这个组件是用来显示左右滑动的界面的,如果不加载xml布局文件,他是不会显示内容的。
    2.         android:id="@+id/viewpager"
    3.         android:layout_width="wrap_content"
    4.         android:layout_height="wrap_content"
    5.         android:layout_gravity="center" >

    [/mw_shl_code]

    2.加载要显示的页卡,
    [mw_shl_code=java,true]

    1. LayoutInflater lf = getLayoutInflater().from(this);
    2.                 view1 = lf.inflate(R.layout.layout1, null);
    3.                 view2 = lf.inflate(R.layout.layout2, null);
    4.                 view3 = lf.inflate(R.layout.layout3, null);

    5.                 viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
    6.                 viewList.add(view1);
    7.                 viewList.add(view2);
    8.                 viewList.add(view3);

    [/mw_shl_code]

    3.在Activity里实例化ViewPager组件,并设置它的Adapter(就是PagerAdapter,方法与ListView一样的),在这里一般需要重写PagerAdapter。
    [mw_shl_code=java,true]

    1. PagerAdapter pagerAdapter = new PagerAdapter() {

    2.                         @Override
    3.                         public boolean isViewFromObject(View arg0, Object arg1) {

    4.                                 return arg0 == arg1;
    5.                         }

    6.                         @Override
    7.                         public int getCount() {

    8.                                 return viewList.size();
    9.                         }

    10.                         @Override
    11.                         public void destroyItem(ViewGroup container, int position,
    12.                                         Object object) {
    13.                                 container.removeView(viewList.get(position));

    14.                         }

    15.                         @Override
    16.                         public int getItemPosition(Object object) {

    17.                                 return super.getItemPosition(object);
    18.                         }

    19.                         @Override
    20.                         public CharSequence getPageTitle(int position) {

    21.                                 return titleList.get(position);
    22.                         }

    23.                         @Override
    24.                         public Object instantiateItem(ViewGroup container, int position) {
    25.                                 container.addView(viewList.get(position));
    26.                                 weibo_button=(Button) findViewById(R.id.button1);
    27.                                 weibo_button.setOnClickListener(new OnClickListener() {
    28.                                          
    29.                                         public void onClick(View v) {
    30.                                                 intent=new Intent(ViewPagerDemo.this,WeiBoActivity.class);
    31.                                                 startActivity(intent);
    32.                                         }
    33.                                 });
    34.                                 return viewList.get(position);
    35.                         }

    36.                 };
    37.                 viewPager.setAdapter(pagerAdapter);

    [/mw_shl_code]

    这是重写PagerAdapter的一个方法,我们还可以这样做:

    [mw_shl_code=java,true]

    1. public class MyViewPagerAdapter extends PagerAdapter{
    2.                 private List<View> mListViews;
    3.                  
    4.                 public MyViewPagerAdapter(List<View> mListViews) {
    5.                         this.mListViews = mListViews;//构造方法,参数是我们的页卡,这样比较方便。
    6.                 }

    7.                 @Override
    8.                 public void destroyItem(ViewGroup container, int position, Object object)         {        
    9.                         container.removeView(mListViews.get(position));//删除页卡
    10.                 }


    11.                 @Override
    12.                 public Object instantiateItem(ViewGroup container, int position) {        //这个方法用来实例化页卡               
    13.                          container.addView(mListViews.get(position), 0);//添加页卡
    14.                          return mListViews.get(position);
    15.                 }

    16.                 @Override
    17.                 public int getCount() {                        
    18.                         return  mListViews.size();//返回页卡的数量
    19.                 }
    20.                  
    21.                 @Override
    22.                 public boolean isViewFromObject(View arg0, Object arg1) {                        
    23.                         return arg0==arg1;//官方提示这样写
    24.                 }
    25.         }

    [/mw_shl_code]

    大同小异,有一定很重要,就是我们需要重写哪些方法。从上面的图片可以看到,ViewPager的适配器是PagerAdapter,它是基类提供适配器 来填充页面ViewPager内部,你很可能想要使用一个更具体的实现,如FragmentPagerAdapter或 FragmentStatePagerAdapter。在这里需要说明一下,其实ViewPager应该和Fragment一起使用,至少谷歌官方是这么 想的,但是在3.0之下,我们没有必要这么做。下面要注意,当你实现一个PagerAdapter,你必须至少覆盖以下方法:

    1. instantiateItem(ViewGroup, int)
    2. destroyItem(ViewGroup, int, Object)
    3. getCount()
    4. isViewFromObject(View, Object)

    从上面的例子中可以看到,我们最少也是实现了上面四个方法,当然如果你想让程序更健壮或是功能更全面,你可以重写其他的方法。下面看一下第一个完整的示例代码:
      主页面Activity:

    [mw_shl_code=java,true]

    1. package com.example.viewpagerdemo;

    2. import java.util.ArrayList;
    3. import java.util.List;
    4. import android.os.Bundle;
    5. import android.app.Activity;
    6. import android.content.Context;
    7. import android.content.Intent;
    8. import android.support.v4.view.PagerAdapter;
    9. import android.support.v4.view.PagerTabStrip;
    10. import android.support.v4.view.PagerTitleStrip;
    11. import android.support.v4.view.ViewPager;
    12. import android.util.AttributeSet;
    13. import android.view.LayoutInflater;
    14. import android.view.Menu;
    15. import android.view.View;
    16. import android.view.View.OnClickListener;
    17. import android.view.ViewGroup;
    18. import android.widget.Button;

    19. public class ViewPagerDemo extends Activity {

    20.         private View view1, view2, view3;//需要滑动的页卡
    21.         private ViewPager viewPager;//viewpager
    22.         private PagerTitleStrip pagerTitleStrip;//viewpager的标题
    23.         private PagerTabStrip pagerTabStrip;//一个viewpager的指示器,效果就是一个横的粗的下划线
    24.         private List<View> viewList;//把需要滑动的页卡添加到这个list中
    25.         private List<String> titleList;//viewpager的标题
    26.         private Button weibo_button;//button对象,一会用来进入第二个Viewpager的示例
    27.    private Intent intent;
    28.         @Override
    29.         public void onCreate(Bundle savedInstanceState) {
    30.                 super.onCreate(savedInstanceState);
    31.                 setContentView(R.layout.activity_view_pager_demo);
    32.                 initView();
    33.         }
    34.       /*在这里需要说明一下,在上面的图片中我们看到了,PagerTabStrip,PagerTitleStrip,他们其实是viewpager的一 个指示器,前者效果就是一个横的粗的下划线,后者用来显示各个页卡的标题,当然而这也可以共存。在使用他们的时候需要注意,看下面的布局文件,要在 android.support.v4.view.ViewPager里面添加
    35. android.support.v4.view.PagerTabStrip以及android.support.v4.view.PagerTitleStrip。

    36.         private void initView() {
    37.                 viewPager = (ViewPager) findViewById(R.id.viewpager);
    38.                 //pagerTitleStrip = (PagerTitleStrip) findViewById(R.id.pagertitle);
    39.                 pagerTabStrip=(PagerTabStrip) findViewById(R.id.pagertab);
    40.                 pagerTabStrip.setTabIndicatorColor(getResources().getColor(R.color.gold));
    41.                 pagerTabStrip.setDrawFullUnderline(false);
    42.                 pagerTabStrip.setBackgroundColor(getResources().getColor(R.color.azure));
    43.                 pagerTabStrip.setTextSpacing(50);
    44.                 /*
    45.                 weibo_button=(Button) findViewById(R.id.button1);
    46.                 weibo_button.setOnClickListener(new OnClickListener() {
    47.                         
    48.                         public void onClick(View v) {
    49.                                 intent=new Intent(ViewPagerDemo.this,WeiBoActivity.class);
    50.                                 startActivity(intent);
    51.                         }
    52.                 });
    53.                 */
    54.                  
    55.                 view1 = findViewById(R.layout.layout1);
    56.                 view2 = findViewById(R.layout.layout2);
    57.                 view3 = findViewById(R.layout.layout3);

    58.                 LayoutInflater lf = getLayoutInflater().from(this);
    59.                 view1 = lf.inflate(R.layout.layout1, null);
    60.                 view2 = lf.inflate(R.layout.layout2, null);
    61.                 view3 = lf.inflate(R.layout.layout3, null);

    62.                 viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
    63.                 viewList.add(view1);
    64.                 viewList.add(view2);
    65.                 viewList.add(view3);

    66.                 titleList = new ArrayList<String>();// 每个页面的Title数据
    67.                 titleList.add("wp");
    68.                 titleList.add("jy");
    69.                 titleList.add("jh");

    70.                 PagerAdapter pagerAdapter = new PagerAdapter() {

    71.                         @Override
    72.                         public boolean isViewFromObject(View arg0, Object arg1) {

    73.                                 return arg0 == arg1;
    74.                         }

    75.                         @Override
    76.                         public int getCount() {

    77.                                 return viewList.size();
    78.                         }

    79.                         @Override
    80.                         public void destroyItem(ViewGroup container, int position,
    81.                                         Object object) {
    82.                                 container.removeView(viewList.get(position));

    83.                         }

    84.                         @Override
    85.                         public int getItemPosition(Object object) {

    86.                                 return super.getItemPosition(object);
    87.                         }

    88.                         @Override
    89.                         public CharSequence getPageTitle(int position) {

    90.                                 return titleList.get(position);//直接用适配器来完成标题的显示,所以从上面可以看到,我们没有使用PagerTitleStrip。当然你可以使用。

    91.                         }

    92.                         @Override
    93.                         public Object instantiateItem(ViewGroup container, int position) {
    94.                                 container.addView(viewList.get(position));
    95.                                 weibo_button=(Button) findViewById(R.id.button1);//这个需要注意,我们是在重写adapter里面实例化button组件的,如果你在 onCreate()方法里这样做会报错的。
    96.                                 weibo_button.setOnClickListener(new OnClickListener() {
    97.                                          
    98.                                         public void onClick(View v) {
    99.                                                 intent=new Intent(ViewPagerDemo.this,WeiBoActivity.class);
    100.                                                 startActivity(intent);
    101.                                         }
    102.                                 });
    103.                                 return viewList.get(position);
    104.                         }

    105.                 };
    106.                 viewPager.setAdapter(pagerAdapter);
    107.         }

    108.         @Override
    109.         public boolean onCreateOptionsMenu(Menu menu) {
    110.                 getMenuInflater().inflate(R.menu.activity_view_pager_demo, menu);
    111.                 return true;
    112.         }

    113. }

    它的布局文件:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3.     android:layout_width="fill_parent"
    4.     android:layout_height="fill_parent"
    5.     android:orientation="vertical" >

    6.     <android.support.v4.view.ViewPager
    7.         android:id="@+id/viewpager"
    8.         android:layout_width="wrap_content"
    9.         android:layout_height="wrap_content"
    10.         android:layout_gravity="center" >
    11.                
    12.         <android.support.v4.view.PagerTabStrip  
    13.             android:id="@+id/pagertab"  
    14.             android:layout_width="wrap_content"  
    15.             android:layout_height="wrap_content"  
    16.             android:layout_gravity="top"/>  
    17.          
    18.     </android.support.v4.view.ViewPager>

    19. </LinearLayout>
    20. <!--

    注意事项:
    1.这里ViewPager和 PagerTabStrip都要把包名写全了,不然会ClassNotFount
    2.API中说:在布局xml把PagerTabStrip当做ViewPager的一个子标签来用,不能拿出来,不然还是会报错
    3.在PagerTabStrip标签中可以用属性android:layout_gravity=TOP|BOTTOM来指定title的位置
    4.如果要显示出PagerTabStrip某一页的title,需要在ViewPager的adapter中实现getPageTitle(int)-->

    这样就完成了一个简单的ViewPager的使用示例,看一下效果图:




    可以左右滑动页卡,但是仔细看一下,标题的效果不好,不能一次显示一个,而且标题还滑动。其实在api里面提供了一个 pagerTabStrip.setTextSpacing()来设置标题的距离,但是我在这里设置了,没有效果不知道为什么,明白的朋友希望能够赐教一 下。
    所以就有人使用下面这样的方法来仿微博的效果,



    这个标题就固定了,而且可以左右滑动,也有下面的横线,来指示页卡。方法和上面的差不多,区别在于这个横线需要我们自己来做,其实就是一个图片。这个例子是网上的一篇文章,看代码:
    主Activity:

    1. package com.example.viewpagerdemo;

    2. import java.util.ArrayList;
    3. import java.util.List;
    4. import android.app.Activity;
    5. import android.graphics.BitmapFactory;
    6. import android.graphics.Matrix;
    7. import android.os.Bundle;
    8. import android.support.v4.view.PagerAdapter;
    9. import android.support.v4.view.ViewPager;
    10. import android.support.v4.view.ViewPager.OnPageChangeListener;
    11. import android.util.DisplayMetrics;
    12. import android.view.LayoutInflater;
    13. import android.view.View;
    14. import android.view.View.OnClickListener;
    15. import android.view.animation.Animation;
    16. import android.view.animation.TranslateAnimation;
    17. import android.view.ViewGroup;
    18. import android.widget.ImageView;
    19. import android.widget.TextView;
    20. import android.widget.Toast;

    21. public class WeiBoActivity extends Activity {

    22.         private ViewPager viewPager;//页卡内容
    23.         private ImageView imageView;// 动画图片
    24.         private TextView textView1,textView2,textView3;
    25.         private List<View> views;// Tab页面列表
    26.         private int offset = 0;// 动画图片偏移量
    27.         private int currIndex = 0;// 当前页卡编号
    28.         private int bmpW;// 动画图片宽度
    29.         private View view1,view2,view3;//各个页卡
    30.         @Override
    31.         protected void onCreate(Bundle savedInstanceState) {
    32.                 super.onCreate(savedInstanceState);
    33.                 setContentView(R.layout.weibo);
    34.                 InitImageView();
    35.                 InitTextView();
    36.                 InitViewPager();
    37.         }

    38.         private void InitViewPager() {
    39.                 viewPager=(ViewPager) findViewById(R.id.vPager);
    40.                 views=new ArrayList<View>();
    41.                 LayoutInflater inflater=getLayoutInflater();
    42.                 view1=inflater.inflate(R.layout.lay1, null);
    43.                 view2=inflater.inflate(R.layout.lay2, null);
    44.                 view3=inflater.inflate(R.layout.lay3, null);
    45.                 views.add(view1);
    46.                 views.add(view2);
    47.                 views.add(view3);
    48.                 viewPager.setAdapter(new MyViewPagerAdapter(views));
    49.                 viewPager.setCurrentItem(0);
    50.                 viewPager.setOnPageChangeListener(new MyOnPageChangeListener());
    51.         }
    52.          /**
    53.           *  初始化头标
    54.           */

    55.         private void InitTextView() {
    56.                 textView1 = (TextView) findViewById(R.id.text1);
    57.                 textView2 = (TextView) findViewById(R.id.text2);
    58.                 textView3 = (TextView) findViewById(R.id.text3);

    59.                 textView1.setOnClickListener(new MyOnClickListener(0));
    60.                 textView2.setOnClickListener(new MyOnClickListener(1));
    61.                 textView3.setOnClickListener(new MyOnClickListener(2));
    62.         }

    63.         /**
    64.          2      * 初始化动画,这个就是页卡滑动时,下面的横线也滑动的效果,在这里需要计算一些数据
    65.          3 */

    66.         private void InitImageView() {
    67.                 imageView= (ImageView) findViewById(R.id.cursor);
    68.                 bmpW = BitmapFactory.decodeResource(getResources(), R.drawable.a).getWidth();// 获取图片宽度
    69.                 DisplayMetrics dm = new DisplayMetrics();
    70.                 getWindowManager().getDefaultDisplay().getMetrics(dm);
    71.                 int screenW = dm.widthPixels;// 获取分辨率宽度
    72.                 offset = (screenW / 3 - bmpW) / 2;// 计算偏移量
    73.                 Matrix matrix = new Matrix();
    74.                 matrix.postTranslate(offset, 0);
    75.                 imageView.setImageMatrix(matrix);// 设置动画初始位置
    76.         }

    77.         /**
    78.          *     
    79.          * 头标点击监听 3 */
    80.         private class MyOnClickListener implements OnClickListener{
    81.         private int index=0;
    82.         public MyOnClickListener(int i){
    83.                 index=i;
    84.         }
    85.                 public void onClick(View v) {
    86.                         viewPager.setCurrentItem(index);                        
    87.                 }
    88.                  
    89.         }
    90.          
    91.         public class MyViewPagerAdapter extends PagerAdapter{
    92.                 private List<View> mListViews;
    93.                  
    94.                 public MyViewPagerAdapter(List<View> mListViews) {
    95.                         this.mListViews = mListViews;
    96.                 }

    97.                 @Override
    98.                 public void destroyItem(ViewGroup container, int position, Object object)         {        
    99.                         container.removeView(mListViews.get(position));
    100.                 }


    101.                 @Override
    102.                 public Object instantiateItem(ViewGroup container, int position) {                        
    103.                          container.addView(mListViews.get(position), 0);
    104.                          return mListViews.get(position);
    105.                 }

    106.                 @Override
    107.                 public int getCount() {                        
    108.                         return  mListViews.size();
    109.                 }
    110.                  
    111.                 @Override
    112.                 public boolean isViewFromObject(View arg0, Object arg1) {                        
    113.                         return arg0==arg1;
    114.                 }
    115.         }

    116.     public class MyOnPageChangeListener implements OnPageChangeListener{

    117.             int one = offset * 2 + bmpW;// 页卡1 -> 页卡2 偏移量
    118.                 int two = one * 2;// 页卡1 -> 页卡3 偏移量
    119.                 public void onPageScrollStateChanged(int arg0) {
    120.                         
    121.                         
    122.                 }

    123.                 public void onPageScrolled(int arg0, float arg1, int arg2) {
    124.                         
    125.                         
    126.                 }

    127.                 public void onPageSelected(int arg0) {
    128.                         /*两种方法,这个是一种,下面还有一种,显然这个比较麻烦
    129.                         Animation animation = null;
    130.                         switch (arg0) {
    131.                         case 0:
    132.                                 if (currIndex == 1) {
    133.                                         animation = new TranslateAnimation(one, 0, 0, 0);
    134.                                 } else if (currIndex == 2) {
    135.                                         animation = new TranslateAnimation(two, 0, 0, 0);
    136.                                 }
    137.                                 break;
    138.                         case 1:
    139.                                 if (currIndex == 0) {
    140.                                         animation = new TranslateAnimation(offset, one, 0, 0);
    141.                                 } else if (currIndex == 2) {
    142.                                         animation = new TranslateAnimation(two, one, 0, 0);
    143.                                 }
    144.                                 break;
    145.                         case 2:
    146.                                 if (currIndex == 0) {
    147.                                         animation = new TranslateAnimation(offset, two, 0, 0);
    148.                                 } else if (currIndex == 1) {
    149.                                         animation = new TranslateAnimation(one, two, 0, 0);
    150.                                 }
    151.                                 break;
    152.                                  
    153.                         }
    154.                         */
    155.                         Animation animation = new TranslateAnimation(one*currIndex, one*arg0, 0, 0);//显然这个比较简洁,只有一行代码。
    156.                         currIndex = arg0;
    157.                         animation.setFillAfter(true);// True:图片停在动画结束位置
    158.                         animation.setDuration(300);
    159.                         imageView.startAnimation(animation);
    160.                         Toast.makeText(WeiBoActivity.this, "您选择了"+ viewPager.getCurrentItem()+"页卡", Toast.LENGTH_SHORT).show();
    161.                 }
    162.             
    163.     }
    164. }

    它的布局文件:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3.     android:layout_width="fill_parent"
    4.     android:layout_height="fill_parent"
    5.     android:orientation="vertical" >

    6.     <LinearLayout
    7.         android:id="@+id/linearLayout1"
    8.         android:layout_width="fill_parent"
    9.         android:layout_height="40.0dip"
    10.         android:background="#FFFFFF" >

    11.         <TextView
    12.             android:id="@+id/text1"
    13.             android:layout_width="fill_parent"
    14.             android:layout_height="fill_parent"
    15.             android:layout_weight="1.0"
    16.             android:gravity="center"
    17.             android:text=" @我"
    18.             android:textColor="#000000"
    19.             android:textSize="20.0dip" />

    20.         <TextView
    21.             android:id="@+id/text2"
    22.             android:layout_width="fill_parent"
    23.             android:layout_height="fill_parent"
    24.             android:layout_weight="1.0"
    25.             android:gravity="center"
    26.             android:text="评论"
    27.             android:textColor="#000000"
    28.             android:textSize="20.0dip" />

    29.         <TextView
    30.             android:id="@+id/text3"
    31.             android:layout_width="fill_parent"
    32.             android:layout_height="fill_parent"
    33.             android:layout_weight="1.0"
    34.             android:gravity="center"
    35.             android:text="私信"
    36.             android:textColor="#000000"
    37.             android:textSize="20.0dip" />
    38.     </LinearLayout>

    39.     <ImageView
    40.         android:id="@+id/cursor"
    41.         android:layout_width="fill_parent"
    42.         android:layout_height="wrap_content"
    43.         android:scaleType="matrix"
    44.         android:src="@drawable/a" />

    45.     <android.support.v4.view.ViewPager
    46.         android:id="@+id/vPager"
    47.         android:layout_width="wrap_content"
    48.         android:layout_height="0dp"
    49.         android:layout_gravity="center"
    50.         android:layout_weight="1.0"
    51.         android:background="#000000"
    52.         android:flipInterval="30"
    53.         android:persistentDrawingCache="animation" />
    54. </LinearLayout>
    复制代码

    效果如下:




    所以总结一下,我们可以使用ViewPager做什么:
    1.程序使用导航,外加底部圆点的效果,这个在微信示例里介绍了
    2.页卡滑动,加上菜单的效果,不管是之前的支持手势也支持底部图标点击的微信,还是今天的微博。

  • 相关阅读:
    es5预览本地文件、es6练习代码演示案例
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Subversion under Linux [Reprint]
    Subversion how[Reprint]
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3254686.html
Copyright © 2020-2023  润新知