欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中用RxJava和ViewPager实现轮播图

程序员文章站 2024-03-05 10:48:24
前言 很多人要实现轮播图都会想到使用viewpager + handler来完成轮播图的效果。但是在rxjava快速发展的情况下,已经可以使用rxjava来代替handl...

前言

很多人要实现轮播图都会想到使用viewpager + handler来完成轮播图的效果。但是在rxjava快速发展的情况下,已经可以使用rxjava来代替handler完成这样任务了。

下面我们就来介绍如何实现rxjava+viewpager的轮播图。

效果图如下

Android中用RxJava和ViewPager实现轮播图

viewpager的操作

说到viwepager应该大家都不陌生,它可以结合普通的view也可以结合fragment一起使用。在此我也就不对它的使用方法进行过多的介绍了。直接开始介绍轮播的方法。

常见的轮播操作

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;
 }
 ....
}
private static class imagehandler extends handler{
 ...
 @override
 public void handlemessage(message msg) {
  super.handlemessage(msg);
  //检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
  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;
  }
 }
 ...
}

以上就是比较常见的轮播图的代码,我只是在网上随便找的。首先它的代码中将pageradapter的getcount()返回了一个integer.max_value;它的目的是为了让图片一直的播放下去,但是在一些极限情况下还是会crash的,并且它返回的数量太大了在一定程度上对内存也造成了较大的消耗。其次我们可以看到handler的代码极其的冗杂,不仅多而且逻辑也比较麻烦。 现在我们针对刚才的问题来进行优化

更好的轮播操作

更好的无限播放:设置页卡视图列表时,在前后额外各加一个页卡。最前面加最后一张图片,最后面加第1张图片。然后每当切换到最前的页卡时,就替换成倒数第2个页卡;每当切换到最后的页卡时,就替换成第2个页卡。这样一来就形成了连贯,自然实现了无限滑动的功能。

1)设置viewpager的视图列表时,在前后各加一个页卡。

for (int i = 0; i < count + 2; i++) {
 if (i == 0) {// 将最前面一页设置成本来最后的那页
  glide.with(context).
    load(imagetitlebeanlist.get(count - 1).getimageurl()).into(ivimage);
  tvtitle.settext(imagetitlebeanlist.get(count - 1).gettitle());
 } else if (i == count + 1) {// 将最后面一页设置成本来最前的那页
  glide.with(context).
    load(imagetitlebeanlist.get(0).getimageurl()).into(ivimage);
  tvtitle.settext(imagetitlebeanlist.get(0).gettitle());
 } else {
  glide.with(context).
    load(imagetitlebeanlist.get(i - 1).getimageurl()).into(ivimage);
  tvtitle.settext(imagetitlebeanlist.get(i - 1).gettitle());
 }
 // 将设置好的view添加到view列表中
 viewlist.add(view);
}

2)在监听viewpager的页卡状态改变中,当滑动到第1个页卡时替换成倒数第2个页卡;当滑动到最后一个页卡时替换成第2个页卡。

@override
public void onpagescrollstatechanged(int state) {
 switch (state) {
  // 闲置中
  case viewpager.scroll_state_idle:
   // “偷梁换柱”
   if (vpimagetitle.getcurrentitem() == 0) {
    vpimagetitle.setcurrentitem(count, false);
   } else if (vpimagetitle.getcurrentitem() == count + 1) {
    vpimagetitle.setcurrentitem(1, false);
   }
   currentitem = vpimagetitle.getcurrentitem();
   break;
 }
}

handler现在就该由rxjava来替代了。

interval 操作符

创建一个按固定时间间隔发射整数序列的observable

Android中用RxJava和ViewPager实现轮播图

interval操作符返回一个observable,它按固定的时间间隔发射一个无限递增的整数序列。

Android中用RxJava和ViewPager实现轮播图

rxjava将这个操作符实现为interval方法。它接受一个表示时间间隔的参数和一个表示时间单位的参数。

javadoc: interval(long,timeunit)

javadoc: interval(long,timeunit,scheduler)

interval默认在computation调度器上执行。你也可以传递一个可选的scheduler参数来指定调度器。

用rxjava取代handler

public void start() {
 mviewpagersubscribe = observable.interval(5, 5, timeunit.seconds) // 5s的延迟,5s的循环时间
  .subscribeon(androidschedulers.mainthread())
  .observeon(androidschedulers.mainthread())
  .subscribe(new action1<long>() {
   @override
   public void call(long along) {
    // 进行轮播操作
    if (mweeklymovieinfos != null && mweeklymovieinfos.size() > 0 && isautoplay) {
     mcurrentpage++;
     mweeklyviewpager.setcurrentitem(mcurrentpage);
    }
   }
  });
}

为了更好的用户体验,在用户进行滑动操作的时候,应该停止自动轮播

mpager.setontouchlistener(new view.ontouchlistener() {
 @override
 public boolean ontouch(view v, motionevent event) {
 //监听viewpager的触摸事件,当用户按下的时候取消注册,当用户手抬起的时候再注册
  switch (event.getaction()){
   case motionevent.action_down:
    stop();
    break;
   case motionevent.action_up:
    start();
    break; 
  }
  return false;
 }});

public void stop() {
 if(mviewpagersubscribe.isunsubscribed()) { 
  mviewpagersubscribe.unsubscribe();
 }
}

总结

这篇文章主要是对viewpager实现轮播图的一种总结。首先提出更好的轮播图的方法,其实讲解了rxjava中interval操作符的使用,最后用该操作符替换掉handler完美实现轮播图。以上就是这篇文章的全部内容,希望本文的内容能对大家有所帮助,如果有疑问大家可以留言交流。

上一篇: 基于RxJava实现酷炫启动页

下一篇: