当前位置: 移动技术网 > IT编程>移动开发>Android > Android简单实现无限滚动自动滚动的ViewPager

Android简单实现无限滚动自动滚动的ViewPager

2019年07月24日  | 移动技术网IT编程  | 我要评论

风花悄落,情趣内衣秀全透明,快递查询中通

经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个viewpager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底。所以试着封装一个比较好用的viewpager

效果如下:

简单的说一下实现思路,要实现无限滚动的话就要在pageradapter上面做一些手脚,在pageradapter的getcount的函数的返回值设置成integer.mxa_value就可以实现向右无限滚动,但是要实现向左无限滚动呢?就是一开始的时候setcurrentitem的时候设置一个非常大的值(大到你向左滚动了一万年还是有东西)

@override 
    public int getcount() { 
      return integer.max_value; 
    } 
mpager.setcurrentitem(10000 * mdatas.size());//一开始设置成这样的话就可以向左无限滚动了 

然后另外一个就是底部的游标了:

底部的游标是用一个自定义视图:无非就是画一个背景,然后在画一个高亮的游标

/** 
  * 指示游标 
  */ 
  private class tipview extends view { 
    private int mpadding; 
    private int mcount; 
    private int mcurpos; 
    private paint mnorpaint;//未被选中的颜色 
    private paint mselpaint;//被选中的颜色 白色 
    private int mheight; 
    public tipview(context context, int count) { 
      super(context); 
      mnorpaint = new paint(); 
      mnorpaint.setantialias(true); 
      int selheight = showutils.dip2px(2); 
      int norheight = showutils.dip2px(1); 
      mheight = showutils.dip2px(2); 
      mnorpaint.setstrokewidth(norheight); 
      mnorpaint.setcolor(color.argb(80, 255, 255, 255)); 
      mselpaint = new paint(); 
      mselpaint.setantialias(true); 
      mselpaint.setstrokewidth(selheight); 
      mselpaint.setcolor(color.white); 
      mcount = count; 
      mpadding = showutils.dip2px(0); 
    } 
    @override 
    protected void ondraw(canvas canvas) { 
      super.ondraw(canvas); 
      int ow = (getwidth()-2 * mpadding)/ mcount; 
      int y = getheight() / 2; 
      canvas.drawline(mpadding, y, mcurpos * ow + mpadding, y, mnorpaint); 
      canvas.drawline(mcurpos * ow + mpadding, y, (mcurpos + 1) * ow + mpadding, y, mselpaint); 
      canvas.drawline((mcurpos + 1) * ow + mpadding, y, getwidth() - mpadding, y, mnorpaint); 
    } 
    @override 
    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
      viewgroup.layoutparams vp = getlayoutparams(); 
      vp.width = viewgroup.layoutparams.match_parent; 
      vp.height = mheight; 
      super.onmeasure(widthmeasurespec, heightmeasurespec); 
    } 
    public void setcurpostion(int pos) { 
      mcurpos = pos; 
      invalidate(); 
    } 
    public void setcount(int count) { 
      mcount = count; 
    } 
  } 

r.layout.layout_recommend_item的布局:

<?xml version="1.0" encoding="utf-8"?> 
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:orientation="vertical" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent"> 
  <imageview 
    android:id="@+id/iv_pic" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:contentdescription="@null" 
    android:scaletype="fitxy"/> 
  <linearlayout 
    android:layout_width="match_parent" 
    android:layout_height="48dp" 
    android:orientation="vertical" 
    android:layout_alignparentbottom="true" 
    android:background="@drawable/recommend" 
    android:gravity="center"> 
    <textview 
      android:id="@+id/tv_desc" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:textcolor="@color/white" 
      android:textsize="@dimen/text_normal" 
      android:maxlines="1" 
      android:ellipsize="end" 
      android:shadowcolor="#ff333333" 
      android:shadowdx="2" 
      android:shadowdy="2" 
      android:paddingright="8dp" 
      android:paddingleft="8dp" 
      android:shadowradius="1" /> 
  </linearlayout> 
</relativelayout> 

还有一个是实现自动滚动,自动滚动的话就是监听onpagerchangelistener里面的函数,在viewpager状态改变的时候利用handler发送一个切换界面的消息:

@override 
    public void onpagescrollstatechanged(int i) { 
      curstate = i; 
      if(i == viewpager.scroll_state_dragging){  //viewpager正在被拖动的时候 
        stopanimation(); 
      }else { //没有可执行消息时候添加消息 实现自动滚动 
        if(!(shandler.hasmessages(start_scroll)&&shandler.hasmessages(scroll_next))){ 
          startanimation(); 
        } 
      } 
    } 
    @override 
    public void onpageselected(final int i) {  //页面跳转后得到调用 
      shandler.removemessages(scroll_next); 
      shandler.removemessages(start_scroll); 
      if(curstate == viewpager.scroll_state_dragging){ 
        return; 
      } 
      message msg = shandler.obtainmessage(scroll_next); 
      msg.arg1 = i + 1; 
      msg.obj = mpager; 
      shandler.sendmessagedelayed(msg, show_time); 
      mtipview.setcurpostion(i % mdatas.size()); 
    } 

整体的代码:

import android.content.context; 
import android.graphics.canvas; 
import android.graphics.color; 
import android.graphics.paint; 
import android.os.handler; 
import android.os.message; 
import android.support.v4.view.pageradapter; 
import android.support.v4.view.viewpager; 
import android.util.displaymetrics; 
import android.view.view; 
import android.view.viewgroup; 
import android.widget.imageview; 
import android.widget.relativelayout; 
import android.widget.textview; 
import com.nostra13.universalimageloader.core.displayimageoptions; 
import com.nostra13.universalimageloader.core.imageloader; 
import com.papau.show.r; 
import com.papau.show.entity.headviewentity; 
import com.papau.show.utils.showutils; 
import java.util.arraylist; 
import java.util.list; 
public class recommendview extends relativelayout implements irecommend { 
  private static final int start_scroll = 1; 
  private static final int scroll_next = 2; 
  private static final int show_time = 5000; 
  private list<headviewentity> mdatas = new arraylist<>(); 
  private viewpager mpager; 
  private context mcontext; 
  private int mwidth, mheight; 
  private imageloader mloader; 
  private displayimageoptions moptions; 
  private int mtitleheight; 
  private tipview mtipview; 
  private static handler shandler = new handler() { 
    @override 
    public void handlemessage(message msg) { 
      int w = msg.what; 
      viewpager pager = (viewpager) msg.obj; 
      switch (w) { 
        case start_scroll: 
          pager.setcurrentitem(msg.arg1, true); 
          break; 
        case scroll_next: 
          pager.setcurrentitem(msg.arg1, true); 
          break; 
      } 
    } 
  }; 
  public recommendview(context context) { 
    super(context); 
  } 
  public recommendview(context context, int w, int h) { 
    super(context); 
    mcontext = context; 
    mwidth = w; 
    mheight = h; 
    initview(); 
//    mpager.setadapter(new recommendadapter()); 
    mpager.setonpagechangelistener(new monpagerchangelistener()); 
    mloader = imageloadermanager.getimageloader(mcontext); 
    moptions = imageloadermanager.getcacheondiskoptions(mcontext); 
    init(); 
//    displaymetrics dm = mcontext.getresources().getdisplaymetrics(); 
    mtitleheight = showutils.dip2px(48);//设置游标高度 
  } 
  @override 
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
    viewgroup.layoutparams vp = getlayoutparams(); 
    if (vp != null) {  //设置视图的宽高 
      vp.width = mwidth; 
      vp.height = mheight; 
    } 
    super.onmeasure(widthmeasurespec, heightmeasurespec); 
  } 
  private void initview() { 
    mpager = new viewpager(mcontext); 
    relativelayout.layoutparams rp = new relativelayout.layoutparams(relativelayout.layoutparams.match_parent, relativelayout.layoutparams.match_parent); 
    addview(mpager, rp); 
  } 
  /** 
   * 初始化指示游标 
   */ 
  private void inittipview() { 
    if (mtipview == null) { 
      relativelayout.layoutparams rp = new relativelayout.layoutparams(10, 10); 
      rp.addrule(relativelayout.align_parent_bottom);//显示在父控件的底部 
      rp.bottommargin = mtitleheight;//游标的高度 
      mtipview = new tipview(mcontext, mdatas.size()); 
      addview(mtipview, rp); 
    } else { 
      mtipview.setcount(mdatas.size()); 
    } 
  } 
  @override 
  public void update() { 
    getdata(); 
  } 
  @override 
  public void init() { 
    getdata(); 
  } 
  @override 
  public void startanimation() { 
    if (mdatas.size() == 0) { 
      return; 
    } 
    message msg = shandler.obtainmessage(start_scroll); 
    msg.obj = mpager; 
    msg.arg1 = (mpager.getcurrentitem() + 1); 
    shandler.sendmessagedelayed(msg, show_time); 
  } 
  @override 
  public void stopanimation() { 
    shandler.removemessages(start_scroll); 
    shandler.removemessages(scroll_next); 
  } 
  /** 
   * 获取viewpager要显示的数据 
   */ 
  private void getdata() { 
    string[] imagedata = new string[]{"http://f.hiphotos.baidu.com/image/h%3d360/sign=e105b9f1d61b0ef473e89e58edc651a1/b151f8198618367a9f738e022a738bd4b21ce573.jpg", 
        "http://c.hiphotos.baidu.com/image/h%3d360/sign=b8cea9e92b738bd4db21b437918b876c/f7246b600c3387448982f948540fd9f9d72aa0bb.jpg", 
        "http://a.hiphotos.baidu.com/image/h%3d360/sign=3da95d01e7dde711f8d245f097eecef4/71cf3bc79f3df8dc39cb6295cf11728b461028c4.jpg", 
        "http://d.hiphotos.baidu.com/image/h%3d360/sign=410c3c96a60f4bfb93d09852334f788f/10dfa9ec8a136327a1de913a938fa0ec08fac78c.jpg", 
        "http://e.hiphotos.baidu.com/image/h%3d360/sign=f6600b1613dfa9ece22e501152d1f754/342ac65c10385343ff41ee2b9113b07eca808829.jpg"}; 
    for (int i = 0; i < 5; i++) { 
      headviewentity info = new headviewentity(); 
      info.setimageurl(imagedata[i]); 
      info.settitle("我不做大哥好多年"+i); 
      info.seturl("www.baidu.com"); 
      mdatas.add(info); 
    } 
    shandler.postdelayed(new runnable() { 
      @override 
      public void run() { 
        stopanimation(); 
        inittipview(); 
        mpager.setadapter(new recommendadapter()); 
        mpager.setcurrentitem(10000 * mdatas.size());//一开始设置成这样的话就可以向左无限滚动了 
      } 
    },2000); 
  } 
  /** 
   * viewpager子项内容 
   */ 
  private class recommendadapter extends pageradapter { 
    /** 
     * 填充子项视图的内容 
     * @param container 父控件 viewpager 
     * @param position 子项的位置 
     * @return 返回子项视图 
     */ 
    @override 
    public object instantiateitem(viewgroup container, int position) { 
      int curpos = position % mdatas.size(); 
      view view = view.inflate(mcontext, r.layout.layout_recommend_item, null); 
      viewgroup.layoutparams vp = new viewgroup.layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.match_parent); 
      imageview iv = (imageview) view.findviewbyid(r.id.iv_pic); 
      textview tv = (textview) view.findviewbyid(r.id.tv_desc); 
      tv.settext(mdatas.get(curpos).gettitle()); 
      mloader.displayimage(mdatas.get(curpos).getimageurl(), iv, moptions); 
      container.addview(view, vp); 
      view.settag(curpos); 
      view.setonclicklistener(new onclicklistener() { 
        @override 
        public void onclick(view v) { 
        } 
      }); 
      return view; 
    } 
    @override 
    public void destroyitem(viewgroup container, int position, object object) { 
      container.removeview((view) object); 
    } 
    @override 
    public int getcount() { 
      return integer.max_value; 
    } 
    @override 
    public boolean isviewfromobject(view view, object o) { 
      return view == o; 
    } 
  } 
  private class monpagerchangelistener implements viewpager.onpagechangelistener { 
    private int curstate; 
    @override 
    public void onpagescrolled(int i, float v, int i1) { 
    } 
    @override 
    public void onpagescrollstatechanged(int i) { 
      curstate = i; 
      if(i == viewpager.scroll_state_dragging){  //viewpager正在被拖动的时候 
        stopanimation(); 
      }else { //没有可执行消息时候添加消息 实现自动滚动 
        if(!(shandler.hasmessages(start_scroll)&&shandler.hasmessages(scroll_next))){ 
          startanimation(); 
        } 
      } 
    } 
    @override 
    public void onpageselected(final int i) {  //页面跳转后得到调用 
      shandler.removemessages(scroll_next); 
      shandler.removemessages(start_scroll); 
      if(curstate == viewpager.scroll_state_dragging){ 
        return; 
      } 
      message msg = shandler.obtainmessage(scroll_next); 
      msg.arg1 = i + 1; 
      msg.obj = mpager; 
      shandler.sendmessagedelayed(msg, show_time); 
      mtipview.setcurpostion(i % mdatas.size()); 
    } 
  } 
  /** 
   * 指示游标 
   */ 
  private class tipview extends view { 
    private int mpadding; 
    private int mcount; 
    private int mcurpos; 
    private paint mnorpaint;//未被选中的颜色 
    private paint mselpaint;//被选中的颜色 白色 
    private int mheight; 
    public tipview(context context, int count) { 
      super(context); 
      mnorpaint = new paint(); 
      mnorpaint.setantialias(true); 
      int selheight = showutils.dip2px(2); 
      int norheight = showutils.dip2px(1); 
      mheight = showutils.dip2px(2); 
      mnorpaint.setstrokewidth(norheight); 
      mnorpaint.setcolor(color.argb(80, 255, 255, 255)); 
      mselpaint = new paint(); 
      mselpaint.setantialias(true); 
      mselpaint.setstrokewidth(selheight); 
      mselpaint.setcolor(color.white); 
      mcount = count; 
      mpadding = showutils.dip2px(0); 
    } 
    @override 
    protected void ondraw(canvas canvas) { 
      super.ondraw(canvas); 
      int ow = (getwidth()-2 * mpadding)/ mcount; 
      int y = getheight() / 2; 
      canvas.drawline(mpadding, y, mcurpos * ow + mpadding, y, mnorpaint); 
      canvas.drawline(mcurpos * ow + mpadding, y, (mcurpos + 1) * ow + mpadding, y, mselpaint); 
      canvas.drawline((mcurpos + 1) * ow + mpadding, y, getwidth() - mpadding, y, mnorpaint); 
    } 
    @override 
    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
      viewgroup.layoutparams vp = getlayoutparams(); 
      vp.width = viewgroup.layoutparams.match_parent; 
      vp.height = mheight; 
      super.onmeasure(widthmeasurespec, heightmeasurespec); 
    } 
    public void setcurpostion(int pos) { 
      mcurpos = pos; 
      invalidate(); 
    } 
    public void setcount(int count) { 
      mcount = count; 
    } 
  } 
} 

然后提供了一个接口调用:

/** 
 * recommendview接口 
 */ 
public interface irecommend { 
  void update(); 
  void init(); 
  void startanimation(); 
  void stopanimation(); 
}

图片的加载用到了imageload库:

import android.content.context; 
import android.graphics.bitmap; 
import com.nostra13.universalimageloader.cache.disc.impl.unlimiteddiskcache; 
import com.nostra13.universalimageloader.core.displayimageoptions; 
import com.nostra13.universalimageloader.core.imageloader; 
import com.nostra13.universalimageloader.core.imageloaderconfiguration; 
import com.nostra13.universalimageloader.core.assist.imagescaletype; 
import com.papau.show.constant.constants; 
import java.io.file; 
public class imageloadermanager { 
  /** 
   * 不带硬盘缓存的options 
   * 
   * @param context 
   * @return 
   */ 
  public static synchronized displayimageoptions getcacheonmemoryoptions(context context) { 
    displayimageoptions options = new displayimageoptions.builder() 
        .cacheinmemory(true) 
        .cacheondisk(false) 
        .imagescaletype(imagescaletype.exactly_stretched) 
        .bitmapconfig(bitmap.config.argb_8888) 
//        .showimageonloading( 
//            context.getresources().getdrawable( 
//                r.drawable.loading_wait)) 
//        .showimageonfail( 
//            context.getresources().getdrawable( 
//                r.drawable.loading_wait)) 
        .build(); 
    return options; 
  } 
  public static synchronized displayimageoptions getcircleoptions(context context) { 
    displayimageoptions options = new displayimageoptions.builder() 
        .cacheinmemory(true) 
        .cacheondisk(false) 
        .imagescaletype(imagescaletype.exactly_stretched) 
        .bitmapconfig(bitmap.config.argb_8888) 
//        .showimageonloading( 
//            context.getresources().getdrawable( 
//                r.drawable.ic_user_head_hint)) 
//        .showimageonfail( 
//            context.getresources().getdrawable( 
//                r.drawable.ic_user_head_hint)) 
        .build(); 
    return options; 
  } 
  /** 
   * 获取在硬盘中缓存options 
   * 
   * @param context 
   * @return options 
   */ 
  public static synchronized displayimageoptions getcacheondiskoptions( 
      context context) { 
    displayimageoptions options = new displayimageoptions.builder() 
        .cacheinmemory(true) 
        .cacheondisk(true) 
        .imagescaletype(imagescaletype.exactly) 
        .bitmapconfig(bitmap.config.argb_8888) 
//        .showimageonloading( 
//            context.getresources().getdrawable( 
//                r.drawable.loading_wait)) 
//        .showimageonfail( 
//            context.getresources().getdrawable( 
//                r.drawable.loading_wait)) 
        .build(); 
    return options; 
  } 
  /** 
   * 获取imageloader 单例 
   * 
   * @param context 
   * @return 
   */ 
  public static synchronized imageloader getimageloader(context context) { 
    imageloader imageloader = imageloader.getinstance(); 
    file cachedir = new file(constants.spiccachelocalpath); 
    imageloaderconfiguration config = new imageloaderconfiguration.builder( 
        context).diskcache(new unlimiteddiskcache(cachedir)) 
        .threadpoolsize(3) 
        .diskcacheextraoptions(480, 320, null) 
        .build(); 
    imageloader.init(config); 
    return imageloader; 
  } 
} 

使用方法

displaymetrics dm = getactivity().getresources().getdisplaymetrics(); 
    recommendview rv = new recommendview(getactivity(),dm.widthpixels ,(dm.widthpixels)/2); 
    headviewpager.addview(rv); 

以上所述是小编给大家介绍的android简单实现无限滚动自动滚动的viewpager,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网