本文实例为大家分享了Android自定义轮播图效果的具体代码,供大家参考,具体内容如下
概述
1、写一个布局,其中有ViewPager,TextView,LinearLayout.
- ViewPager:用来承载图片
- TextView:用来展示文字描述
- LinearLayout:用来展示指示器
2、自定义ConstraintLayout, 在该控件中处理页面切换逻辑等.
分析
1、获取自定义属性以及设置一些属性
复制代码
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
124public BannerY(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); initXmlParams(context, attrs, defStyleAttr); fixParams(); initListener(); initLists(); initImageLoader(); } /** * 初始化ImageLoader */ private void initImageLoader() { ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(mContext)); } /** * 将布局填充进BannerY,获取VP,TextView,LinearLayout控件 * * @param context */ private void initView(Context context) { mContext = context; LayoutInflater.from(context).inflate(R.layout.layout_banner, this); mVp = (ViewPager) findViewById(R.id.vp); mTvDesc = (TextView) findViewById(R.id.tv_desc); mLLPoint = (LinearLayout) findViewById(R.id.ll_point); } /** * 获取自定义属性 * * @param context * @param attrs * @param defStyleAttr */ private void initXmlParams(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerY, defStyleAttr, 0); mPointSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_size, 8); mPointBG = typedArray.getResourceId(R.styleable.BannerY_point_bg, R.drawable.point_selector); mInterval = typedArray.getInteger(R.styleable.BannerY_banner_interval, 2000); mTvBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_bottom_margin, 8); mPointBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_bottom_margin, 8); mDescColor = typedArray.getColor(R.styleable.BannerY_desc_color, Color.BLACK); mDescSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_size, 14); mScaleType = typedArray.getInt(R.styleable.BannerY_banner_scaletype, -1); typedArray.recycle(); } /** * 通过自定义属性调整指示器与文字描述位置 */ private void fixParams() { //描述控件 LayoutParams mTvDescLayoutParams = (LayoutParams) mTvDesc.getLayoutParams(); mTvDescLayoutParams.bottomMargin = (int) mTvBottomMargin; mTvDesc.setLayoutParams(mTvDescLayoutParams); mTvDesc.setTextColor(mDescColor); mTvDesc.getPaint().setTextSize(mDescSize); //指示器 LayoutParams mLLPointLayoutParams = (LayoutParams) mLLPoint.getLayoutParams(); mLLPointLayoutParams.bottomMargin = (int) mPointBottomMargin; mLLPoint.setLayoutParams(mLLPointLayoutParams); } /** * 创建数据源集合以及创建Handler对象 */ @SuppressLint("HandlerLeak") private void initLists() { mImageViewList = new ArrayList<>(); mDescList = new ArrayList<>(); mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); // 获取ViewPager当前展示图片的索引值 int currentItem = mVp.getCurrentItem(); // 切换到下一个图片 mVp.setCurrentItem(currentItem + 1); // 间隔一定时间发送一个消息,间隔时长由自定义属性值控制. mHandler.sendEmptyMessageDelayed(1, mInterval); } }; } /** * 为ViewPager设置滑动监听 */ private void initListener() { mVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { // ViewPager总共设置有Integer.MAX_VALUE个视图 // position取模,转换为mImageViewList对应的索引. int realPosition = position % mImageViewList.size(); if (mDescList.size() == mImageViewList.size()) { // 文字描述集合与图片集合长度相等,那么就为文字描述TextView展示对应的文字内容. String desc = mDescList.get(realPosition); mTvDesc.setText(desc); } else { if (BuildConfig.DEBUG) { Log.d(TAG, "文字集合和图片集合长度不相等"); } } // 上一个页面对应的指示器设置为没有选中 mLLPoint.getChildAt(prePosition).setEnabled(false); // 从装有指示器的LinearLayout中获得当前视图对应的指示器,然后设置指示器当前是选中,从而改变指示器颜色. mLLPoint.getChildAt(realPosition).setEnabled(true); prePosition = realPosition; } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_DRAGGING) {//正在滑动 // 手动触碰ViewPager,使之正在处于滑动状态,Handler就停止发送消息. isDragging = true; mHandler.removeCallbacksAndMessages(null); } if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {//空闲状态 // ViewPager手动滑动停止之后,重新开启Handler发送消息. mHandler.removeCallbacksAndMessages(null); mHandler.sendEmptyMessageDelayed(1, mInterval); } } }); }
2、设置图片源集合
复制代码
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/** * 设置图片源 * @param imagesRes * @param <T> */ public <T> void setImagesRes(ArrayList<T> imagesRes) { if (judgeLenght(imagesRes)) { mImageViewList.clear(); // 初始化图片列表 initImageList(imagesRes); // 创建Adapter mBannerAdapter = new BannerAdapter(mImageViewList); mVp.setAdapter(mBannerAdapter); // 设置ViewPager当前视图为中间位置, 因为ViewPager视图个数为Integer.MAX_VALUE(在ViewPagerAdapter中设置的). int position = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % mImageViewList.size(); // 设置当前ViewPager展示哪个视图 mVp.setCurrentItem(position); // 开启消息循环 mHandler.sendEmptyMessageDelayed(1, mInterval); if (mDescList.size() == mImageViewList.size()) { // 设置文字描述展示 mTvDesc.setText(mDescList.get(prePosition)); } } } /** * 初始化图片列表 */ private void initImageList(ArrayList imagesRes) { Class<?> imageResClass = imagesRes.get(0).getClass(); for (int i = 0; i < imagesRes.size(); i++) { // 创建ImageView ImageView imageView = createImageView(imagesRes, i, imageResClass); // 为ImageView设置点击事件 setImageViewListener(imageView); // 将ImageView添加进集合中 mImageViewList.add(imageView); //添加指示器 addPoint(i); } } /** * 根据参数创建ImageView对象 * * @param imagesRes * @param i * @param imageResClass * @return */ private ImageView createImageView(ArrayList imagesRes, int i, Class<?> imageResClass) { ImageView imageView = new ImageView(mContext); ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); imageView.setLayoutParams(layoutParams); ImageView.ScaleType scaleType = sScaleTypeArray[mScaleType]; imageView.setScaleType(scaleType); if (imageResClass.equals(String.class)) { // 假如图片数据源集合是url,网址图片 String url = (String) imagesRes.get(i); // 使用ImageLoader将图片展示到ImageView中 ImageLoader.getInstance().displayImage(url, imageView); } else if (imageResClass.equals(Integer.class)) { // 假如图片数据源集合是图片资源ID Integer resId = (Integer) imagesRes.get(i); imageView.setImageResource(resId); } return imageView; } /** * 为ImageView对象设置点击事件和触摸事件 * * @param imageView */ @SuppressLint("ClickableViewAccessibility") private void setImageViewListener(ImageView imageView) { imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 当手指在ImageView下按下,那么停止handler发送切换图片的消息 mHandler.removeCallbacksAndMessages(null); break; case MotionEvent.ACTION_UP: // 当手指抬起,正常发送切换图片消息. mHandler.removeCallbacksAndMessages(null); mHandler.sendEmptyMessageDelayed(1, mInterval); break; } return false; } }); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mIClickBanner != null) { // 当点击ImageView时,通过getTage()获取图片当前对应的视图索引值. // 该值是在ViewPagerAdapter中的instantiateItem()中设置的. int positon = (int) v.getTag(); int i = positon % mImageViewList.size(); mIClickBanner.click(i); } else { if (BuildConfig.DEBUG) { Log.e(TAG, "图片回调方法为不存在"); } } } }); }
3、BannerY的Adapter
复制代码
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
43public class BannerAdapter<T> extends PagerAdapter { private final static String TAG = BannerAdapter.class.getName(); ArrayList<ImageView> mImageViewList; /** * @param mImageViewList ImageView 控件列表,该列表中中的IamgeView都设置了图片资源还有点击事件等. */ public BannerAdapter(ArrayList<ImageView> mImageViewList) { this.mImageViewList = mImageViewList; } @Override public int getCount() { // 设置ViewPager的视图个数,Integer.MAX_VALUE是一个非常大的数字, 不管轮询多久都很难到尽头. return Integer.MAX_VALUE; } @SuppressLint("ClickableViewAccessibility") @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, final int position) { // position这个数字很大, 取模之后就能够对应mImageViewList集合中的索引值了. final int realPosition = position % mImageViewList.size(); ImageView imageView = mImageViewList.get(realPosition); // 将索引值与ImageView绑定,当被点击的时候可以取出该索引值. imageView.setTag(position); ViewParent viewParent = imageView.getParent(); if (viewParent != null) { // 这里是防止ViewPager重复添加图片. ((ViewGroup) viewParent).removeView(imageView); } // 将图片添加进ViewPager中 container.addView(imageView); return imageView; } @Override public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { return view == object; } @Override public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是酷炫白开水最近收集整理的关于Android自定义轮播图效果的全部内容,更多相关Android自定义轮播图效果内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复