我是靠谱客的博主 温暖小蝴蝶,这篇文章主要介绍Android广告页循环播放,现在分享给大家,希望可以做个参考。

 

  摘要:项目要求做一个广告页,实现几秒更换一次广告页,下方还有指示第几张广告页,同样也支持手动左滑或右滑。

 

  1.准备好粘贴5个有关广告页的类。

    ①BaseViewPager==>自定义高度的ViewPager

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1 public class BaseViewPager extends ViewPager { 2 private boolean scrollable = true; 3 4 public BaseViewPager(Context context) { 5 super(context); 6 } 7 8 public BaseViewPager(Context context, AttributeSet attrs) { 9 super(context, attrs); 10 } 11 12 /** 13 * 设置viewpager是否可以滚动 14 * 15 * @param enable 16 */ 17 public void setScrollable(boolean enable) { 18 scrollable = enable; 19 } 20 21 @Override 22 public boolean onInterceptTouchEvent(MotionEvent event) { 23 if (scrollable) { 24 return super.onInterceptTouchEvent(event); 25 } else { 26 return false; 27 } 28 } 29 }
View Code

 

    ②CycleViewPager==>实现可循环、可轮播的viewPager

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
1 @SuppressLint("NewApi") 2 public class CycleViewPager extends Fragment implements OnPageChangeListener { 3 4 private List<ImageView> imageViews = new ArrayList<ImageView>(); 5 private ImageView[] indicators; 6 private FrameLayout viewPagerFragmentLayout; 7 private LinearLayout indicatorLayout; // 指示器 8 private BaseViewPager viewPager; 9 private BaseViewPager parentViewPager; 10 private ViewPagerAdapter adapter; 11 private CycleViewPagerHandler handler; 12 private int time = 5000; // 默认轮播时间 13 private int currentPosition = 0; // 轮播当前位置 14 private boolean isScrolling = false; // 滚动框是否滚动着 15 private boolean isCycle = false; // 是否循环 16 private boolean isWheel = false; // 是否轮播 17 private long releaseTime = 0; // 手指松开、页面不滚动时间,防止手机松开后短时间进行切换 18 private int WHEEL = 100; // 转动 19 private int WHEEL_WAIT = 101; // 等待 20 private ImageCycleViewListener mImageCycleViewListener; 21 private List<MyImage> infos; 22 23 @Override 24 public View onCreateView(LayoutInflater inflater, ViewGroup container, 25 Bundle savedInstanceState) { 26 View view = LayoutInflater.from(getActivity()).inflate( 27 R.layout.view_cycle_viewpager_contet, null); 28 29 viewPager = (BaseViewPager) view.findViewById(R.id.viewPager); 30 indicatorLayout = (LinearLayout) view.findViewById(R.id.layout_viewpager_indicator);//就是那个白点吧 31 viewPagerFragmentLayout = (FrameLayout) view.findViewById(R.id.layout_viewager_content); 32 33 handler = new CycleViewPagerHandler(getActivity()) { 34 35 @Override 36 public void handleMessage(Message msg) { 37 super.handleMessage(msg); 38 if (msg.what == WHEEL && imageViews.size() != 0) { 39 if (!isScrolling) { 40 int max = imageViews.size() + 1; 41 int position = (currentPosition + 1) % imageViews.size(); 42 viewPager.setCurrentItem(position, true); 43 if (position == max) { // 最后一页时回到第一页 44 viewPager.setCurrentItem(1, false); 45 } 46 } 47 48 releaseTime = System.currentTimeMillis(); 49 handler.removeCallbacks(runnable); 50 handler.postDelayed(runnable, time); 51 return; 52 } 53 if (msg.what == WHEEL_WAIT && imageViews.size() != 0) { 54 handler.removeCallbacks(runnable); 55 handler.postDelayed(runnable, time); 56 } 57 } 58 }; 59 60 return view; 61 } 62 63 public void setData(List<ImageView> views, List<MyImage> list, ImageCycleViewListener listener) { 64 setData(views, list, listener, 0); 65 } 66 67 /** 68 * 初始化viewpager 69 * 70 * @param views 71 * 要显示的views 72 * @param showPosition 73 * 默认显示位置 74 */ 75 public void setData(List<ImageView> views, List<MyImage> list, ImageCycleViewListener listener, int showPosition) { 76 mImageCycleViewListener = listener; 77 infos = list; 78 this.imageViews.clear(); 79 80 if (views.size() == 0) { 81 viewPagerFragmentLayout.setVisibility(View.GONE); 82 return; 83 } 84 85 for (ImageView item : views) { 86 this.imageViews.add(item); 87 } 88 89 int ivSize = views.size(); 90 91 // 设置指示器 92 indicators = new ImageView[ivSize]; 93 if (isCycle) 94 indicators = new ImageView[ivSize - 2]; 95 indicatorLayout.removeAllViews(); 96 for (int i = 0; i < indicators.length; i++) { 97 View view = LayoutInflater.from(getActivity()).inflate( 98 R.layout.view_cycle_viewpager_indicator, null); 99 indicators[i] = (ImageView) view.findViewById(R.id.image_indicator); 100 indicatorLayout.addView(view); 101 } 102 103 adapter = new ViewPagerAdapter(); 104 105 // 默认指向第一项,下方viewPager.setCurrentItem将触发重新计算指示器指向 106 setIndicator(0); 107 108 viewPager.setOffscreenPageLimit(3); 109 viewPager.setOnPageChangeListener(this); 110 viewPager.setAdapter(adapter); 111 if (showPosition < 0 || showPosition >= views.size()) 112 showPosition = 0; 113 if (isCycle) { 114 showPosition = showPosition + 1; 115 } 116 viewPager.setCurrentItem(showPosition); 117 118 } 119 120 /** 121 * 设置指示器居中,默认指示器在右方 122 */ 123 public void setIndicatorCenter() { 124 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( 125 RelativeLayout.LayoutParams.WRAP_CONTENT, 126 RelativeLayout.LayoutParams.WRAP_CONTENT); 127 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 128 params.addRule(RelativeLayout.CENTER_HORIZONTAL); 129 indicatorLayout.setLayoutParams(params); 130 } 131 /** 132 * 是否循环,默认不开启,开启前,请将views的最前面与最后面各加入一个视图,用于循环 133 * 134 * @param isCycle 135 * 是否循环 136 */ 137 public void setCycle(boolean isCycle) { 138 this.isCycle = isCycle; 139 } 140 141 /** 142 * 是否处于循环状态 143 * 144 * @return 145 */ 146 public boolean isCycle() { 147 return isCycle; 148 } 149 150 /** 151 * 设置是否轮播,默认不轮播,轮播一定是循环的 152 * 153 * @param isWheel 154 */ 155 public void setWheel(boolean isWheel) { 156 this.isWheel = isWheel; 157 isCycle = true; 158 if (isWheel) { 159 handler.postDelayed(runnable, time); 160 } 161 } 162 163 /** 164 * 是否处于轮播状态 165 * 166 * @return 167 */ 168 public boolean isWheel() { 169 return isWheel; 170 } 171 172 final Runnable runnable = new Runnable() { 173 174 @Override 175 public void run() { 176 if (getActivity() != null && !getActivity().isFinishing() 177 && isWheel) { 178 long now = System.currentTimeMillis(); 179 // 检测上一次滑动时间与本次之间是否有触击(手滑动)操作,有的话等待下次轮播 180 if (now - releaseTime > time - 500) { 181 handler.sendEmptyMessage(WHEEL); 182 } else { 183 handler.sendEmptyMessage(WHEEL_WAIT); 184 } 185 } 186 } 187 }; 188 189 /** 190 * 释放指示器高度,可能由于之前指示器被限制了高度,此处释放 191 */ 192 public void releaseHeight() { 193 getView().getLayoutParams().height = RelativeLayout.LayoutParams.MATCH_PARENT; 194 refreshData(); 195 } 196 197 /** 198 * 设置轮播暂停时间,即没多少秒切换到下一张视图.默认5000ms 199 * 200 * @param time 201 * 毫秒为单位 202 */ 203 public void setTime(int time) { 204 this.time = time; 205 } 206 207 /** 208 * 刷新数据,当外部视图更新后,通知刷新数据 209 */ 210 public void refreshData() { 211 if (adapter != null) 212 adapter.notifyDataSetChanged(); 213 } 214 215 /** 216 * 隐藏CycleViewPager 217 */ 218 public void hide() { 219 viewPagerFragmentLayout.setVisibility(View.GONE); 220 } 221 222 /** 223 * 返回内置的viewpager 224 * 225 * @return viewPager 226 */ 227 public BaseViewPager getViewPager() { 228 return viewPager; 229 } 230 231 /** 232 * 页面适配器 返回对应的view 233 * 234 * @author Yuedong Li 235 * 236 */ 237 private class ViewPagerAdapter extends PagerAdapter { 238 239 @Override 240 public int getCount() { 241 return imageViews.size(); 242 } 243 244 @Override 245 public boolean isViewFromObject(View arg0, Object arg1) { 246 return arg0 == arg1; 247 } 248 249 @Override 250 public void destroyItem(ViewGroup container, int position, Object object) { 251 container.removeView((View) object); 252 } 253 254 @Override 255 public View instantiateItem(ViewGroup container, final int position) { 256 ImageView v = imageViews.get(position); 257 if (mImageCycleViewListener != null) { 258 v.setOnClickListener(new OnClickListener() { 259 260 @Override 261 public void onClick(View v) { 262 mImageCycleViewListener.onImageClick(infos.get(currentPosition - 1), currentPosition, v); 263 } 264 }); 265 } 266 container.addView(v); 267 return v; 268 } 269 270 @Override 271 public int getItemPosition(Object object) { 272 return POSITION_NONE; 273 } 274 } 275 276 @Override 277 public void onPageScrollStateChanged(int arg0) { 278 if (arg0 == 1) { // viewPager在滚动 279 isScrolling = true; 280 return; 281 } else if (arg0 == 0) { // viewPager滚动结束 282 if (parentViewPager != null) 283 parentViewPager.setScrollable(true); 284 285 releaseTime = System.currentTimeMillis(); 286 287 viewPager.setCurrentItem(currentPosition, false); 288 289 } 290 isScrolling = false; 291 } 292 293 @Override 294 public void onPageScrolled(int arg0, float arg1, int arg2) { 295 } 296 297 @Override 298 public void onPageSelected(int arg0) { 299 int max = imageViews.size() - 1; 300 int position = arg0; 301 currentPosition = arg0; 302 if (isCycle) { 303 if (arg0 == 0) { 304 currentPosition = max - 1; 305 } else if (arg0 == max) { 306 currentPosition = 1; 307 } 308 position = currentPosition - 1; 309 } 310 setIndicator(position); 311 } 312 313 /** 314 * 设置viewpager是否可以滚动 315 * 316 * @param enable 317 */ 318 public void setScrollable(boolean enable) { 319 viewPager.setScrollable(enable); 320 } 321 322 /** 323 * 返回当前位置,循环时需要注意返回的position包含之前在views最前方与最后方加入的视图,即当前页面试图在views集合的位置 324 * 325 * @return 326 */ 327 public int getCurrentPostion() { 328 return currentPosition; 329 } 330 331 /** 332 * 设置指示器 333 * 334 * @param selectedPosition 335 * 默认指示器位置 336 */ 337 private void setIndicator(int selectedPosition) { 338 for (int i = 0; i < indicators.length; i++) { 339 indicators[i].setBackgroundResource(R.mipmap.icon_point); 340 } 341 if (indicators.length > selectedPosition) 342 indicators[selectedPosition].setBackgroundResource(R.mipmap.icon_point_pre); 343 } 344 345 /** 346 * 如果当前页面嵌套在另一个viewPager中,为了在进行滚动时阻断父ViewPager滚动,可以 阻止父ViewPager滑动事件 347 * 父ViewPager需要实现ParentViewPager中的setScrollable方法 348 */ 349 public void disableParentViewPagerTouchEvent(BaseViewPager parentViewPager) { 350 if (parentViewPager != null) 351 parentViewPager.setScrollable(false); 352 } 353 354 355 /** 356 * 轮播控件的监听事件 357 * 358 * @author minking 359 */ 360 public static interface ImageCycleViewListener { 361 362 /** 363 * 单击图片事件 364 * 365 * @param position 366 * @param imageView 367 */ 368 public void onImageClick(MyImage info, int postion, View imageView); 369 } 370 }
View Code

 

       ③CycleViewPagerHandler==>为了防止内存泄漏,定义外部类,防止内部类对外部类的引用

复制代码
1
2
3
4
5
6
7
1 public class CycleViewPagerHandler extends Handler { 2 Context context; 3 4 public CycleViewPagerHandler(Context context) { 5 this.context = context; 6 } 7 }
View Code

 

        ④ViewFactory==>创建ImageView工厂,获取ImageView视图的同时加载显示url

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1 public class ViewFactory { 2 3 /** 4 * 获取ImageView视图的同时加载显示url 5 * 6 * @param 7 * @return 8 */ 9 public static ImageView getImageView(Context context, String url) { 10 ImageView imageView = (ImageView)LayoutInflater.from(context).inflate( 11 R.layout.view_banner, null); 12 ImageLoader.getInstance().displayImage(url, imageView);//最核心的部分 13 return imageView; 14 } 15 }
View Code

 

         ⑤MyImage==>这是广告页的bean类

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1 class MyImage { 2 3 var link: String? = null 4 var image:String?=null 5 var title:String?=null 6 7 constructor():super() 8 constructor(image: String) : super() { 9 this.image = image 10 } 11 constructor(image:String,link:String,title:String){ 12 this.image=image 13 this.link=link 14 this.title=title 15 } 16 17 override fun toString(): String { 18 return "MyImage[link=$link,image=$image,title=$title]" 19 } 20 }
View Code

 

   

   2.从服务器中拿到图片的链接地址,一般广告页都是从服务器拿到的数据。本地的也可以,而且更加简单了。我就拿前者举例吧。

    下面的代码是我自己的一个请求,里面有很多东西都是自己定义的东西。 

    如:LogUtils.d_debugprint()是自己封装好的一个日志输出的类。

      Constant也是自己封装好的常量。

      HttpUtil.httpPost也是自己封装的网络请求的类。

      JsonUtil.get_key_string也是自己封装Json解析的类。

      MyImage是自己定义的一个Bean类。

      Toasty是引用的第三方库toast的类,用来提示用户。

      initialize()是自己初始化广告页,后面第三步就是写这个函数了。

    

      解释清楚之后,请求的函数如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
1 private fun getADfromServer() { 2 var urlPath = "" 3 var sign = "" 4 val encode = Constant.ENCODE 5 val school = Constant.SCHOOLDEFULT 6 if (LogUtils.APP_IS_DEBUG) { 7 urlPath = Constant.BASEURLFORTEST + Constant.School_AD 8 sign = MD5Util.md5(Constant.SALTFORTEST) 9 } else { 10 urlPath = Constant.BASEURLFORRELEASE + Constant.School_AD 11 sign = MD5Util.md5(Constant.SALTFORRELEASE) 12 } 13 val params = mapOf<String, Any?>("school" to school,"sign" to sign) 14 LogUtils.d_debugprint(TAG, Constant.TOSERVER + urlPath + "n提交的map=" + params.toString()) 15 Thread(Runnable { 16 getAdfromServer= HttpUtil.httpPost(urlPath,params,encode) 17 // LogUtils.d_debugprint(TAG,Constant.GETDATAFROMSERVER+getAdfromServer) 18 val getCode:String 19 var msg:String?=null 20 var result:String 21 var getData:List<Map<String,Any?>> 22 getCode= JsonUtil.get_key_string(Constant.Server_Code,getAdfromServer!!) 23 if(Constant.RIGHTCODE.equals(getCode)) { 24 handler_result1.post { 25 msg = JsonUtil.get_key_string(Constant.Server_Msg, getAdfromServer!!) 26 result = JsonUtil.get_key_string(Constant.Server_Result, getAdfromServer!!) 27 getData = JsonUtil.getListMap("data", result)//=====这里可能发生异常 28 LogUtils.d_debugprint(TAG, "json解析出来的对象是=" + getData.toString()) 29 if (getData != null&&getData.size>0) { 30 for (i in getData.indices) { 31 val myImage=MyImage() 32 if(getData[i].getValue("link").toString()!=null&&getData[i].getValue("image").toString()!=null&&getData[i].getValue("title").toString()!=null) { 33 myImage.link = getData[i].getValue("link").toString() 34 myImage.image = getData[i].getValue("image").toString() 35 myImage.title = getData[i].getValue("title").toString() 36 myImageList.add(myImage)//=====这里保存了所有广告信息 37 }else{ 38 Toasty.error(context,Constant.SERVERBROKEN).show() 39 } 40 } 41 initialize() //初始化顶部导航栏 42 }else{ 43 val myImage=MyImage() 44 myImage.link="" 45 myImage.image="" 46 myImage.title="" 47 myImageList.add(myImage) 48 //Toasty.error(context,Constant.SERVERBROKEN).show() 49 } 50 } 51 } 52 }).start() 53 }
View Code

 

 

   3.然后就是initialize()函数了

    说明一下==>>

    myImageOverAD是覆盖在广告页上的一张默认图片,如果没有网,或者请求失败的时候,将显示这张图片。

    cycleViewPager是广告栏中的一个叫fragment的布局。

    views是广告栏的一个ArrayList<ImageView>(),可以动态添加ImageView

    mAdCycleViewListener是广告页点击的监听器,第四步会详细讲。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1 @SuppressLint("NewApi") 2 private fun initialize() { 3 myImageOverAD!!.visibility=View.GONE 4 cycleViewPager = activity.fragmentManager.findFragmentById(R.id.oneFm_fragment_cycle_viewpager_content) as CycleViewPager 5 6 views.add(ViewFactory.getImageView(context, myImageList[myImageList.size - 1].image)) // 将最后一个ImageView添加进来 7 for (i in myImageList.indices) { 8 views.add(ViewFactory.getImageView(context, myImageList[i].image)) 9 } 10 views.add(ViewFactory.getImageView(context, myImageList[0].image)) // 将第一个ImageView添加进来 11 cycleViewPager!!.isCycle = true // 设置循环,在调用setData方法前调用 12 cycleViewPager!!.setData(views, myImageList, mAdCycleViewListener) // 在加载数据前设置是否循环 13 cycleViewPager!!.isWheel = true //设置轮播 14 cycleViewPager!!.setTime(5000) // 设置轮播时间,默认5000ms 15 cycleViewPager!!.setIndicatorCenter() //设置圆点指示图标组居中显示,默认靠右 16 }
View Code

 

 

   4.然后是mAdCycleViewListener监听器的实现了。

    说明一下==>>

    ADWebView是点击广告页要调整的webView。

    R.anim.slide_left_out是一个从左边出去的动画。

    源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1 private val mAdCycleViewListener = CycleViewPager.ImageCycleViewListener { info, position, imageView -> 2 var position = position 3 if (cycleViewPager!!.isCycle) { 4 position = position - 1 5 //Toasty.info(context,"标题:"+info.title+ "n链接:" + info.link).show() 6 7 val bundle=Bundle() 8 bundle.putString("title",info.title) 9 bundle.putString("link",info.link) 10 val intent:Intent=Intent(context,ADWebView::class.java) 11 intent.putExtras(bundle) 12 startActivity(intent) 13 activity.overridePendingTransition(0,R.anim.slide_left_out) 14 } 15 }
View Code

 

   5.广告页的布局代码差点忘记了。

      说明一下==>>

    这里的fragment才是主角,下方的ImageView是覆盖在广告页上的一张默认图片,在没有网获取没有成功请求到服务器的时候显示的图片。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1 <RelativeLayout 2 android:layout_width="match_parent" 3 android:layout_height="350pt"> 4 5 <fragment 6 android:id="@+id/oneFm_fragment_cycle_viewpager_content" 7 android:name="com.guangdamiao.www.mew_android_debug.banner.CycleViewPager" 8 android:layout_width="match_parent" 9 android:layout_height="350pt" 10 /> 11 12 <ImageView 13 android:id="@+id/oneFm_fragment_cycle_viewpager_content_over" 14 android:layout_width="match_parent" 15 android:layout_height="360pt" 16 android:src="@drawable/one_overad" 17 android:visibility="visible" 18 android:scaleType="centerCrop" 19 /> 20 21 </RelativeLayout>
View Code

 

 

  效果如下:

  

 

  

 

转载于:https://www.cnblogs.com/Jason-Jan/p/7691809.html

最后

以上就是温暖小蝴蝶最近收集整理的关于Android广告页循环播放的全部内容,更多相关Android广告页循环播放内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部