Android開發之ViewPager實現輪播圖(輪播廣告)效果的自定義View---轉

最近開發中須要作一個相似京東首頁那樣的廣告輪播效果,因而採用ViewPager本身自定義了一個輪播圖效果的View。html

主要原理就是利用定時任務器定時切換ViewPager的頁面。java

主頁面佈局實現以下:android

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>

輪播效果視圖類代碼實現以下:ide

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相似,實現以下:佈局

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
相關文章
相關標籤/搜索