当前位置: 首页 > 编程笔记 >

Android ViewPager无限循环滑动并可自动滚动完整实例

夏侯俊美
2023-03-14
本文向大家介绍Android ViewPager无限循环滑动并可自动滚动完整实例,包括了Android ViewPager无限循环滑动并可自动滚动完整实例的使用技巧和注意事项,需要的朋友参考一下

对于ViewPager 广告页这个功能很多APP都有这个功能在网上也看过一些资料,我就在这把我自己完整的实现方法写出来吧

基础的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:id="@+id/top_item"
  android:orientation="vertical">

    <android.support.v4.view.ViewPager
      android:layout_width="match_parent"
      android:layout_height="180dp"
      android:id="@+id/top_vp"

      ></android.support.v4.view.ViewPager>

</LinearLayout>

很简单 仅仅是一个ViewPager

接下来简单的设置一下ViewPager的Adapter 添加ImageView

public class MainActivity extends AppCompatActivity {

  private ViewPager topVp;
  private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模拟存放要展示的图片
  private List<ImageView> imageViews ;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initImageViews();
    initVp();
  }

  /**
   * 初始化图片资源
   */
  private void initImageViews() {
    imageViews = new ArrayList<>();
    for(int i = 0;i<images.length;i++){
      ImageView imageView = new ImageView(this);
      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
      imageView.setImageResource(images[i]);
      imageViews.add(imageView);
    }
  }

  private void initVp() {

    topVp = (ViewPager) findViewById(R.id.top_vp);
    topVp.setAdapter(new PagerAdapter() {
      @Override
      public int getCount() {
        return imageViews.size();
      }

      @Override
      public boolean isViewFromObject(View view, Object object) {
        return view==object;
      }

      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(imageViews.get(position));
      }

      @Override
      public Object instantiateItem(ViewGroup container, int position) {
        container.addView(imageViews.get(position));
        return imageViews.get(position);
      }
    });
  }

}

上述是最基础的一个ViewPager 下面我们就在这个基础上改造就可以了

实现无限循环滑动:

这里我事先循环滑动的方式很简单 就是把 adapter的count 设置为一个很大的值 这样 让它滑不到头 然后切换图片 就可以实现 虽然方法比较LOW 但是效果还是可以的

代码在基础的ViewPager下修改如下 :

public class MainActivity extends AppCompatActivity {

  private ViewPager topVp;
  private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模拟存放要展示的图片
  private List<ImageView> imageViews ;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initImageViews();
    initVp();
  }

  /**
   * 初始化图片资源
   */
  private void initImageViews() {
    imageViews = new ArrayList<>();
    for(int i = 0;i<images.length;i++){
      ImageView imageView = new ImageView(this);
      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
      imageView.setImageResource(images[i]);
      imageViews.add(imageView);
    }
  }

  private void initVp() {

    topVp = (ViewPager) findViewById(R.id.top_vp);
    topVp.setAdapter(new PagerAdapter() {
      @Override
      public int getCount() {
//        return imageViews.size(); 修改如下
        return 10000;
      }

      @Override
      public boolean isViewFromObject(View view, Object object) {
        return view==object;
      }

      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
//        container.removeView(imageViews.get(position%imageViews.size())); 删除此句 此句不删除 会出现 滑动中 布局消失的情况 因为被移除了 此处这样修改会影响一些性能。。。。。
      }

      @Override
      public Object instantiateItem(ViewGroup container, int position) {
//        container.addView(imageViews.get(position));
//        return imageViews.get(position); 修改如下
        try {
          container.addView(imageViews.get(position%imageViews.size()));
        }catch (Exception e){

        }
        return imageViews.get(position%imageViews.size());
      }
    });
  }

}

这样 之后就可以实现无限循环右滑了 但是在程序刚启动 是 无法向左滑动的 要解决 很简单 只需要在开始的时候

viewPager.setCurrentItem(1000*imageViews.size());

即可 这样 就可以 实现 无限左右滑了

自动定时循环滑动:

下面增加自动定时左右滑动的功能

要实现自动滑动 最主要的是 实现定时器功能我这里使用 Handler+Runnable的方法在上述代码的基础上 修改 如下:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initImageViews();
    initVp();
    handler = new Handler();
    handler.postDelayed(new TimerRunnable(),5000);
  }

  class TimerRunnable implements Runnable{

    @Override
    public void run() {
      int curItem = topVp.getCurrentItem();
      topVp.setCurrentItem(curItem+1);
      if (handler!=null){
        handler.postDelayed(this,5000);
      }
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    handler = null; //此处在Activity退出时及时 回收
  }

这之后 就可以实现自动滑动了

添加左下角圆形小按钮:

接下来添加 左下角的导航小原点

首先 修改布局 :

<?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:id="@+id/top_item"
  android:orientation="vertical">
  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="180dp">


    <android.support.v4.view.ViewPager
      android:layout_width="match_parent"
      android:layout_height="180dp"
      android:id="@+id/top_vp"

      ></android.support.v4.view.ViewPager>
    <LinearLayout
      android:id="@+id/lin_points"
      android:layout_marginBottom="10dp"
      android:layout_marginLeft="10dp"
      android:layout_alignParentBottom="true"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      >

    </LinearLayout>
  </RelativeLayout>


</LinearLayout>

我们需要的原点 要放在 LinearLayout布局中

主要原理 就是向这个LinearLayout中动态添加 小圆点 即可

public class MainActivity extends AppCompatActivity {

  private ViewPager topVp;
  private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模拟存放要展示的图片
  private List<ImageView> imageViews ;
  private List<TextView> txtPoints;
  private LinearLayout lin_points;
  private Handler handler;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lin_points = (LinearLayout) findViewById(R.id.lin_points);
    initImageViews();
    initVp();

    initCircle();
    /*
     * 计时器
     */
    handler = new Handler();
    handler.postDelayed(new TimerRunnable(),5000);
  }

  /**
   * 初始化小圆点
   */
  private void initCircle() {
    txtPoints = new ArrayList<>();
    int d = 20;
    int m = 7;
    for (int i = 0; i < imageViews.size(); i++) {
      TextView txt = new TextView(this);
      if (i == 0) {
        txt.setBackgroundResource(R.drawable.point_pink);
      } else {
        txt.setBackgroundResource(R.drawable.point_grey);
      }
      LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d, d);

      params.setMargins(m, m, m, m);
      txt.setLayoutParams(params);
      txtPoints.add(txt);
      lin_points.addView(txt);
    }
  }

  class TimerRunnable implements Runnable{

    @Override
    public void run() {
      int curItem = topVp.getCurrentItem();
      topVp.setCurrentItem(curItem+1);
      changePoints((curItem+1)%imageViews.size());
      if (handler!=null){
        handler.postDelayed(this,5000);
      }
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    handler = null;
  }

  /**
   * 初始化图片资源
   */
  private void initImageViews() {
    imageViews = new ArrayList<>();
    for(int i = 0;i<images.length;i++){
      ImageView imageView = new ImageView(this);
      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
      imageView.setImageResource(images[i]);
      imageViews.add(imageView);
    }
  }


  private void initVp() {

    topVp = (ViewPager) findViewById(R.id.top_vp);
    topVp.setAdapter(new PagerAdapter() {
      @Override
      public int getCount() {
//        return imageViews.size(); 修改如下
        return 10000;
      }

      @Override
      public boolean isViewFromObject(View view, Object object) {
        return view==object;
      }

      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
//        container.removeView(imageViews.get(position%imageViews.size())); 删除此句
      }

      @Override
      public Object instantiateItem(ViewGroup container, int position) {
//        container.addView(imageViews.get(position));
//        return imageViews.get(position); 修改如下
        try {
          container.addView(imageViews.get(position%imageViews.size()));
        }catch (Exception e){

        }
        return imageViews.get(position%imageViews.size());
      }
    });

    topVp.setCurrentItem(imageViews.size()*1000);

    topVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

      }

      @Override
      public void onPageSelected(int position) {
        changePoints((position)%imageViews.size());
      }

      @Override
      public void onPageScrollStateChanged(int state) {

      }
    });
  }
  public void changePoints(int pos) {
    if (txtPoints != null) {
      for (int i = 0; i < txtPoints.size(); i++) {
        if (pos == i) {
          txtPoints.get(i).setBackgroundResource(R.drawable.point_pink);
        } else {
          txtPoints.get(i).setBackgroundResource(R.drawable.point_grey);
        }
      }
    }
  }
}

给ViewPager添加切换动画:

topVp.setPageTransformer(true,new CubeOutTransformer());

调用 此行代码 可以添加 后面的TransFormer类 是自定义的过渡效果类

控制ViewPager 自动切换的速度

ViewPager自身的切换速度是写死的,我们无法修改,但是我们可以通过源码看到,ViewPager的切换速度是通过 Scroller类 控制的,而Scroller类中是可以设置过渡的时间的,因此 我们可以通过自己创建一个Scroller类 继承 Scroller 然后 通过反射 把ViewPager中的mScroller属性 设置成我们自己的可以设置时间的Scroller类即可

下面是代码:

public class FixedSpeedScroller extends Scroller {
  private int mDuration = 1500;

  public FixedSpeedScroller(Context context) {
    super(context);
  }

  public FixedSpeedScroller(Context context, Interpolator interpolator) {
    super(context, interpolator);
  }

  @Override
  public void startScroll(int startX, int startY, int dx, int dy, int duration) {
    // Ignore received duration, use fixed one instead
    super.startScroll(startX, startY, dx, dy, mDuration);
  }

  @Override
  public void startScroll(int startX, int startY, int dx, int dy) {
    // Ignore received duration, use fixed one instead
    super.startScroll(startX, startY, dx, dy, mDuration);
  }

  public void setmDuration(int time) {
    mDuration = time;
  }

  public int getmDuration() {
    return mDuration;
  }
}

反射修改ViewPager属性:

 try {
      Field field = ViewPager.class.getDeclaredField("mScroller");
      field.setAccessible(true);
      scroller = new FixedSpeedScroller(getActivity());
      scroller.setmDuration(1000);
      field.set(topVp, scroller);
    } catch (Exception e) {
//      e.printStackTrace();
      System.out.println("aaaaaa错误啦");
    }

这样就可以控制速度了

好了,Android ViewPager广告页可无限循环滑动并可自动滚动带有小圆点的功能基本就实现了,具体参数大家可以自行设定

 类似资料:
  • 本文向大家介绍Android简单实现无限滚动自动滚动的ViewPager,包括了Android简单实现无限滚动自动滚动的ViewPager的使用技巧和注意事项,需要的朋友参考一下 经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底。所以试着封装一个比较好用的ViewPager 效果如下: 简

  • 本文向大家介绍Android ViewPager无限循环实现底部小圆点动态滑动,包括了Android ViewPager无限循环实现底部小圆点动态滑动的使用技巧和注意事项,需要的朋友参考一下 页面拖动到最后一页 再向下滑动回复到 第一页,第一页向前滑动回到 最后一页 同时,底部红色小圆点随着页面的滑动距离比例随时改变位置 布局: 其中red_circle是用shape绘制的红色小圆点 最后的Lin

  • 本文向大家介绍jQuery自定义滚动条完整实例,包括了jQuery自定义滚动条完整实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jQuery自定义滚动条实现方法。分享给大家供大家参考,具体如下: 很多时候,由于美观上的考虑,往往需要自定义各种各样的滚动条,因此,本人做了一个demo 运行效果截图如下: 以下是代码部分: 希望本文所述对大家jQuery程序设计有所帮助。

  • 无限滚动用来在页面滚动到接近底部时加载新内容或进行其他操作。 在底部的无限滚动 你只需在可滚动的容器上添加“infinite-scroll”类,一般是页面滚动区域 - div.content <style type="text/css"> .infinite-scroll-preloader { margin-top:-20px; } </style> <heade

  • 无限滚动用来在页面滚动到接近底部时加载新内容或进行其他操作。 无限滚动HTML结构 你只需在可滚动的容器上添加“infinite-scroll”类,一般是页面滚动区域 - <div class="page-content">: <div class="page"> <div class="page-content infinite-scroll" data-distance="100">

  • 我有一个问题与自动滚动在滚动视图。 在我的例子中,有两个Recyclerview。第一个循环视图,水平滚动,第二个垂直滚动。第一个循环视图仅用于拖动,第二个循环视图只用于拖放。两个循环视图都在ScrollView中,所以我在第二个循环视图中禁用了垂直滚动。我在第二个Recyclerview的项目中添加了DragListener。每个项目都有一个拖动侦听器,因此我在拖放项目时添加/替换项目。 所以我