首页 > 代码库 > Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View---转

Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View---转

最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View。

主要原理就是利用定时任务器定时切换ViewPager的页面。

主页面布局实现如下:

view sourceprint?
01.<?xml version="1.0" encoding="utf-8"?>
02. 
03.<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
04.android:layout_width="match_parent"
05.android:layout_height="match_parent">
06. 
07.<android.support.v4.view.ViewPager
08.android:id="@+id/viewPager"
09.android:layout_width="match_parent"
10.android:layout_height="match_parent" />
11. 
12.<LinearLayout
13.android:layout_width="match_parent"
14.android:layout_height="wrap_content"
15.android:layout_alignParentBottom="true"
16.android:padding="5dp"
17.android:gravity="center"
18.android:orientation="horizontal">
19. 
20.<View
21.android:id="@+id/v_dot1"
22.android:layout_width="8dp"
23.android:layout_height="8dp"
24.android:background="@drawable/dot_black" />
25. 
26.<View
27.android:id="@+id/v_dot2"
28.android:layout_width="8dp"
29.android:layout_height="8dp"
30.android:layout_marginLeft="5dp"
31.android:background="@drawable/dot_white" />
32. 
33.<View
34.android:id="@+id/v_dot3"
35.android:layout_width="8dp"
36.android:layout_height="8dp"
37.android:layout_marginLeft="5dp"
38.android:background="@drawable/dot_white" />
39. 
40.<View
41.android:id="@+id/v_dot4"
42.android:layout_width="8dp"
43.android:layout_height="8dp"
44.android:layout_marginLeft="5dp"
45.android:background="@drawable/dot_white" />
46. 
47.<View
48.android:id="@+id/v_dot5"
49.android:layout_width="8dp"
50.android:layout_height="8dp"
51.android:layout_marginLeft="5dp"
52.android:background="@drawable/dot_white" />
53. 
54.</LinearLayout>
55.</RelativeLayout>

轮播效果视图类代码实现如下:

view sourceprint?
001.package com.czm.customview;
002. 
003.import java.util.ArrayList;
004.import java.util.List;
005.import java.util.concurrent.Executors;
006.import java.util.concurrent.ScheduledExecutorService;
007.import java.util.concurrent.TimeUnit;
008. 
009.import android.content.Context;
010.import android.graphics.drawable.Drawable;
011.import android.os.Handler;
012.import android.os.Message;
013.import android.os.Parcelable;
014.import android.support.v4.view.PagerAdapter;
015.import android.support.v4.view.ViewPager;
016.import android.support.v4.view.ViewPager.OnPageChangeListener;
017.import android.util.AttributeSet;
018.import android.view.LayoutInflater;
019.import android.view.View;
020.import android.widget.FrameLayout;
021.import android.widget.ImageView;
022.import android.widget.ImageView.ScaleType;
023. 
024. 
025./**
026.* ViewPager实现的轮播图广告自定义视图,如京东首页的广告轮播图效果;
027.* 既支持自动轮播页面也支持手势滑动切换页面
028.* @author caizhiming
029.*
030.*/
031. 
032.public class SlideShowView extends FrameLayout {
033. 
034.//轮播图图片数量
035.private final static int IMAGE_COUNT = 5;
036.//自动轮播的时间间隔
037.private final static int TIME_INTERVAL = 5;
038.//自动轮播启用开关
039.private final static boolean isAutoPlay = true;
040. 
041.//自定义轮播图的资源ID
042.private int[] imagesResIds;
043.//放轮播图片的ImageView 的list
044.private List<ImageView> imageViewsList;
045.//放圆点的View的list
046.private List<View> dotViewsList;
047. 
048.private ViewPager viewPager;
049.//当前轮播页
050.private int currentItem  = 0;
051.//定时任务
052.private ScheduledExecutorService scheduledExecutorService;
053.//Handler
054.private Handler handler = new Handler(){
055. 
056.@Override
057.public void handleMessage(Message msg) {
058.// TODO Auto-generated method stub
059.super.handleMessage(msg);
060.viewPager.setCurrentItem(currentItem);
061.}
062. 
063.};
064. 
065.public SlideShowView(Context context) {
066.this(context,null);
067.// TODO Auto-generated constructor stub
068.}
069.public SlideShowView(Context context, AttributeSet attrs) {
070.this(context, attrs, 0);
071.// TODO Auto-generated constructor stub
072.}
073.public SlideShowView(Context context, AttributeSet attrs, int defStyle) {
074.super(context, attrs, defStyle);
075.// TODO Auto-generated constructor stub
076.initData();
077.initUI(context);
078.if(isAutoPlay){
079.startPlay();
080.}
081. 
082.}
083./**
084.* 开始轮播图切换
085.*/
086.private void startPlay(){
087.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
088.scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 14, TimeUnit.SECONDS);
089.}
090./**
091.* 停止轮播图切换
092.*/
093.private void stopPlay(){
094.scheduledExecutorService.shutdown();
095.}
096./**
097.* 初始化相关Data
098.*/
099.private void initData(){
100.imagesResIds = new int[]{
101.R.drawable.pic1,
102.R.drawable.pic2,
103.R.drawable.pic3,
104.R.drawable.pic4,
105.R.drawable.pic5,
106. 
107.};
108.imageViewsList = new ArrayList<ImageView>();
109.dotViewsList = new ArrayList<View>();
110. 
111.}
112./**
113.* 初始化Views等UI
114.*/
115.private void initUI(Context context){
116.LayoutInflater.from(context).inflate(R.layout.layout_slideshow, thistrue);
117.for(int imageID : imagesResIds){
118.ImageView view =  new ImageView(context);
119.view.setImageResource(imageID);
120.view.setScaleType(ScaleType.FIT_XY);
121.imageViewsList.add(view);
122.}
123.dotViewsList.add(findViewById(R.id.v_dot1));
124.dotViewsList.add(findViewById(R.id.v_dot2));
125.dotViewsList.add(findViewById(R.id.v_dot3));
126.dotViewsList.add(findViewById(R.id.v_dot4));
127.dotViewsList.add(findViewById(R.id.v_dot5));
128. 
129.viewPager = (ViewPager) findViewById(R.id.viewPager);
130.viewPager.setFocusable(true);
131. 
132.viewPager.setAdapter(new MyPagerAdapter());
133.viewPager.setOnPageChangeListener(new MyPageChangeListener());
134.}
135. 
136./**
137.* 填充ViewPager的页面适配器
138.* @author caizhiming
139.*/
140.private class MyPagerAdapter  extends PagerAdapter{
141. 
142.@Override
143.public void destroyItem(View container, int position, Object object) {
144.// TODO Auto-generated method stub
145.//((ViewPag.er)container).removeView((View)object);
146.((ViewPager)container).removeView(imageViewsList.get(position));
147.}
148. 
149.@Override
150.public Object instantiateItem(View container, int position) {
151.// TODO Auto-generated method stub
152.((ViewPager)container).addView(imageViewsList.get(position));
153.return imageViewsList.get(position);
154.}
155. 
156.@Override
157.public int getCount() {
158.// TODO Auto-generated method stub
159.return imageViewsList.size();
160.}
161. 
162.@Override
163.public boolean isViewFromObject(View arg0, Object arg1) {
164.// TODO Auto-generated method stub
165.return arg0 == arg1;
166.}
167.@Override
168.public void restoreState(Parcelable arg0, ClassLoader arg1) {
169.// TODO Auto-generated method stub
170. 
171.}
172. 
173.@Override
174.public Parcelable saveState() {
175.// TODO Auto-generated method stub
176.return null;
177.}
178. 
179.@Override
180.public void startUpdate(View arg0) {
181.// TODO Auto-generated method stub
182. 
183.}
184. 
185.@Override
186.public void finishUpdate(View arg0) {
187.// TODO Auto-generated method stub
188. 
189.}
190. 
191.}
192./**
193.* ViewPager的监听器
194.* 当ViewPager中页面的状态发生改变时调用
195.* @author caizhiming
196.*/
197.private class MyPageChangeListener implements OnPageChangeListener{
198. 
199.boolean isAutoPlay = false;
200. 
201.@Override
202.public void onPageScrollStateChanged(int arg0) {
203.// TODO Auto-generated method stub
204.switch (arg0) {
205.case 1:// 手势滑动,空闲中
206.isAutoPlay = false;
207.break;
208.case 2:// 界面切换中
209.isAutoPlay = true;
210.break;
211.case 0:// 滑动结束,即切换完毕或者加载完毕
212.// 当前为最后一张,此时从右向左滑,则切换到第一张
213.if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() - 1 && !isAutoPlay) {
214.viewPager.setCurrentItem(0);
215.}
216.// 当前为第一张,此时从左向右滑,则切换到最后一张
217.else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {
218.viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 1);
219.}
220.break;
221.}
222.}
223. 
224.@Override
225.public void onPageScrolled(int arg0, float arg1, int arg2) {
226.// TODO Auto-generated method stub
227. 
228.}
229. 
230.@Override
231.public void onPageSelected(int pos) {
232.// TODO Auto-generated method stub
233. 
234.currentItem = pos;
235.for(int i=0;i < dotViewsList.size();i++){
236.if(i == pos){
237.((View)dotViewsList.get(pos)).setBackgroundResource(R.drawable.dot_black);
238.}else {
239.((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.dot_white);
240.}
241.}
242.}
243. 
244.}
245. 
246./**
247.*执行轮播图切换任务
248.*@author caizhiming
249.*/
250.private class SlideShowTask implements Runnable{
251. 
252.@Override
253.public void run() {
254.// TODO Auto-generated method stub
255.synchronized (viewPager) {
256.currentItem = (currentItem+1)%imageViewsList.size();
257.handler.obtainMessage().sendToTarget();
258.}
259.}
260. 
261.}
262./**
263.* 销毁ImageView资源,回收内存
264.* @author caizhiming
265.*/
266.private void destoryBitmaps() {
267. 
268.for (int i = 0; i < IMAGE_COUNT; i++) {
269.ImageView imageView = imageViewsList.get(i);
270.Drawable drawable = imageView.getDrawable();
271.if (drawable != null) {
272.//解除drawable对view的引用
273.drawable.setCallback(null);
274.}
275.}
276.}
277. 
278.}

如何引用上面自定义的轮播图效果视图View呢?其实很引用普通的View类似,实现如下:

view sourceprint?
1.<com.czm.customview.SlideShowView
2.android:id="@+id/slideshowView"
3.android:layout_width="335dp"
4.android:layout_height="120dp"
5.android:layout_centerHorizontal="true"
6./>
 
 
转自:http://www.it165.net/pro/html/201406/16227.html