android ViewPager实现的左右滑动广告框

ViewPager

1.先对ViewPager这个控件进行一些了解,

  PagerAdapter是 android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAdapter,这两个adapter都是Fragment的适配器,用于实现Fragment的滑动效果。PagerAdapter主要是viewpager的适配器,而viewPager则也是在 android.support.v4扩展包中新添加的一个强大的控件,可以实现控件的滑动效果,比如咱们在软件中常见的广告栏的滑动效果,用viewPager就可以实现。今天主要介绍如何使用viewPagr并重写PagerAdapter实现常见广告栏的滑动效果

  但GOOLE官方更希望将ViewPager与Fragment相结合起来一起使用的。

2.ViewPager要用到的适配器是PagerAdapter,这里PAI的解释:

 

  在使用ViewPager常用设置

  1)ViewPager.setOffscreenPageLimit(2);//设置缓存view 的个数(实际有3个,缓存2个+正在显示的1个)
  2)ViewPager.setPageMargin((int)getResources().getDimensionPixelOffset(R.dimen.ui_5_dip));// 设置viewpager每个页卡的间距,与gallery的spacing属性类似

  3)ViewPager更新数据问题:

  直接使用notifyDataSetChanged是无法更新,需要同时重写getItemPosition返回常量 POSITION_NONE (此常量为viewpager带的)

  在继承了PagerAdapter后主要复写那个4个方法。

  1)当要显示的图片可以进行缓存的时候,会调用这个方法进行显示图片的初始化,我们将要显示的ImageView加入到ViewGroup中,然后作为返回值返回即可,

   而PagerAdapter缓存的图片是三张  (后面给出证明)

   instantiateItem(ViewGroup, int) 

 

  2)PagerAdapter只缓存三张要显示的图片,如果滑动的图片超出了缓存的范围,就会调用这个方法,将图片销毁

  destroyItem(ViewGroup ,int , Object)

  3)获取要滑动的控件的数量,在这里我们以滑动的广告栏为例,那么这里就应该是展示的广告图片的ImageView数量这里设置。

  要想实现能滑到边缘图片还能滑动就需要在这里设置值了

  getCount()

  4) 来判断显示的是否是同一张图片,这里我们将两个参数相比较返回即可,官方就是这么写的,具体作用还不明确

  isViewFromObject(View, Object)

3.再是用PagerAdapter的时候经常会遇到这个:The specified child already has a parent. You must call removeView

解决方法和思路可以参考这个地址:解决办法 

主要的意思就是:子view在引用的时候必须和父view一起被引用,不能脱离父view而被单独引用,除非子view和父view之间脱离了关系就可以了

4.通过一个小例子来进一步解释PagerAdapter:

activity的xml文件:

 1 <LinearLayout 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     android:orientation="horizontal"
 6     tools:context=".MainActivity" >
 7 
 8     <android.support.v4.view.ViewPager
 9         android:id="@+id/viewPager"
10         android:layout_width="fill_parent"
11         android:layout_height="wrap_content" />
12 
13 </LinearLayout>

MainActivity:

 1 public class MainActivity extends Activity {
 2     int i = 0;
 3     int j = 0;
 4     private ViewPager viewPager;
 5 
 6     private int[] imageID;
 7 
 8     private ImageView[] imageViews;
 9 
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.activity_main);
14         viewPager = (ViewPager) findViewById(R.id.viewPager);
15         imageID = new int[] { R.drawable.p1, R.drawable.p2, R.drawable.p3,
16                 R.drawable.p4, R.drawable.p5, R.drawable.p6 };
17         imageViews = new ImageView[imageID.length];
18         for (int i = 0; i < imageViews.length; i++) {
19             ImageView imageView = new ImageView(this);
20             imageView.setBackgroundResource(imageID[i]);
21             imageViews[i] = imageView;
22         }
23 
24         viewPager.setAdapter(new myAdapter());
25 
26     }
27 
28     class myAdapter extends PagerAdapter {
29 
30         @Override
31         public int getCount() {
32             return imageViews.length;
33         }
34 
35         @Override
36         public boolean isViewFromObject(View arg0, Object arg1) {
37             return arg0 == arg1;
38         }
39 
40         @Override
41         public Object instantiateItem(ViewGroup container, int position) {
42             System.out.println("instantiateItem执行了" + (++i) + "次 ,执行位置--->>"
43                     + position);
44             container.addView(imageViews[position], 0); // 将ImageView装到pagerView当中去
45             return imageViews[position];
46         }
47 
48         @Override
49         public void destroyItem(ViewGroup container, int position, Object object) {
50             System.out.println("destroyItem执行了" + (++i) + "次 ,执行位置--->>"
51                     + position);
52             container.removeView(imageViews[position]);
53         }
54 
55     }
56 
57 }

运行后的效果:

在程序运行成功后,打印出了:

这张图片说明ViewPager初始化的时候,是加载了两张图片进去的

在滚动两张图片后打印出:

滚动后instantiateItem是先执行了三次,因为PagerAdapter的缓存熟默认是3,可以修改缓存熟在试试,在滚动后图片数量超过三张后,就会三处最边缘的一张。

虽然实现了图片滚动,但没有达到广告的那种效果。下面进一步的改进

注意:若只有三张图片参与滚动下面方法就会报错,请参考上面的连接。

activity的xml文件:

 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="fill_parent"
 3     android:layout_height="fill_parent"
 4     android:orientation="vertical" >
 5 
 6     <android.support.v4.view.ViewPager
 7         android:id="@+id/viewPager"
 8         android:layout_width="fill_parent"
 9         android:layout_height="wrap_content" />
10 
11     <RelativeLayout
12         android:layout_width="fill_parent"
13         android:layout_height="wrap_content"
14         android:orientation="vertical" >
15 
16         <LinearLayout
17             android:id="@+id/viewGroup"
18             android:layout_width="fill_parent"
19             android:layout_height="wrap_content"
20             android:layout_alignParentBottom="true"
21             android:layout_marginBottom="30dp"
22             android:gravity="center_horizontal"
23             android:orientation="horizontal" >
24         </LinearLayout>
25     </RelativeLayout>
26 
27 </FrameLayout>

MianActivity:

 1 public class MainActivity extends Activity implements OnPageChangeListener {
 2     private ViewPager viewPager;
 3 
 4     private int[] imageID;
 5 
 6     private ImageView[] imageViews;
 7 
 8     private ImageView[] tips;
 9 
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.activity_main);
14         viewPager = (ViewPager) findViewById(R.id.viewPager);
15         imageID = new int[] { R.drawable.p1, R.drawable.p2, R.drawable.p3,
16                 R.drawable.p4, R.drawable.p5, R.drawable.p6 };
17         imageViews = new ImageView[imageID.length];
18         for (int i = 0; i < imageViews.length; i++) {
19             ImageView imageView = new ImageView(this);
20             imageView.setBackgroundResource(imageID[i]);
21             imageViews[i] = imageView;
22         }
23         ViewGroup viewGroup = (ViewGroup) findViewById(R.id.viewGroup);
24         tips = new ImageView[imageViews.length];
25         // 装小圆点
26         for (int j = 0; j < imageViews.length; j++) {
27             ImageView img = new ImageView(this);
28             img.setLayoutParams(new LayoutParams(20, 20));
29             tips[j] = img;
30             if (j == 0) {
31                 tips[j].setBackgroundResource(R.drawable.page_indicator_focused);
32             } else {
33                 tips[j].setBackgroundResource(R.drawable.page_indicator_unfocused);
34             }
35             viewGroup.addView(img);
36         }
37 
38         viewPager.setAdapter(new myAdapter());
39         viewPager.setOnPageChangeListener(this);
40         viewPager.setCurrentItem(imageViews.length * 100);// 这样设置初始化的图片就是显示Integer.MAX_VALUE图片中第imageViews.length
41                                                             // * 100张,这样就可以往左右翻了
42     }
43 
44     class myAdapter extends PagerAdapter {
45 
46         @Override
47         public int getCount() {
48             return Integer.MAX_VALUE;
49         }
50 
51         @Override
52         public boolean isViewFromObject(View arg0, Object arg1) {
53             return arg0 == arg1;
54         }
55 
56         @Override
57         public Object instantiateItem(ViewGroup container, int position) {
58             // System.out.println("instantiateItem执行了" + (++i) + "次 ,执行位置--->>"
59             // + position);
60             container.addView(imageViews[position % imageViews.length], 0); // 取余数后,每次添加的都是之前的6张图片了
61             return imageViews[position % imageViews.length];
62         }
63 
64         @Override
65         public void destroyItem(ViewGroup container, int position, Object object) {
66             // System.out.println("destroyItem执行了" + (++i) + "次 ,执行位置--->>"
67             // + position);       这里在打印出来,就会懂原理了
68             container.removeView(imageViews[position % imageViews.length]);
69         }
70 
71     }
72 
73     @Override
74     public void onPageScrollStateChanged(int arg0) {
75 
76     }
77 
78     @Override
79     public void onPageScrolled(int arg0, float arg1, int arg2) {
80 
81     }
82 
83     @Override
84     public void onPageSelected(int arg0) {
85         setImageBackground(arg0 % imageViews.length);
86     }
87 
88     private void setImageBackground(int selectItems) {
89         for (int i = 0; i < tips.length; i++) {
90             if (i == selectItems) {
91                 tips[i].setBackgroundResource(R.drawable.page_indicator_focused);
92             } else {
93                 tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused);
94             }
95         }
96     }
97 }

运行的效果:

源码下载地址:源码

posted @ 2014-06-06 18:18  perfect亮  阅读(1952)  评论(0编辑  收藏  举报