Android轮播图原理思路分析+实现方案
来自:http://blog.csdn.net/wubihang/article/details/52512597
ListView的headerView设置为轮播图之后结合上/下拉刷新/加载的模式成为现在大多数APP的一个必须具备的功能,对于许多初学者来说想要实现轮播图这样一个集线程睡眠、自动处理、替换过程中刷新UI界面的组合功能非常困难,没有思路,感觉无从下手,去搜索各种实现方案,发现目前充斥着大量的类似于使用弃用组件Gallery这样的例子。
本篇博客将通过分析轮播图的各个注意事项及实现思路来实现一个简易的轮播图。
首先看下一下效果图;
需求: 1.轮播,如轮播四张图:到第四张之后不会回到第一张而是继续向下一张切换;
2.初始状态即可向前滑动
3.轮播过程中会有状态切换以白点和黑点的方式呈现;
ps:这里的魂斗罗见到有没有热血沸腾,情怀所在;
实现步骤:
一、轮播图部分采用的是ViewPager显示Layout布局,替换图片的方式
1.为了让图片滑到最后一张不是以翻页的形式回到首页,getCount方法返回的是int最大值,这样就会有很多页;
2.由于getCount方法返回整型最大值,所以使用的position采用取余的计算方法,虽然position会一直增加,但是显示的数据始终为固定数量;
package com.wu.rotateimgdemo;import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import java.util.List;/*** Created by wubihang on 16/9/12.*/
public class RotateVpAdapter extends PagerAdapter{private List<RotateBean> datas;private Context context;private LayoutInflater inflater;public RotateVpAdapter(Context context) {this.context = context;inflater = LayoutInflater.from(context);}public void setDatas(List<RotateBean> datas) {this.datas = datas;notifyDataSetChanged();}@Overridepublic int getCount() {// 为了让ViewPager到最后一页不会像翻书一样回到第一页// 设置页数为int最大值,这样向下滑动永远都是下一页return datas == null ? 0 : Integer.MAX_VALUE;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {// position是int最大值所以这里可能是几百甚至上千,因此取余避免数组越界int newPosition = position % datas.size();View convertView = inflater.inflate(R.layout.item_vp, container, false);ImageView imageView = (ImageView) convertView.findViewById(R.id.item_iv);TextView textView = (TextView) convertView.findViewById(R.id.item_tv);textView.setText("文字内容" + newPosition);imageView.setImageResource(datas.get(newPosition).getImgId());container.addView(convertView);return convertView;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {}
}
- 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
二、设置轮播的线程
1.轮播采用Handler对象的postDelayed方法,发送一个延时的任务;
任务的内容是每隔固定时间让ViewPager当前页自增1,如果处于轮播状态再次延时执行该任务,这样只要轮播状态isRotate为true,就像死循环一样一直执行此轮播任务;
/*** 开始轮播*/private void startRotate() {rotateRunnable = new Runnable() {@Overridepublic void run() {int nowIndex = viewPager.getCurrentItem();viewPager.setCurrentItem(++nowIndex);if (isRotate) {handler.postDelayed(rotateRunnable, TIME);}}};handler.postDelayed(rotateRunnable, TIME);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
在onPause和onResume里对于轮播状态进行了处理
@Overrideprotected void onResume() {super.onResume();isRotate = true;}@Overrideprotected void onPause() {super.onPause();isRotate = false;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
三、设置轮播状态切换的小圆点
1.设置的方式是动态的,有多少张轮播图就循环加入多少个小圆点;
2.将position==0时的小圆点设置为黑色,默认选中第一张,剩下的设置为白色;
这里的mipmap是我自己做的两张黑色的和白色的小圆点图片;
/*** 添加轮播切换小点*/private void addPoints() {// 有多少张图加载多少个小点for (int i = 0; i < datas.size(); i++) {ImageView pointIv = new ImageView(this);pointIv.setPadding(5,5,5,5);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20,20);pointIv.setLayoutParams(params);// 设置第0页小点的为灰色if (i == 0) {pointIv.setImageResource(R.mipmap.point_grey);} else {pointIv.setImageResource(R.mipmap.point_white);}pointLl.addView(pointIv);}}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
四、设置ViewPager页切换时小圆点的颜色跟着改变
1.当页切换时,获取所有的小圆点,将他们都设置为白色;
2.获取当前页的小圆点,将它设置为黑色;
private void changePoints() {viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {if (isRotate) {// 把所有小点设置为白色for (int i = 0; i < datas.size(); i++) {ImageView pointIv = (ImageView) pointLl.getChildAt(i);pointIv.setImageResource(R.mipmap.point_white);}// 设置当前位置小点为灰色ImageView iv = (ImageView) pointLl.getChildAt(position % datas.size());iv.setImageResource(R.mipmap.point_grey);}}@Overridepublic void onPageScrollStateChanged(int state) {}});}
- 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
这样简单的完成了一个ViewPager实现的轮播线程;
分析及实现过程完毕,下面贴上全部代码!
1.布局文件
activity_main.xml
分别是装载轮播图的ViewPager和装载小圆点的容器;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><FrameLayout
android:layout_width="match_parent"android:layout_height="300dp"><android.support.v4.view.ViewPager
android:id="@+id/rotate_vp"android:layout_width="match_parent"android:layout_height="match_parent"/><LinearLayout
android:id="@+id/rotate_point_container"android:layout_width="match_parent"android:layout_height="20dp"android:layout_gravity="bottom|center"android:layout_marginBottom="10dp"android:orientation="horizontal"/></FrameLayout></LinearLayout>
- 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
ViewPager的页布局
item_vp.xml
分别是显示轮播图的ImageView和显示上面文字的TextView;
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageView
android:id="@+id/item_iv"android:layout_width="match_parent"android:layout_height="match_parent"android:adjustViewBounds="true"android:scaleType="fitXY" /><TextView
android:id="@+id/item_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|right"android:layout_marginBottom="25dp"android:textSize="16sp"android:textColor="#f03"android:layout_marginRight="10dp"android:textStyle="bold" /></FrameLayout>
- 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
2.数据实体类
这里运用的是本地图片,因此使用的是imgId;
如果网络图片也可以加入,将图片源更改即可;
package com.wu.rotateimgdemo;import java.io.Serializable;/*** Created by wubihang on 16/9/12.*/
public class RotateBean implements Serializable{private int imgId;private String imgUrl;public RotateBean() {}public RotateBean(String imgUrl) {this.imgUrl = imgUrl;}public RotateBean(int imgId) {this.imgId = imgId;}public RotateBean(int imgId, String imgUrl) {this.imgId = imgId;this.imgUrl = imgUrl;}public int getImgId() {return imgId;}public void setImgId(int imgId) {this.imgId = imgId;}public String getImgUrl() {return imgUrl;}public void setImgUrl(String imgUrl) {this.imgUrl = imgUrl;}
}
- 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
3.适配器
适配器部分需要注意:
1)getCount的返回值
2)使用时position取余的运用(防止数组越界)
package com.wu.rotateimgdemo;import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import java.util.List;/*** Created by wubihang on 16/9/12.*/
public class RotateVpAdapter extends PagerAdapter{private List<RotateBean> datas;private Context context;private LayoutInflater inflater;public RotateVpAdapter(List<RotateBean> datas, Context context) {this.datas = datas;this.context = context;inflater = LayoutInflater.from(context);}public RotateVpAdapter(Context context) {this.context = context;inflater = LayoutInflater.from(context);}public void setDatas(List<RotateBean> datas) {this.datas = datas;notifyDataSetChanged();}@Overridepublic int getCount() {// 为了让ViewPager到最后一页不会像翻书一样回到第一页// 设置页数为int最大值,这样向下滑动永远都是下一页return datas == null ? 0 : Integer.MAX_VALUE;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, int position) {// position是int最大值所以这里可能是几百甚至上千,因此取余避免数组越界int newPosition = position % datas.size();View convertView = inflater.inflate(R.layout.item_vp, container, false);ImageView imageView = (ImageView) convertView.findViewById(R.id.item_iv);TextView textView = (TextView) convertView.findViewById(R.id.item_tv);textView.setText("文字内容" + newPosition);imageView.setImageResource(datas.get(newPosition).getImgId());container.addView(convertView);return convertView;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {}
}
- 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
4.Activity部分,此部分代码比较多,请阅读时仔细梳理;
package com.wu.rotateimgdemo;import android.os.Handler;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private static final int TIME = 3000;private ViewPager viewPager;private LinearLayout pointLl;// 轮播状态改变的小圆点容器private List<RotateBean> datas;private RotateVpAdapter vpAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);viewPager = (ViewPager) findViewById(R.id.rotate_vp);pointLl = (LinearLayout) findViewById(R.id.rotate_point_container);buildDatas();// 构造数据vpAdapter = new RotateVpAdapter(datas, this);viewPager.setAdapter(vpAdapter);// ViewPager的页数为int最大值,设置当前页多一些,可以上来就向前滑动// 为了保证第一页始终为数据的第0条 取余要为0,因此设置数据集合大小的倍数viewPager.setCurrentItem(datas.size() * 100);// 开始轮播handler = new Handler();startRotate();// 添加轮播小点addPoints();// 随着轮播改变小点changePoints();}private void changePoints() {viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {if (isRotate) {// 把所有小点设置为白色for (int i = 0; i < datas.size(); i++) {ImageView pointIv = (ImageView) pointLl.getChildAt(i);pointIv.setImageResource(R.mipmap.point_white);}// 设置当前位置小点为灰色ImageView iv = (ImageView) pointLl.getChildAt(position % datas.size());iv.setImageResource(R.mipmap.point_grey);}}@Overridepublic void onPageScrollStateChanged(int state) {}});}/*** 添加轮播切换小点*/private void addPoints() {// 有多少张图加载多少个小点for (int i = 0; i < datas.size(); i++) {ImageView pointIv = new ImageView(this);pointIv.setPadding(5,5,5,5);LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20,20);pointIv.setLayoutParams(params);// 设置第0页小点的为灰色if (i == 0) {pointIv.setImageResource(R.mipmap.point_grey);} else {pointIv.setImageResource(R.mipmap.point_white);}pointLl.addView(pointIv);}}private Handler handler;private boolean isRotate = false;private Runnable rotateRunnable;/*** 开始轮播*/private void startRotate() {rotateRunnable = new Runnable() {@Overridepublic void run() {int nowIndex = viewPager.getCurrentItem();viewPager.setCurrentItem(++nowIndex);if (isRotate) {handler.postDelayed(rotateRunnable, TIME);}}};handler.postDelayed(rotateRunnable, TIME);}@Overrideprotected void onResume() {super.onResume();isRotate = true;}@Overrideprotected void onPause() {super.onPause();isRotate = false;}private void buildDatas() {datas = new ArrayList<>();datas.add(new RotateBean(R.mipmap.big_image));datas.add(new RotateBean(R.mipmap.btn_normal));datas.add(new RotateBean(R.mipmap.icon_baoman));datas.add(new RotateBean(R.mipmap.btn_pressed));}
}
- 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
本篇博客内容纯属原创,各位随便使用随便点评;
祝大家写代码无bug,实现功能思路如飞;
源码下载请见下方链接
http://download.csdn.net/detail/wubihang/9628348
Android轮播图原理思路分析+实现方案相关推荐
- android github轮播图,GitHub - ZTJzzz/Banner: Android轮播图
Android轮播图 - Banner 纵观Android古今,轮播图已然泛滥成灾!大神们各显神通大兴土木,所起楼台之高让后来者心生膜拜,纷纷Star!但不法分子也是层出不穷,为求"大神&q ...
- 原生js实现轮播图的思路、代码及知识点!
一.轮播图实现思路: 1.自动轮播: (1)使所有的图片的层级为0,并且li的背景颜色设置为默认颜色: (2)使当前下标的图片的层级为1,并且当前li的背景颜色设置为白色: (3)时间函数每隔1秒执行 ...
- 老徐WEB:最简单详细的轮播图原理和制作过程(一)
老徐利用空闲时间,制作了一个最简单的轮播图,主要介绍轮播图的原理和制作过程,只要大家能认真看完这篇文章,并理解文中内容,就能完全掌握轮播图的制作了.之后工作中碰到复杂的轮播图,自己也能思考制作出来了. ...
- android轮播图实现方案,Android轮播图实现教程
ListView的headerView设置为轮播图之后结合上/下拉刷新/加载的模式成为现在大多数APP的一个必须具备的功能,对于许多初学者来说想要实现轮播图这样一个集线程睡眠.自动处理.替换过程中刷新 ...
- html轮播图原理,30_用js实现一个轮播图效果,简单说下原理
一.原理 将一些图片在一行中平铺,然后计算偏移量再利用定时器实现定时轮播. 步骤一:建立html基本布局 如下所示: 轮播图 1 2 3 4 5 < > 只有五张图片,却使用7张来轮播,这 ...
- android轮播图简单实现(左右无限滑动,自动轮播)
直接上代码了,都有注释,原理很简单 public class MainActivity extends AppCompatActivity { private static final String ...
- Android 轮播图从 0 到 1
轮播图是 Android 常用功能之一,效果大概是这样的: 之前我封装写了一个,基本达到了要求,是继承了 Fragment(当时脑袋肯定锈掉了),里面 Viewpager add Fragment,这 ...
- android开发banner框架,Android 轮播图 最火的banner框架 (包含demo和代码解释)
在android里,轮播图的实现可以使用viewpage的控件实现,但由于实现有点繁琐,可以使用banner框架,方便快捷的实现轮播图的效果.这里首先贴上github的banner框架地址:https ...
- 小白怎么做一个轮播图?(思路+代码)
在页面中写好结构和样式(根据情况而定) 外层用一个$(function(){})函数包裹起来,代表等页面的内容加载完成后再去执行jquery的功能代码. 获取到包裹ul,li的大盒子元素:const ...
最新文章
- 时隔两年,EfficientNet v2来了!更快,更小,更强!
- Scrum 冲刺博客第四篇
- hdu 2896 病毒侵袭
- idea导入项目的问题:nothing found
- linux关闭防火墙时出现问号乱码,linux文件名乱码问题的解决方...-tcp_wrappers防火墙配置方法-su 与 su - 的比较_169IT.COM...
- java 工作簿_将多个Excel工作簿合并到一个工作簿中
- 2021蓝桥杯——直线
- 国信证券有限责任公司关于创设南航认沽权证的公告
- 人工智能技术涉及到的学科有哪些,22年最新
- 解决 have unmet dependencies: youdao-dict :
- HackerRank - C语言 - Introduction - Playing With Characters
- 支持英特尔9242的服务器,宝德2U双子星服务器PR2725TP2
- 从键盘输入一个三位整数n,分别求出n的个位数字、十位数字和百位数字
- 实体门店的促销活动该如何策划才能成功?
- 【java】eclipse
- JSP用户登录连接数据库
- 执行docker命令,出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
- git push错误,如何回滚
- Java资源大全中文版-Awesome - java
- 【LTspice】【如何手动测量仿真波形的电压(差)值】