View pager实现自动轮播图

2024-01-04 06:20
文章标签 实现 自动 view 轮播 pager

本文主要是介绍View pager实现自动轮播图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

轮播图

首先放上一张常见的轮播图样图:
这是一张神级图片
** 如图这就是常见的轮播图,对于这样的轮播图该怎么实现?
** 下面开始进入正题:
** 看图,通常这样的页面会滚动播放,同时页面的切换也是平滑的,那么我们首先想到的是应该用View Pager,是的,你没有看错,就是ViewPager。
** 首先先贴上XML文件,布局如下:

<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" ><RelativeLayout
        android:layout_width="match_parent"android:layout_height="160dp" ><android.support.v4.view.ViewPager
            android:id="@+id/viewpager"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayout
            android:layout_width="match_parent"android:layout_height="40dp"android:padding="5dp"android:orientation="vertical"android:layout_alignParentBottom="true"android:gravity="center_horizontal"android:background="#66000000" ><TextView
                android:id="@+id/tv_desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@android:color/white"android:singleLine="true"android:text="天王盖地虎, 天王盖地虎, 天王盖地虎, " /><LinearLayout android:id="@+id/ll_point_container"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:orientation="horizontal"></LinearLayout></LinearLayout></RelativeLayout></RelativeLayout>

** 我们将这个布局看成是相对布局,在相对布局中,我们将View Pager充满父布局,同时通常我们的轮播图底部会有一栏文字描述和相对应的小圆点指示器。所以我们采用相对布局,这样才能保证在轮播图底部出现文字和圆点,而文字和圆点,通常都是一个方向的排列,那么我们可以将他们放在竖直的线性布局,这样文字放在小圆点的上方,而小圆点通常为一排,所以我们采用水平的线性布局。
** 接下来就是如何通过java代码去实现这些想法了。
** 首先初始化控件:

private void initViews() {viewPager = (ViewPager) findViewById(R.id.viewpager);viewPager.setOnPageChangeListener(this);// 设置页面更新监听
//      viewPager.setOffscreenPageLimit(1);// 左右各保留几个对象ll_point_container = (LinearLayout) findViewById(R.id.ll_point_container);tv_desc = (TextView) findViewById(R.id.tv_desc);}

** 同时对页面的改变设置监听,在页面切换时可以同步的更换文字描述和对应的小圆点。
初始化控件之后,我们就要将这些控件进行相应对的填充和设置,见下文:

    private void initData() {// 初始化要显示的数据// 图片资源id数组imageResIds = new int[]{R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e};// 文本描述contentDescs = new String[]{"是故圣人一守司其门户,审察其所先后,度权量能,校其伎巧短长。","粤若稽古,圣人之在天地间也,为众生之先。","即欲捭之贵周,即欲阖之贵密。周密之贵微,而与道相追。","捭阖者,道之大化,说之变也;必豫审其变化,吉凶大命系焉。","捭阖之道,以阴阳试之,故与阳言者依崇高,与阴言者依卑小。"};// 初始化要展示的5个ImageViewimageViewList = new ArrayList<ImageView>();ImageView imageView;View pointView;LayoutParams layoutParams;for (int i = 0; i < imageResIds.length; i++) {// 初始化要显示的图片对象imageView = new ImageView(this);imageView.setBackgroundResource(imageResIds[i]);imageViewList.add(imageView);// 加小白点, 指示器pointView = new View(this);pointView.setBackgroundResource(R.drawable.selector_bg_point);layoutParams = new LinearLayout.LayoutParams(5, 5);if(i != 0)layoutParams.leftMargin = 10;// 设置默认所有都不可用pointView.setEnabled(false);ll_point_container.addView(pointView, layoutParams);}}

** 由于是轮播图,所以我们不能如同引导页一样,每一个图都设置一个布局页面,所以我们先将图片的资源ID添加到数组中,同时也将对应的文字添加进文字数组中,然后在初始化要展示的5个轮播图,首先我们通过for循环将初始化要显示的图片,通过资源id设置其背景,(也可以通过setSrc来赋值),将image View添加进集合中,应为我们要通过Adapter才能实现页面的加载和显示,同时将小圆点也加载进圆点的线性布局中。

private void initAdapter() {ll_point_container.getChildAt(0).setEnabled(true);tv_desc.setText(contentDescs[0]);previousSelectedPosition = 0;// 设置适配器viewPager.setAdapter(new MyAdapter());// 默认设置到中间的某个位置int pos = Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2 % imageViewList.size());// 2147483647 / 2 = 1073741823 - (1073741823 % 5)viewPager.setCurrentItem(5000000); // 设置到某个位置}

** 然后我们初始化适配器,要想让View Pager实现轮播,同时也可左右滑动,而不会出现滑到头划不动的情况,我们就可以先将View Pager的position设置为一个比较大的数。这样在前后滑动的时候,通常都不会滑动到头。同时配置适配器。

class MyAdapter extends PagerAdapter{@Overridepublic int getCount() {return Integer.MAX_VALUE;}// 3. 指定复用的判断逻辑, 固定写法@Overridepublic boolean isViewFromObject(View view, Object object) {
//          System.out.println("isViewFromObject: "+(view == object));// 当划到新的条目, 又返回来, view是否可以被复用.// 返回判断规则return view == object;}// 1. 返回要显示的条目内容, 创建条目@Overridepublic Object instantiateItem(ViewGroup container, int position) {System.out.println("instantiateItem初始化: " + position);// container: 容器: ViewPager// position: 当前要显示条目的位置 0 -> 4//          newPosition = position % 5int newPosition = position % imageViewList.size();ImageView imageView = imageViewList.get(newPosition);// a. 把View对象添加到container中container.addView(imageView);// b. 把View对象返回给框架, 适配器return imageView; // 必须重写, 否则报异常}// 2. 销毁条目@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {// object 要销毁的对象System.out.println("destroyItem销毁: " + position);container.removeView((View)object);}}

创建适配器,实现4个必须实现的方法,第一个getCount()返回的时view Pager的大小,也就是轮播图片的数量。但是看上图我们返回的是Int的类型的最大值,这样就是i为了避免在图片轮播的时候出现滑到头,无法滑动的情况。
** 第二个方法,isViewFromObject(),就是在view pager滑动时,滑动到新的条目时,对比缓存中的数据,是否缓存中存在,如果缓存中存在,那么就从缓存中取出,如果没有,则加载该视图。

** 第三个方法:instantiaeItem(),返回要显示的条目内容,创建条目,见上图,我们先将position%图片集合的大小,是因为我们在第一个方法中将view Pager的大小设置的很大,所以这里如果直接使用获取到的position就会很大,而如果要通过图片集合image View List取得对应的图片,由于集合的大小为5,那么就会出现空指针的情况,所以我们将position先转换为0-5以内,再取出对应的imageView,同时将image View添加进container容器中,container容器的作用就是将该imageView保存到缓存中,同时将该image View返回出去,创建条目。

** 第四个方法:destroy Item(),将缓存中的不需要的imageView删除。注意:这里是重点——–看我划重点了:第三个方法和第四个方法中的position不是同一个值啊,第三个方法中position是当前view Pager显示的image View对应的position,而第四个方法的position则不是,那到底是多少呢? 看下图↓
view Pager缓存分析
** 红的的是当前的显示图片,而通常view Pager中,会缓存当前布局的前后各一个布局,这样才能保证再图片滑动的时候可以无缝链接,这就是view Pager的默认初始化范围,如果先要增加默认初始化范围可以使用这个方法→:Viewpager.setOffscreenPageLimit(2),其中的参数2,就是将初始化范围增加为当前显示布局的前后各2个布局。所以这个destroy Item中的position就是当前需要移除的布局,如上图,如果第3个布局往左滑动,第四个布局显示为当前布局,那么这里的position就为2,因为2超出了缓存范围,所以要去掉,如果布局3往右滑动,则这里的position就变为4.所以说这个方法的position的值与第三个方法的position的值不对应。
**接下来就是文本和小圆点的加载了:

@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {// 滚动时调用}@Overridepublic void onPageSelected(int position) {// 新的条目被选中时调用System.out.println("onPageSelected: " + position);int newPosition = position % imageViewList.size();//设置文本tv_desc.setText(contentDescs[newPosition]);//      for (int i = 0; i < ll_point_container.getChildCount(); i++) {
//          View childAt = ll_point_container.getChildAt(position);
//          childAt.setEnabled(position == i);
//      }// 把之前的禁用, 把最新的启用, 更新指示器ll_point_container.getChildAt(previousSelectedPosition).setEnabled(false);ll_point_container.getChildAt(newPosition).setEnabled(true);// 记录之前的位置previousSelectedPosition  = newPosition;}@Overridepublic void onPageScrollStateChanged(int state) {// 滚动状态变化时调用}

**这里我们通过view Pager滑动时的监听来进行文本和小圆点的加载,通常这里我们选用onPageSelected()来加载,因为该方法是在新的条目被选中时调用,其他的两个方法的调用事件不满足条件,不能实现文字和小圆点的准确加载。
**接下来就是如何实现自动的轮播了,

// 开启轮询new Thread(){public void run() {isRunning = true;while(isRunning){try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}// 往下跳一位runOnUiThread(new Runnable() {@Overridepublic void run() {System.out.println("设置当前位置: " + viewPager.getCurrentItem());viewPager.setCurrentItem(viewPager.getCurrentItem()+1);                         }});}};}.start();

**要想实现定时的轮播,那么就要让线程sleep一定的时间,但是不能在主线程sleep,主线程等待,用户就无法进行操作,所以开辟一个子线程进行轮播,但是由于轮播又是已是一个需要刷新Ui的操作,那么我们就需要一个handler来接收刷新Ui的消息,在主线程中刷新UI,也可以通过上面这种方式来进行刷新UI的操作,通过runOnUiThread(new Runnable())的方法,开辟一个刷新UI线程,在这个线程中的run方法中刷新UI.
**好了,这就是一个简单的实现广告轮播图的View pager的实现方法。

这篇关于View pager实现自动轮播图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/568410

相关文章

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

Conda虚拟环境的复制和迁移的四种方法实现

《Conda虚拟环境的复制和迁移的四种方法实现》本文主要介绍了Conda虚拟环境的复制和迁移的四种方法实现,包括requirements.txt,environment.yml,conda-pack,... 目录在本机复制Conda虚拟环境相同操作系统之间复制环境方法一:requirements.txt方法

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置