Android ViewPager实现无限循环滑动

最近做项目需要实现一个类似于淘宝、京东首页那种滑动效果的广告。于是想到使用ViewPager,但是ViewPager本身是不支持无限左右滑动的,所以需要自己实现。目前实现无限滑动的思路大体有两个:

1、将viewpager上限设置成一个很大的数,第一个页面设置到中间。然后滑动的时候,用当前的序号与viewpager页面数取余得到目标页面的序号,然后显示出来。理论上一个人不会无聊到一直左滑或者右滑。因此可以模拟无限循环。

2、假设viewpager中有四个页面,分别为A、B、C、D。然后在A左边添加一个页面D,在D右边添加一个页面A,变成 DA、B、C、DA。当滑到D时跳转到D,滑到A时跳转到A

第一种并不是实现了真正意义上的无限循环,但是效果比较好,页面切换的时候也不会出现跳转闪烁的情况。

第二种虽然是真正的无限循环,但是需要在开头结尾添加元素,这样就会造成其他问题,比如图片下方跟随图片切换的小圆点的设置就会比较复杂。更新数据的时候也比较费劲。而且还会在切换页面时出现闪烁,影响用户体验。因此选择第一种实现方案。

首先,在activity_main.xml中添加一个viewpager

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v4.view.ViewPager
        android:id="@+id/main_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    </android.support.v4.view.ViewPager>
</RelativeLayout>
再添加一个index_pager_image_item.xml文件。作为viewpager的页面。

<?xml version="1.0" encoding="utf-8"?>
<!--这是主页内容最上方viewpager的子控件布局-->
<LinearLayout 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/index_viewpager_item_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />
</LinearLayout>

然后写一个MyAdapter类继承FragmentPagerAdapter。在其中重写getItem、getCount、instantiateItem三个方法。

public class MyAdapter extends FragmentPagerAdapter {

    private List<Fragment>fragmentList;
    private int count;//设定的上限

    public MyAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragmentList = fragments;
        this.count = fragmentList.size() * 200;//上限等于页面数的200倍
    }

    public MyAdapter(FragmentManager fm) {
        super(fm);
    }


    @Override
    public Fragment getItem(int position) {
        //在这里不处理position的原因是因为getItem方法在
        //instantiateItem方法中调用。只要在调用前处理
        //position即可,以免重复处理
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return count;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        //处理position。让position落在[0,fragmentList.size)中
        position = position % fragmentList.size();
        //调用原来的方法
        return super.instantiateItem(container, position);

    }
}


最后在MainActivity中初始化数据并给viewpager设置adapter即可。

public class MainActivity extends AppCompatActivity {

    private ViewPager mainViewPager;
    private List<Fragment> fragments;
    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mainViewPager = (ViewPager) findViewById(R.id.main_viewpager);
        initFragment();//初始化数据
        //设置adapter
        mainViewPager.setAdapter(new MyAdapter(this.getSupportFragmentManager(),fragments));
        //将第一个位置设置到中间序号处。这样就可以实现开始就能向右滑
        mainViewPager.setCurrentItem(fragments.size() * 100);
    }

    private void initFragment() {
        fragments = new ArrayList<>();
        IndexViewPagerFragment fragment;

        fragment = new IndexViewPagerFragment(R.layout.index_pager_image_item, R.drawable.ads001);
        fragments.add(fragment);

        fragment = new IndexViewPagerFragment(R.layout.index_pager_image_item, R.drawable.ads002);
        fragments.add(fragment);

        fragment = new IndexViewPagerFragment(R.layout.index_pager_image_item, R.drawable.ads003);
        fragments.add(fragment);

        fragment = new IndexViewPagerFragment(R.layout.index_pager_image_item, R.drawable.ads004);
        fragments.add(fragment);

    }
}


存在问题:viewpager中的页面数不能少于四个。否则会出现报错或者无法加载的情况。

点击下载源码




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值