利用ViewPager实现图片循环滚动

来源:互联网 发布:最好的广告拦截软件 编辑:程序博客网 时间:2024/05/15 23:53

Android中的ListView可以实现屏幕上下滑动来浏览数据,ViewPager则实现了左右滑动的效果。我们可以拿它做很多事情,从最简单的导航,到页面菜单等等。ViewPager类提供了多界面切换的新效果。新效果有如下特征:

[1] 当前显示一组界面中的其中一个界面。

[2] 当用户通过左右滑动界面时,当前的屏幕显示当前界面和下一个界面的一部分。

[3]滑动结束后,界面自动跳转到当前选择的界面中。


下面的代码实现了一个图片循环滚动的功能。首先是布局文件,使用了一个ViewPager控件:

  1. <span style="padding: 0px; margin: 0px; font-size: 14px;"><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.   
  6.     <android.support.v4.view.ViewPager  
  7.         android:id="@+id/viewpager"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="match_parent" >  
  10.     </android.support.v4.view.ViewPager>  
  11.   
  12.     <LinearLayout  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:layout_alignBottom="@id/viewpager"  
  16.         android:background="#33000000"  
  17.         android:orientation="vertical"  
  18.         android:padding="5dip" >  
  19.   
  20.         <TextView  
  21.             android:id="@+id/tv_image_description"  
  22.             android:layout_width="wrap_content"  
  23.             android:layout_height="wrap_content"  
  24.             android:layout_gravity="center_horizontal"  
  25.             android:text="第一个引导页面"  
  26.             android:textColor="@android:color/white"  
  27.             android:textSize="14sp" />  
  28.   
  29.         <LinearLayout  
  30.             android:id="@+id/ll_points"  
  31.             android:layout_width="wrap_content"  
  32.             android:layout_height="wrap_content"  
  33.             android:layout_marginTop="5dip"  
  34.             android:layout_gravity="center_horizontal"  
  35.             android:orientation="horizontal" >  
  36.         </LinearLayout>  
  37.     </LinearLayout>  
  38.   
  39. </RelativeLayout></span> 
ViewPager的适配器是PagerAdapter,它是基类提供适配器来填充页面ViewPager内部。

接下来实现一个继承PagerAdapter的MyAdapter类,实现一个PagerAdapter,必须至少覆盖以下方法:

  • instantiateItem(ViewGroup, int)
  • destroyItem(ViewGroup, int, Object)
  • getCount()
  • isViewFromObject(View, Object

[java] view plaincopy
  1. <span style="padding: 0px; margin: 0px; font-size: 14px;">package com.example.viewpagertest;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.support.v4.view.PagerAdapter;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.ImageView;  
  9.   
  10. class ViewPagerAdapter extends PagerAdapter {  
  11.     private List<ImageView> mImageViewList;  
  12.     public ViewPagerAdapter(List<ImageView> imageViewList) {  
  13.         super();  
  14.         this.mImageViewList = imageViewList;  
  15.     }  
  16.     /** 
  17.      * 该方法将返回所包含的 Item总个数。为了实现一种循环滚动的效果,返回了基本整型的最大值,这样就会创建很多的Item, 
  18.      * 其实这并非是真正的无限循环。 
  19.      */  
  20.     @Override  
  21.     public int getCount() {  
  22.         return Integer.MAX_VALUE;  
  23.     }  
  24.          /** 
  25.      * 判断出去的view是否等于进来的view 如果为true直接复用 
  26.      */  
  27.     @Override  
  28.     public boolean isViewFromObject(View arg0, Object arg1) {  
  29.         return arg0 == arg1;  
  30.     }  
  31.     /** 
  32.      * 销毁预加载以外的view对象, 会把需要销毁的对象的索引位置传进来,就是position, 
  33.      * 因为mImageViewList只有五条数据,而position将会取到很大的值, 
  34.      * 所以使用取余数的方法来获取每一条数据项。 
  35.      */  
  36.     @Override  
  37.     public void destroyItem(ViewGroup container, int position, Object object) {  
  38.         container.removeView(mImageViewList.get(position % mImageViewList.size()));  
  39.     }  
  40.     /** 
  41.      * 创建一个view, 
  42.      */  
  43.     @Override  
  44.     public Object instantiateItem(ViewGroup container, int position) {  
  45.         container.addView(mImageViewList.get(position % mImageViewList.size()));  
  46.         return mImageViewList.get(position % mImageViewList.size());  
  47.     }  
  48. }  
  49. </span>  
最后是主界面部分的代码:

[java] view plaincopy
  1. <span style="padding: 0px; margin: 0px; font-size: 14px;">package com.example.viewpagertest;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.os.SystemClock;  
  11. import android.support.v4.view.ViewPager;  
  12. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  13. import android.view.View;  
  14. import android.widget.ImageView;  
  15. import android.widget.LinearLayout;  
  16. import android.widget.LinearLayout.LayoutParams;  
  17. import android.widget.TextView;  
  18.   
  19. public class MainActivity extends Activity implements OnPageChangeListener {  
  20.   
  21.     private List<ImageView> imageViewList;  
  22.     private TextView tvDescription;  
  23.     private LinearLayout llPoints;  
  24.     private String[] imageDescriptions;  
  25.     private int previousSelectPosition = 0;  
  26.     private ViewPager mViewPager;  
  27.     private boolean isLoop = true;  
  28.     private Handler handler = new Handler() {  
  29.   
  30.         @Override  
  31.         public void handleMessage(Message msg) {  
  32.             super.handleMessage(msg);  
  33.   
  34.             mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);  
  35.         }  
  36.     };  
  37.   
  38.     @Override  
  39.     protected void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setView();  
  42.         initView();  
  43.     }  
  44.   
  45.     public void setView() {  
  46.         setContentView(R.layout.activity_splash_viewpager);  
  47.   
  48.         // 自动切换页面功能  
  49.         new Thread(new Runnable() {  
  50.   
  51.             @Override  
  52.             public void run() {  
  53.                 while (isLoop) {  
  54.                     SystemClock.sleep(2000);  
  55.                     handler.sendEmptyMessage(0);  
  56.                 }  
  57.             }  
  58.         }).start();  
  59.     }  
  60.   
  61.     public void initView() {  
  62.         mViewPager = (ViewPager) findViewById(R.id.viewpager);  
  63.         tvDescription = (TextView) findViewById(R.id.tv_image_description);  
  64.         llPoints = (LinearLayout) findViewById(R.id.ll_points);  
  65.           
  66.         prepareData();  
  67.           
  68.         ViewPagerAdapter adapter = new ViewPagerAdapter(imageViewList);  
  69.         mViewPager.setAdapter(adapter);  
  70.         mViewPager.setOnPageChangeListener(this);  
  71.           
  72.         tvDescription.setText(imageDescriptions[previousSelectPosition]);  
  73.         llPoints.getChildAt(previousSelectPosition).setEnabled(true);  
  74.           
  75.         /** 
  76.          * 2147483647 / 2 = 1073741820 - 1  
  77.          * 设置ViewPager的当前项为一个比较大的数,以便一开始就可以左右循环滑动 
  78.          */  
  79.         int n = Integer.MAX_VALUE / 2 % imageViewList.size();  
  80.         int itemPosition = Integer.MAX_VALUE / 2 - n;  
  81.           
  82.         mViewPager.setCurrentItem(itemPosition);  
  83.     }  
  84.       
  85.      private void prepareData() {  
  86.             imageViewList = new ArrayList<ImageView>();  
  87.             int[] imageResIDs = getImageResIDs();  
  88.             imageDescriptions = getImageDescription();  
  89.               
  90.             ImageView iv;  
  91.             View view;  
  92.             for (int i = 0; i < imageResIDs.length; i++) {  
  93.                 iv = new ImageView(this);  
  94.                 iv.setBackgroundResource(imageResIDs[i]);  
  95.                 imageViewList.add(iv);  
  96.                   
  97.                 // 添加点view对象  
  98.                 view = new View(this);  
  99.                 view.setBackgroundDrawable(getResources().getDrawable(R.drawable.point_background));  
  100.                 LayoutParams lp = new LayoutParams(55);  
  101.                 lp.leftMargin = 10;  
  102.                 view.setLayoutParams(lp);  
  103.                 view.setEnabled(false);  
  104.                 llPoints.addView(view);  
  105.             }  
  106.         }  
  107.           
  108.         private int[] getImageResIDs() {  
  109.             return new int[]{  
  110.                     R.drawable.bg1,  
  111.                     R.drawable.bg2,  
  112.                     R.drawable.bg3,  
  113.                     R.drawable.pic_01,  
  114.                     R.drawable.pic_02  
  115.             };  
  116.         }  
  117.           
  118.         private String[] getImageDescription() {  
  119.             return new String[]{  
  120.                     "第一个引导页面",  
  121.                     "第二个引导页面",  
  122.                     "第三个引导页面",  
  123.                     "第四个引导页面",  
  124.                     "第五个引导页面"  
  125.             };  
  126.         }  
  127.   
  128.         @Override  
  129.         public void onPageScrollStateChanged(int arg0) {  
  130.               
  131.         }  
  132.   
  133.         @Override  
  134.         public void onPageScrolled(int arg0, float arg1, int arg2) {  
  135.               
  136.         }  
  137.   
  138.         @Override  
  139.         public void onPageSelected(int position) {  
  140.             // 改变图片的描述信息  
  141.             tvDescription.setText(imageDescriptions[position % imageViewList.size()]);  
  142.             // 切换选中的点,把前一个点置为normal状态  
  143.             llPoints.getChildAt(previousSelectPosition).setEnabled(false);  
  144.             // 把当前选中的position对应的点置为enabled状态  
  145.             llPoints.getChildAt(position % imageViewList.size()).setEnabled(true);  
  146.             previousSelectPosition = position  % imageViewList.size();  
  147.         }  
  148.   
  149.     @Override  
  150.     protected void onDestroy() {  
  151.         super.onDestroy();  
  152.         isLoop = false;  
  153.     }  
  154.   
  155. }  
  156. </span>  

此处并不是一个真正的无限循环,只是把ViewPager要加载的数据项设置成了一个很大的数值,给人一种感觉是可以无限循环滚动的。这里实现的自动滑动,还有就是监听OnPageChangedListener,实现手动滑动,网上基本都是这种思路,在getCount()中返回一个较大的值,比如500,然后初始时设置mViewPager.currentItem(300或者其他),因为一般人不会划到那么多次。


顺便提一下ViewFlipper和ViewFlow,

1、ViewPager(android.support.v4.view.ViewPager)与ViewFlow都能够使用适配器(ViewPager--PagerAdapter;ViewFlow--BaseAdapter)进行大量数据的适配,并且ViewFlow也带有原点和标题的位置提示,二者比较相像;

2、ViewFlipper使用时主要在有限的少数页面切换中比较合适,并且能够自定义每一个切换动画,用于一个应用间的画面切换比较合适,类似于ActvityGroup;

3、ViewFlow由于提供源码,所以在扩展上更强,可根据需要自行定制,比如加入循环播放等;

4、当需要再一系列不确定数据的View中滑动时,可以考虑使用ViewFlow;如果View数目确定,应该改用Fragments或者兼容库里的ViewPager。


0 0
原创粉丝点击