本文实例为大家分享了Android实现BannerLayout图文轮播功能的具体代码,供大家参考,具体内容如下
实现效果图:
(1)在biuld.gradle文件加入
1
|
compile 'com.ydevelop:bannerlayout:1.0.4' |
(2)创建BannerLayout文件
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
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Interpolator; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.os.Handler; import android.os.Message; import android.support.annotation.NonNull; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Scroller; import android.widget.TextView; import com.bumptech.glide.Glide; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class BannerLayout extends RelativeLayout { private ViewPager mViewPager; // 轮播容器 // 指示器(圆点)容器 private LinearLayout indicatorContainer; private Drawable unSelectedDrawable; private Drawable selectedDrawable; private int WHAT_AUTO_PLAY = 1000 ; private boolean isAutoPlay = true ; // 自动轮播 private int itemCount; private int selectedIndicatorColor = 0xffff0000 ; private int unSelectedIndicatorColor = 0x88888888 ; private int titleBGColor = 0X33000000 ; private int titleColor = 0Xffffffff ; private Shape indicatorShape = Shape.oval; private int selectedIndicatorHeight = 20 ; private int selectedIndecatorWidth = 20 ; private int unSelectedIndicatorHeight = 20 ; private int unSelectedIndecatorWidth = 20 ; private int autoPlayDuration = 4000 ; private int scrollDuration = 900 ; // 指示器中点和点之间的距离 private int indicatorSpace = 10 ; // 指示器整体的设置 private int indicatorMargin = 20 ; private static final int titlePadding = 20 ; private int defaultImage; private enum Shape { // 矩形 或 圆形的指示器 rect, oval } private OnBannerItemClickListener mOnBannerItemClickListener; private Handler mHandler = new Handler( new Handler.Callback() { @Override public boolean handleMessage(Message msg) { if (msg.what == WHAT_AUTO_PLAY) { if (mViewPager != null ) { mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1 , true ); mHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration); } } return false ; } }); public BannerLayout(Context context) { super (context); init( null , 0 ); } public BannerLayout(Context context, AttributeSet attrs) { super (context, attrs); init(attrs, 0 ); } public BannerLayout(Context context, AttributeSet attrs, int defStyleAttr) { super (context, attrs, defStyleAttr); init(attrs, defStyleAttr); } private void init(AttributeSet attrs, int defStyleAttr) { TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.BannerLayoutStyle, defStyleAttr, 0 ); selectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_selectedIndicatorColor, selectedIndicatorColor); unSelectedIndicatorColor = array.getColor(R.styleable.BannerLayoutStyle_unSelectedIndicatorColor, unSelectedIndicatorColor); titleBGColor = array.getColor(R.styleable.BannerLayoutStyle_titleBGColor, titleBGColor); titleColor = array.getColor(R.styleable.BannerLayoutStyle_titleColor, titleColor); int shape = array.getInt(R.styleable.BannerLayoutStyle_indicatorShape, Shape.oval.ordinal()); for (Shape shape1 : Shape.values()) { if (shape1.ordinal() == shape) { indicatorShape = shape1; break ; } } selectedIndecatorWidth = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorWidth, selectedIndecatorWidth); selectedIndicatorHeight = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_selectedIndicatorHeight, selectedIndicatorHeight); unSelectedIndecatorWidth = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorWidth, unSelectedIndecatorWidth); unSelectedIndicatorHeight = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_unSelectedIndicatorHeight, unSelectedIndicatorHeight); indicatorSpace = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_indicatorSpace, indicatorSpace); indicatorMargin = ( int ) array.getDimension(R.styleable.BannerLayoutStyle_indicatorMargin, indicatorMargin); autoPlayDuration = array.getInt(R.styleable.BannerLayoutStyle_autoPlayDuration, autoPlayDuration); scrollDuration = array.getInt(R.styleable.BannerLayoutStyle_scrollDuration, scrollDuration); isAutoPlay = array.getBoolean(R.styleable.BannerLayoutStyle_isAutoPlay, isAutoPlay); defaultImage = array.getResourceId(R.styleable.BannerLayoutStyle_defaultImage, defaultImage); array.recycle(); LayerDrawable unSelectedLayerDrawable; LayerDrawable selectedLayerDrawable; GradientDrawable unSelectedGradientDrawable = new GradientDrawable(); GradientDrawable selectedGradientDtawbale = new GradientDrawable(); switch (indicatorShape) { case rect: unSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE); selectedGradientDtawbale.setShape(GradientDrawable.RECTANGLE); break ; case oval: unSelectedGradientDrawable.setShape(GradientDrawable.OVAL); selectedGradientDtawbale.setShape(GradientDrawable.OVAL); break ; } unSelectedGradientDrawable.setColor(unSelectedIndicatorColor); unSelectedGradientDrawable.setSize(unSelectedIndecatorWidth, unSelectedIndicatorHeight); unSelectedLayerDrawable = new LayerDrawable( new Drawable[]{unSelectedGradientDrawable}); unSelectedDrawable = unSelectedLayerDrawable; selectedGradientDtawbale.setColor(selectedIndicatorColor); selectedGradientDtawbale.setSize(selectedIndecatorWidth, selectedIndicatorHeight); selectedLayerDrawable = new LayerDrawable( new Drawable[]{selectedGradientDtawbale}); selectedDrawable = selectedLayerDrawable; } /** * 添加本地图片 * * @param viewRes 图片id集合 * @param titles 标题集合,可空 */ public void setViewRes(List<Integer> viewRes, List<String> titles) { List<View> views = new ArrayList<>(); itemCount = viewRes.size(); if (titles != null && titles.size() != viewRes.size()) { throw new IllegalStateException( "views.size() != titles.size()" ); } // 把数量拼凑到三个以上 if (itemCount < 1 ) { throw new IllegalStateException( "item count not equal zero" ); } else if (itemCount < 2 ) { views.add(getFrameLayoutView(viewRes.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(viewRes.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(viewRes.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); } else if (itemCount < 3 ) { views.add(getFrameLayoutView(viewRes.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(viewRes.get( 1 ), titles != null ? titles.get( 1 ) : null , 1 )); views.add(getFrameLayoutView(viewRes.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(viewRes.get( 1 ), titles != null ? titles.get( 1 ) : null , 1 )); } else { for ( int i = 0 ; i < viewRes.size(); i++) { views.add(getFrameLayoutView(viewRes.get(i), titles != null ? titles.get(i) : null , i)); } } setViews(views); } //添加网络图片路径 public void setViewUrls(Context context,List<String> urls, List<String> titles) { List<View> views = new ArrayList<>(); itemCount = urls.size(); Log.e( "TAG" ,titles.size()+ "---90---" +urls.size()); if (titles != null && titles.size() != itemCount) { throw new IllegalStateException( "views.size() != titles.size()" ); } //主要是解决当item为小于3个的时候滑动有问题,这里将其拼凑成3个以上 if (itemCount < 1 ) { //当item个数0 throw new IllegalStateException( "item count not equal zero" ); } else if (itemCount < 2 ) { //当item个数为1 views.add(getFrameLayoutView(context,urls.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(context,urls.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(context,urls.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); } else if (itemCount < 3 ) { //当item个数为2 views.add(getFrameLayoutView(context,urls.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(context,urls.get( 1 ), titles != null ? titles.get( 1 ) : null , 1 )); views.add(getFrameLayoutView(context,urls.get( 0 ), titles != null ? titles.get( 0 ) : null , 0 )); views.add(getFrameLayoutView(context,urls.get( 1 ), titles != null ? titles.get( 1 ) : null , 1 )); } else { for ( int i = 0 ; i < urls.size(); i++) { views.add(getFrameLayoutView(context,urls.get(i), titles != null ? titles.get(i) : null , i)); } } setViews(views); } private void setViews( final List<View> views) { mViewPager = new ViewPager(getContext()); addView(mViewPager); setSliderTransformDuration(scrollDuration); //初始化indicatorContainer indicatorContainer = new LinearLayout(getContext()); indicatorContainer.setGravity(Gravity.CENTER_VERTICAL); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); // 设置 指示点的位置 ALIGN_PARENT_RIGHT表示居右 CENTER_HORIZONTAL表示居中 params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); //设置margin params.setMargins(indicatorMargin, indicatorMargin, indicatorMargin, indicatorMargin); //添加指示器容器布局到SliderLayout addView(indicatorContainer, params); //初始化指示器,并添加到指示器容器布局 for ( int i = 0 ; i < itemCount; i++) { ImageView indicator = new ImageView(getContext()); indicator.setLayoutParams( new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); indicator.setPadding(indicatorSpace, indicatorSpace, indicatorSpace, indicatorSpace); indicator.setImageDrawable(unSelectedDrawable); indicatorContainer.addView(indicator); } LoopPagerAdapter pagerAdapter = new LoopPagerAdapter(views); mViewPager.setAdapter(pagerAdapter); //设置当前item到Integer.MAX_VALUE中间的一个值,看起来像无论是往前滑还是往后滑都是ok的 //如果不设置,用户往左边滑动的时候已经划不动了 int targetItemPosition = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % itemCount; mViewPager.setCurrentItem(targetItemPosition); switchIndicator(targetItemPosition % itemCount); mViewPager.addOnPageChangeListener( new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected( int position) { switchIndicator(position % itemCount); } }); startAutoPlay(); } /** * 开始自动轮播 */ public void startAutoPlay() { stopAutoPlay(); // 避免重复消息 if (isAutoPlay) { mHandler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, autoPlayDuration); } @Override protected void onWindowVisibilityChanged( int visibility) { super .onWindowVisibilityChanged(visibility); if (visibility == VISIBLE) { startAutoPlay(); } else { stopAutoPlay(); } } /** * 停止自动轮播 */ public void stopAutoPlay() { if (isAutoPlay) { mHandler.removeMessages(WHAT_AUTO_PLAY); } } private void setSliderTransformDuration( int scrollDuration) { try { Field mScroller = ViewPager. class .getDeclaredField( "mScroller" ); mScroller.setAccessible( true ); FixedSpeedScroller fixedSpeedScroller = new FixedSpeedScroller(mViewPager.getContext(), null , scrollDuration); mScroller.set(mViewPager, fixedSpeedScroller); } catch (Exception e) { e.printStackTrace(); } } @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: stopAutoPlay(); break ; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: startAutoPlay(); break ; } return super .dispatchTouchEvent(ev); } /** * 切换指示器状态 * * @param currentPosition 当前位置 */ private void switchIndicator( int currentPosition) { for ( int i = 0 ; i < indicatorContainer.getChildCount(); i++) { ((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == currentPosition ? selectedDrawable : unSelectedDrawable); } } public void setOnBannerItemClickListener(OnBannerItemClickListener onBannerItemClickListener) { this .mOnBannerItemClickListener = onBannerItemClickListener; } @NonNull private FrameLayout getFrameLayoutView(Context context, String url, String title, final int position) { FrameLayout frameLayout = new FrameLayout(getContext()); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.gravity = Gravity.CENTER; ImageView imageView = new ImageView(getContext()); frameLayout.addView(imageView); frameLayout.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { if (mOnBannerItemClickListener != null ) { mOnBannerItemClickListener.onItemClick(position); } } }); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); if (defaultImage != 0 ){ Glide.with(getContext()).load(url).placeholder(defaultImage).centerCrop().into(imageView); } else { Glide.with(getContext()).load(url).centerCrop().into(imageView); } if (!TextUtils.isEmpty(title)) { TextView textView = new TextView(getContext()); textView.setText(title); textView.setTextColor(titleColor); textView.setPadding(titlePadding, titlePadding, titlePadding, titlePadding); textView.setBackgroundColor(titleBGColor); textView.getPaint().setFakeBoldText( true ); layoutParams.gravity = Gravity.BOTTOM; frameLayout.addView(textView, layoutParams); } return frameLayout; } @NonNull private FrameLayout getFrameLayoutView(Integer res, String title, final int position) { FrameLayout frameLayout = new FrameLayout(getContext()); FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.gravity = Gravity.CENTER; ImageView imageView = new ImageView(getContext()); frameLayout.addView(imageView); frameLayout.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { if (mOnBannerItemClickListener != null ) { mOnBannerItemClickListener.onItemClick(position); } } }); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); Glide.with(getContext()).load(res).centerCrop().into(imageView); if (!TextUtils.isEmpty(title)) { TextView textView = new TextView(getContext()); textView.setText(title); textView.setTextColor(titleColor); textView.setPadding(titlePadding, titlePadding, titlePadding, titlePadding); textView.setBackgroundColor(titleBGColor); textView.getPaint().setFakeBoldText( true ); layoutParams.gravity = Gravity.BOTTOM; frameLayout.addView(textView, layoutParams); } return frameLayout; } public interface OnBannerItemClickListener { void onItemClick( int position); } public class LoopPagerAdapter extends PagerAdapter { private List<View> views; public LoopPagerAdapter(List<View> views) { this .views = views; } @Override public int getCount() { //Integer.MAX_VALUE = 2147483647 return Integer.MAX_VALUE; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { if (views.size() > 0 ) { //position % view.size()是指虚拟的position会在[0,view.size())之间循环 View view = views.get(position % views.size()); if (container.equals(view.getParent())) { container.removeView(view); } container.addView(view); return view; } return null ; } @Override public void destroyItem(ViewGroup container, int position, Object object) { } } public class FixedSpeedScroller extends Scroller { private int mDuration = 1000 ; public FixedSpeedScroller(Context context) { super (context); } public FixedSpeedScroller(Context context, Interpolator interpolator) { super (context, (android.view.animation.Interpolator) interpolator); } public FixedSpeedScroller(Context context, Interpolator interpolator, int duration) { this (context, interpolator); mDuration = duration; @Override public void startScroll( int startX, int startY, int dx, int dy, int duration) { // Ignore received duration, use fixed one instead super .startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll( int startX, int startY, int dx, int dy) { // Ignore received duration, use fixed one instead super .startScroll(startX, startY, dx, dy, mDuration); } } } |
(3)MainAvtivity.java文件
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
|
import android.app.Activity; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import android.widget.ImageView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; /** * Created by lenovo on 2018/4/23. */ public class MainActivity extends Activity { private MyListView lv_zyb; private ImageView iv_zybfh; @Override protected void onCreate( @Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv_zybfh=(ImageView) findViewById(R.id.iv_zybfh); BannerLayout bannerLayout = (BannerLayout) findViewById(R.id.bannerzhuangyuanbang); List<String> urls = new ArrayList<>(); urls.add( "http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1404/02/c5/32731218_32731218_1396429876186.jpg" ); urls.add( "http://pic2.16pic.com/00/11/65/16pic_1165030_b.jpg" ); urls.add( "http://upload.17u.net/uploadpicbase/image/201708201147537103.jpg" ); urls.add( "http://img2.gzgov.gov.cn/gzsrmzf/dcgz/lyzx/rmjd/201709/W020170926622407643781.jpg" ); urls.add( "http://photocdn.sohu.com/20150324/Img410244363.jpg" ); urls.add( "http://pic4.40017.cn/scenery/destination/2017/01/10/11/SiTllI.jpg" ); List<String> titleas = new ArrayList<>(); titleas.add( "标题一" ); titleas.add( "标题二" ); titleas.add( "标题三" ); titleas.add( "标题四" ); titleas.add( "标题五" ); titleas.add( "标题六" ); if (bannerLayout != null ) { bannerLayout.setViewUrls( this ,urls, titleas); bannerLayout.setOnBannerItemClickListener( new BannerLayout.OnBannerItemClickListener() { @Override public void onItemClick( int position) { Toast.makeText(ZhuangyuanbangActivity. this , "position:" + position, Toast.LENGTH_SHORT).show(); } }); } } } |
(4)activity_main.xml文件,必须加红色这一句,否则app开头的会报错。还有红色的是包名,记得修改为自己项目的包名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:app = "http://schemas.android.com/apk/res-auto" android:orientation = "vertical" android:layout_width = "match_parent" android:layout_height = "match_parent" > < applwj.eduation.com.topeduation.BannerLayout android:id = "@+id/bannerzhuangyuanbang" android:layout_width = "match_parent" android:layout_height = "210dp" app:scrollDuration = "1000" app:autoPlayDuration = "3000" app:unSelectedIndicatorHeight = "10dp" app:unSelectedIndicatorWidth = "10dp" app:selectedIndicatorHeight = "10dp" app:selectedIndicatorWidth = "10dp" app:unSelectedIndicatorColor = "#99ffffff" app:selectedIndicatorColor = "#000000" app:isAutoPlay = "true" /> </ LinearLayout > |
demo下载:Android实现图文轮播功能
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/AWM_98K5520/article/details/80305359