Android ViewPager实现无限循环滑动_viewpager2 左右滑动无限循环-程序员宅基地

技术标签: java  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中的页面数不能少于四个。否则会出现报错或者无法加载的情况。

点击下载源码




版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/greyfreedom/article/details/50240417

智能推荐

数据保护条例框架与wik解读 第一章 GDPR 个人数据的控制者和处理者必须采取适当的技术和组织措施以实施数据保护原则。在设计和构建处理个人数据的业务流程时,必须考虑到这些原则,并提供保护数据的-程序员宅基地

数据保护条例框架与wik解读GDPR个人数据的控制者和处理者必须采取适当的技术和组织措施以实施数据保护原则。在设计和构建处理个人数据的业务流程时,必须考虑到这些原则,并提供保护数据的保护措施(例如,在适当的情况下使用假名或完全匿名化)。数据控制器必须在设计信息系统时考虑到隐私,例如默认情况下使用最高可能的隐私设置,以使数据集默认情况下不公开可用,并且不能用于标识主题。除非根据法...

mac安装adb-程序员宅基地

搭建adb环境,需要安装homebrew1、安装hombrewruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”直接安装提示:curl: (7) Failed to connect to raw.githubusercontent.com port 443: Co...

pygame的冲突检测_pygame 重合检测-程序员宅基地

一、精灵与精灵之间的冲突检测1.两个精灵之间的矩形检测在只有两个精灵的时候我们可以使用pygame.sprite.collide_rect()函数来进行一对一的冲突检测。这个函数需要传递2个参数,并且每个参数都是需要继承自pygame.sprite.Sprite。举个例子:spirte_1 = MySprite("sprite_1.png",200,200,1)sprite_2..._pygame 重合检测

打开我的收藏夹 -- Python数据分析杂谈_从根节点开始,匹配name节点_看,未来的博客-程序员宅基地

文章目录玩转json什么是jsonPython中的Json模块获取json中的某个数据Jpathnumpy使用ndarray创建数组的好处numpy基本操作文本数据去重数据采集方式好几天没写啥实在的干货了,今天见六不废话了,直接上干货。玩转json什么是jsonJson是一种轻量级的数据交换格式,具有数据格式简单,读写方便易懂等很多优点。用它来进行前后端的数据传输,大大的简化了服务器和客户端的开发工作量。如果说现在对json还没有什么概念的朋友,了解了以上内容之后,再了解一下它是字典形式的即可._从根节点开始,匹配name节点

牛人的经历_多分钟一些牛人背后的经历,阅历-程序员宅基地

有人工作,有人继续上学,大家千万不要错过这篇文章,能看到这篇文章也是一种幸运,真的受益匪浅,对我有很大启迪,这篇文章将会改变我的一生,真的太好了,希望与有缘人分享,也希望对有缘人有所帮助!看完之后有种“相见恨晚”的感觉,特别激动,希望大家好好的珍藏这篇文章,相信多年以后,再来看这篇文章,一定有不同的感觉。 正如"打工皇帝"唐骏说:"我觉得有两种人不要跟别人争利益和价值回报。第一种_多分钟一些牛人背后的经历,阅历

C++ 11 initializer_list关键字-程序员宅基地

initializer_list是C++11提供的新类型,定义在头文件中。 用于表示某种特定类型的值的数组,和vector一样,initializer_list也是一种模板类型。templateclass T >class initializer_list;要介绍initializer_list的使用,有必要先谈一谈列表初始化。C++11扩大了初始化列表的适用范围,使其可用于所有

随便推点

Spring Cloud底层原理_spring cloud网关底层-程序员宅基地

概述毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术。不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓。因此本文将通过大量的手绘图,给大家谈谈Spring Cloud微服务架构的底层原理。实际上,Spring Cloud是一个全家桶式的技术栈,包含了很多组件。本文先从其最核心的几个组件入手,来剖析..._spring cloud网关底层

MySQL Workbench 执行更新或删除操作时出现 1175错误 安全更新限制_workbench 删除数据 安全机制-程序员宅基地

错误信息:Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Queries and_workbench 删除数据 安全机制

#UML统一建模语言#(Unified Modeling Language)类图Class_航班的属性有哪些uml-程序员宅基地

目录定义用途组成元素以及元素之间的关系说明类名类属性列表类操作列表继承关联关联(Association)关系聚合(Aggregat ion)关系依赖(Dependency)关系泛化(Generalization)关系实现(Realization)关系画法例子定义类图 Class diagram通过显示出系统的类以及这些类之间的关系来表..._航班的属性有哪些uml

Java笔记---将java程序打包成exe程序_cefsharp java打包exe-程序员宅基地

一、前言我们编写好一个 C/S 的 Java 程序后,虽然我们可以使用 Eclipse 来启动我们的程序。但是当我们需要将程序运行在其他电脑上呢?难道,我们需要在安装JDK,然后安装Eclipse再来运行?这样肯定是不符合我们的需求的。那么我们如何将编号的程序打包成Windows常用的 .exe 程序呢?二、准备资源Fat Jar: 一款可以集成到 Eclipse 中的打包插件,..._cefsharp java打包exe

(C语言)验证哥德巴赫猜想,输入一个大于6的偶数,输出这个数能被分解为哪两个质数的和_问题描述: 哥德巴赫猜想:一个充分大的偶数 n(n≥6),可以分解为两个质数之和。下-程序员宅基地

(C语言)验证哥德巴赫猜想,输入一个大于6的偶数,输出这个数能被分解为哪两个质数的和,如10=3+7,12+5+7。// 质数:除了1和自身,不能被任何数整除的数 #include<stdio.h>#include<stdlib.h>int judge(int n){//用于判断是否为质数,是质数则返回1,不是质数则返回0 for(int i=2;i<n;i++){ if(n%i==0){ return 0; } return 1; }} i_问题描述: 哥德巴赫猜想:一个充分大的偶数 n(n≥6),可以分解为两个质数之和。下

推荐文章

热门文章

相关标签