版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中怎么使用ViewPager实现左右循环滑动效果
Android中怎么使用ViewPager实现左右循环滑动效果,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。循环滑动效果的实现:PagerAdapter我们知道ViewPager自带的滑动效果非常出色,因此我们基本不需要处理这个滑动,只处理内容的显示。而内容的显示是由Adapter控制的,因此这里重点就是这个Adapter了。为简单起见,本例的每个View直接是一张图片。下面是Adapter的代码:private
class
ImageAdapter
extends
PagerAdapter{
private
ArrayList<ImageView>
viewlist;
public
ImageAdapter(ArrayList<ImageView>
viewlist)
{
this.viewlist
=
viewlist;
}
@Override
public
int
getCount()
{
//设置成最大,使用户看不到边界
return
Integer.MAX_VALUE;
}
@Override
public
boolean
isViewFromObject(View
arg0,
Object
arg1)
{
return
arg0==arg1;
}
@Override
public
void
destroyItem(ViewGroup
container,
int
position,
Object
object)
{
//Warning:不要在这里调用removeView
}
@Override
public
Object
instantiateItem(ViewGroup
container,
int
position)
{
//对ViewPager页号求模取出View列表中要显示的项
position
%=
viewlist.size();
if
(position<0){
position
=
viewlist.size()+position;
}
ImageView
view
=
viewlist.get(position);
//如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
ViewParent
vp
=view.getParent();
if
(vp!=null){
ViewGroup
parent
=
(ViewGroup)vp;
parent.removeView(view);
}
container.addView(view);
//add
listeners
here
if
necessary
return
view;
}
}这里有几个地方需要注意:getCount()
方法的返回值:这个值直接关系到ViewPager的“边界”,因此当我们把它设置为Integer.MAX_VALUE之后,用户基本就看不到这个边界了(估计滑到这里的时候电池已经挂了吧o_O)。当然,通常情况下设置为100倍实际内容个数也是可以的,之前看的某个实现就是这么干的。instantiateItem()
方法position的处理:由于我们设置了count为
Integer.MAX_VALUE,因此这个position的取值范围很大很大,但我们实际要显示的内容肯定没这么多(往往只有几项),所以这里肯定会有求模操作。但是,简单的求模会出现问题:考虑用户向左滑的情形,则position可能会出现负值。所以我们需要对负值再处理一次,使其落在正确的区间内。instantiateItem()
方法父组件的处理:通常我们会直接addView,但这里如果直接这样写,则会抛出IllegalStateException。假设一共有三个view,则当用户滑到第四个的时候就会触发这个异常,原因是我们试图把一个有父组件的View添加到另一个组件。但是,如果直接写成下面这样:(ViewGroup)view.getParent().removeView(view);则又会因为一开始的时候组件并没有父组件而抛出NullPointerException。因此,需要进行一次判断。也就是上面的代码。destroyItem()
方法:由于我们在instantiateItem()方法中已经处理了remove的逻辑,因此这里并不需要处理。实际上,实验表明这里如果加上了remove的调用,则会出现ViewPager的内容为空的情况。轮播效果的实现:使用Handler进行更新这里我定义了一个Handler来处理ViewPager的轮播。所谓的“轮播”效果实现起来是这样的:每隔一定时间(这里是3秒)切换一次显示的页面。通过控制各页面以一定顺序循环播放,就达到了轮播的效果。为此,我们可以使用Handler的sendEmptyMessageDelayed()方法来实现定时更新,并注意用户也可能会对带有轮播效果的ViewPager手动进行滑动操作,因此我认为用户这时候是希望查看指定页面的,这时候应该取消轮播。下面是这个Handler的实现:private
static
class
ImageHandler
extends
Handler{
/**
*
请求更新显示的View。
*/
protected
static
final
int
MSG_UPDATE_IMAGE
=
1;
/**
*
请求暂停轮播。
*/
protected
static
final
int
MSG_KEEP_SILENT
=
2;
/**
*
请求恢复轮播。
*/
protected
static
final
int
MSG_BREAK_SILENT
=
3;
/**
*
记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
*
例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
*
则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
*/
protected
static
final
int
MSG_PAGE_CHANGED
=
4;
//轮播间隔时间
protected
static
final
long
MSG_DELAY
=
3000;
//使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等
private
WeakReference<MainActivity>
weakReference;
private
int
currentItem
=
0;
protected
ImageHandler(WeakReference<MainActivity>
wk){
weakReference
=
wk;
}
@Override
public
void
handleMessage(Message
msg)
{
super.handleMessage(msg);
Log.d(LOG_TAG,
"receive
message
"
+
msg.what);
MainActivity
activity
=
weakReference.get();
if
(activity==null){
//Activity已经回收,无需再处理UI了
return
;
}
//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
if
(activity.handler.hasMessages(MSG_UPDATE_IMAGE)){
activity.handler.removeMessages(MSG_UPDATE_IMAGE);
}
switch
(msg.what)
{
case
MSG_UPDATE_IMAGE:
currentItem++;
activity.viewPager.setCurrentItem(currentItem);
//准备下次播放
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE,
MSG_DELAY);
break;
case
MSG_KEEP_SILENT:
//只要不发送消息就暂停了
break;
case
MSG_BREAK_SILENT:
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE,
MSG_DELAY);
break;
case
MSG_PAGE_CHANGED:
//记录当前的页号,避免播放的时候页面显示不正确。
currentItem
=
msg.arg1;
break;
default:
break;
}
}
}集成代码:MainActivity下面是MainActivity的代码,主要是加载View和对ViewPager进行初始化设置。因为代码量比较少,重要的部分已经加了注释,就不赘述了public
class
MainActivity
extends
Activity
{
private
static
final
String
LOG_TAG
=
"MainActivity";
private
ImageHandler
handler
=
new
ImageHandler(new
WeakReference<MainActivity>(this));
private
ViewPager
viewPager;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化iewPager的内容
viewPager
=
(ViewPager)
findViewById(R.id.main_viewpager);
LayoutInflater
inflater
=
LayoutInflater.from(this);
ImageView
view1
=
(ImageView)
inflater.inflate(R.layout.item,
null);
ImageView
view2
=
(ImageView)
inflater.inflate(R.layout.item,
null);
ImageView
view3
=
(ImageView)
inflater.inflate(R.layout.item,
null);
view1.setImageResource(R.drawable.ics);
view2.setImageResource(R.drawable.jellybean);
view3.setImageResource(R.drawable.kitkat);
ArrayList<ImageView>
views
=
new
ArrayList<ImageView>();
views.add(view1);
views.add(view2);
views.add(view3);
viewPager.setAdapter(new
ImageAdapter(views));
viewPager.setOnPageChangeListener(new
ViewPager.OnPageChangeListener()
{
//配合Adapter的currentItem字段进行设置。
@Override
public
void
onPageSelected(int
arg0)
{
handler.sendMessage(Message.obtain(handler,
ImageHandler.MSG_PAGE_CHANGED,
arg0,
0));
}
@Override
public
void
onPageScrolled(int
arg0,
float
arg1,
int
arg2)
{
}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 多方借款合同范本
- 某市小学运动场地建设方案
- 精装修房屋水电安装方案
- 分成合同范本
- 社区安全应急服务方案
- 运动会场地硅PU材料方案
- 城市交通改善方案及实施步骤
- 文物保护建筑加固修复方案
- 别墅防渗漏精装修专项方案
- 二人合伙创业协议书
- 河南中职语文-基础模块上册-(高教版)第一单元测试题含答案
- 设备维修保养人员专业素质培养
- 27《一个粗瓷大碗》(教学设计)统编版语文三年级上册
- 学前儿童听说游戏活动(学前儿童语言教育活动课件)
- 环境艺术设计发展现状分析报告
- 培训机构校长竞聘
- 企业微信指导手册管理员版
- 2024年公路交通运输技能考试-公交车笔试参考题库含答案
- 孙子兵法中的思维智慧智慧树知到期末考试答案2024年
- 监控维保服务方案
- 临床试验方案偏离处理流程
评论
0/150
提交评论