ViewPager详解(二)广告轮播图

Android中ViewPager支持一屏多个View、切换动画以及无限滚动 1. 首先看一下最终的效果图2. 需求拆解第一眼看见上面的效果,是不是有些朋友觉得这个效果很酷,有的高手会觉得这个效果很简单。笔者昨天刚拿到需求的时候,最开始也是觉得这个很简单,可是越分析越发现好像实现出来并不是那么容易。单个的效果可能很简单,但是这么多的效果叠在一起,可能就比较复杂了。我简单得将这个效果任务拆解一下: 一屏要展示3个View,支持左右滑动 屏幕中间两侧的View移向中间时,会有一个 阅读详情

http://www.jianshu.com/p/48f63c537ae5


http://www.jianshu.com/p/d411d687f46d


显示的效果请往下看,先说一下需求,可以自动轮播,按下停止轮播,松手开始轮播,不可见时停止轮播,自动轮播时带动画,手动滑动时不带动画,点击时要有水波纹效果,下拉刷新回到第一页,页面不能卡顿等等。参考了一些网上的想法,结合自己的认知,总结如下。


先上效果图

自定义BannerView控件

为了以后开发的方便,这里将Banner封装成一个控件来使用,以后就可以直接在布局里引用。

做这种轮播效果一般采用的都是ViewPager,所以这个控件也是对ViewPager的封装,为了解耦,这里没有把适配器放在BannerView,只是提供了基类适配器和接口,使用很方便。

讲一下具体如何实现封装:
第一步:自定义控件,实现构造,初始化属性和视图。

  • 基于需求,先定义了页面边距,主页面占比,缩放比例,轮播时长,是否动画轮播等等属性,通过引用attrs的方式,在布局里赋值,并且提供set方法在代码里设置。
   private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BannerView);
        pageMargin = (int) a.getDimension(R.styleable.BannerView_bannerPageMargin, pageMargin);
        pagePercent = a.getFloat(R.styleable.BannerView_bannerPagePercent, pagePercent);
        scaleMin = a.getFloat(R.styleable.BannerView_bannerPageScale, scaleMin);
        alphaMin = a.getFloat(R.styleable.BannerView_bannerPageAlpha, alphaMin);
        ...
        a.recycle();
    }
  • 定义了基本属性后,将ViewPager视图填充到控件容器里,ViewPager布局里需要使用clipChildren属性来控制系统绘制View的范围,在ViewPager和它的父容器里都设置clipChildren=false。这样指定了主页面占比后,左右两边的Page就会进行绘制。
      private void initView() {
          mRootView = LayoutInflater.from(getContext()).inflate(R.layout.banner_view, this);
          mViewPager = (ViewPager) mRootView.findViewById(R.id.viewPager);
          LayoutParams params = (LayoutParams) mViewPager.getLayoutParams();
          params.width = (int) (getScreenWidth() * pagePercent);
          params.gravity = Gravity.CENTER;
          mViewPager.setLayoutParams(params);
          mViewPager.setPageMargin(pageMargin);
          mViewPager.setPageTransformer(false, new BannerPageTransformer());
          mViewPager.setOffscreenPageLimit(5);
          // 自动轮播任务
          mScrollTask = new AutoScrollTask();
          // 如果动画轮播
          if (isAnimScroll) {
              setAnimationScroll((int) mAnimDuration);
          }
      }

第二步:滑动动画实现

  • 众所周知,谷歌已经提供了ViewPager的滑动动画设置接口setPageTransformer(),并且他自己也实现了三种基本的滑动滑动。需要自定义动画时只需实现ViewPager.PageTransformer接口,并实现transformPage()方法。

  • 设计稿中的动画要求是,滑动时左侧缩小,主页随着滑动百分比缩小,右侧随着滑动百分比放大。transformPage方法中提供了主页所在的position=0.0,左侧位置百分比position<0,右侧位置百分比position>0,通过这个position可以动态计算出各个页面的缩放比。

      public void transformPage(View page, float position) {
         // 不同位置的缩放和透明度
         float scale = (position < 0)
                  ? ((1 - scaleMin) * position + 1)
                  : ((scaleMin - 1) * position + 1);
         float alpha = (position < 0)
                  ? ((1 - alphaMin) * position + 1)
                  : ((alphaMin - 1) * position + 1);
         // 保持左右两边的图片位置中心
         if (position < 0) {
              ViewCompat.setPivotX(page, page.getWidth());
              ViewCompat.setPivotY(page, page.getHeight() / 2);
          } else {
              ViewCompat.setPivotX(page, 0);
              ViewCompat.setPivotY(page, page.getHeight() / 2);
          }
          Log.d(TAG, "transformPage: scale=" + scale);
          ViewCompat.setScaleX(page, scale);
          ViewCompat.setScaleY(page, scale);
          ViewCompat.setAlpha(page, Math.abs(alpha));
      }

第三步:无限自动轮播和轮播动画处理

  • 无限轮播可用线程池,定时器,Handler等等实现,这里采用最简单的Handler实现。首先自定义一个轮播任务,实现Runnable接口,在run方法里使用Handler发送延时消息来不停轮播,并且提供start方法和stop方法开启和停止轮播。在初始化视图完毕时,开启轮播。
     @Override
      protected void onAttachedToWindow() {
          super.onAttachedToWindow();
          // 视图初始化完毕,开始轮播任务
          if (mScrollTask == null) mScrollTask = new AutoScrollTask();
          if (isAutoScroll) startAutoScroll();
      }
  • ViewPager滑动是没有延时的,谷歌也没有提供具体的接口去实现延时滑动。所以这里使用反射去重新设置ViewPager的滑动世间。自动轮播时,需求动画延时滑动,但是手动滑动时需要原生的滑动,所以根据使用时间差和滑动时间来控制自动和手动滑动。

    public void startScroll(int startX, int startY, int dx,
                                          int dy, int duration) {
        // 如果手动滚动,则加速滚动
           // TODO 使用这种设置极不稳定,需要抽离
           if (System.currentTimeMillis() - mRecentTouchTime > mScrollDuration && isAnimScroll) {
               // 动画滑动
               duration = during;
           } else {
               // 手势滚动
               duration /= 2;
    
           }
           super.startScroll(startX, startY, dx, dy, duration);
       }

BannerView的基类适配器封装
  • BannerView封装的是ViewPager,所以基类适配器BannerBaseAdapter封装的也是PagerAdapter,由于适配器涉及到数据和视图,所以基类里将所有都封装好,只留数据和视图留给子类去实现。除此之外,页面的点击,按下和抬起也在适配器实现并通过接口暴露出来。
  • 实现父类适配后,只需要指定数据类型和实现展示视图转换数据的方法,加载完数据之后,通过setData方法来重新更新数据即可。
    private class BannerAdapter extends BannerBaseAdapter<BannerBean> {
          public BannerAdapter(Context context) {
              super(context);
          }
          @Override
          protected int getLayoutResID() {
              return R.layout.item_banner;
          }
          @Override
          protected void convert(View convertView, BannerBean data) {
              setImage(R.id.pageImage, data.imageRes);
              setText(R.id.pageText, data.title);
          }
    }

使用教程
  • 拷贝BannerView全路径到布局里,使用attrs指定属性

    <com.pinger.widget.banner.BannerView
        android:id="@+id/bannerView"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:bannerPageAlpha="1.0"
        app:bannerPageMargin="8dp"
        app:bannerPagePercent="0.8"
        app:bannerPageScale="0.8"
        app:bannerAnimScroll="true"
        app:bannerAutoScroll="true"
        app:bannerScrollDuration="4000"
        app:bannerAnimDuration="1500"/>
  • 在代码中设置适配器和设置页面的触摸监听,初始化数据之后,更新数据

  final BannerView bannerView = (BannerView) findViewById(R.id.bannerView);
  bannerView.setAdapter(mAdapter = new BannerAdapter(this));
  initData();  // 初始化数据
  mAdapter.setData(mDatas);
  mAdapter.setOnPageTouchListener(...);

Demo下载地址

欢迎大家访问我的简书,博客和GitHub。


Android-ViewPager实现广告轮播图 Android-ViewPager实现广告轮播图,集成过程请见优快云博客介绍https://blog.youkuaiyun.com/weimeig/article/details/80242315 立即下载

相关推荐

Android:ViewPager轮播图

自定义的viewpager,实现功能如下:无限自动轮播,pager点击事件处理,手指长按停止自动轮播,手指抬起恢复自动轮播;

惊!关于BaseAdapter你可能不知道的真相(多种type的情况下)

在实现一些app的聊天功能的时候,经常要用到一个ListView显示多种布局。很多书本或者教程都有现成的模板代码,就是在BaseAdapter里面,重写getViewTypeCount,getItemViewType,然后就在getView里面判断具体条目的类型,返回对应的View。就好像下面的代码。 初学的时候非常的不解。代码中对于View 的复用,难道不会造成混乱吗?例如在应该显示左边的聊天...

jackzee的博客 731

安卓的ViewPager广告轮播图实现无限轮播

采用ViewPager实现的广告轮播图,可以实现无限轮播,代码结构清晰易懂

android 无限循环检查,Android_ViewPager_无限循环

ViewPager 实现无线循环ViewPager 无限循环作为Banner来使用是一个很常见的场景,那么它的实现原理是怎么样的呢?相信这一块大家已经都比较熟悉了。话不多说,先上图。效果图原理图其中所有的黑色框用来展示原始的数据集合,为了实现无限循环的效果,这里有一个小把戏,就是在首部添加了一个原始数据集合最后的元素,同时,将原始集合第一个元素添加到了尾部,这样,就重新组成了一个新的数据集合。/*...

weixin_31509753的博客 340

给STM32F103的7寸屏找个新UI:LVGL 8.2裸机移植保姆级教程(附避坑清单)

本文详细介绍了如何将LVGL 8.2裸机移植到STM32F103开发板,特别针对7寸大屏(800×480分辨率)进行优化配置。从环境准备、工程搭建到显示驱动移植、内存优化与性能调优,提供完整的解决方案和避坑清单,帮助开发者快速实现美观的用户界面。

weixin_29181861的博客 413

一文看懂英伟达A100、H100、A800、H800、H20

想要Deepseek私有化部署吗?无论是训练大型AI模型,还是进行高性能计算(HPC),还是Deepseek私有化部署,都需要强大的GPU支持。而英伟达(NVIDIA)作为全球领先的AI芯片制造商,推出了一系列高性能GPU,包括等,广泛应用于AI训练、推理、科学计算等领域。如果想搭建一个属于自己的算力中心,该如何选择合适的GPU?本文将带你详细了解这些GPU的特性,并指导你如何搭建算力中心。一、英伟达算力GPU系列解析1. A100:数据中心AI计算的奠基石:Ampere:6912:432。

【可全包】本人程序员,不需要做任何吹嘘,只是实在写点程序,写点文档,熟悉各类主流框架,SSM,SpringBoot,Flask,Djiango,Mysql,Sqlite,VUE,Uniapp等,各类程序设计专家,优质作者 2万+

跟ViewHolder说再见!实现一个无限轮播图究竟有多简单?

去年8月份,我在Github开源了一个无限循环的轮播图库–BannerViewPager(以下简称BVP)。时至今日,一年多的时间过去了,BVP在大家的支持下已经在GitHub上收获了1.9k的Star。前段时间,我将BVP迁移到了Gitee,也很有幸受到了Gitee官方的认可,并得到了Gitee官方的推荐,短时间内在Gitee上收获了近120个Star。当然,能够却得这么大的成绩离不开大家的支持。另一方面也少不了我对BVP的悉心维护。 BVP最初的目标是做一个全网最好用的轮播图库,让大家用尽可能少的代码实

smily的博客 576

【Unity】ABB CRB 15000 外部引导运动实战:从配置到实时控制

本文详细介绍了ABB CRB 15000协作机器人的外部引导运动(EGM)功能在Unity环境中的实战应用。从RobotStudio配置到Unity实时通信架构,再到EGM运动控制技巧和问题排查,全面解析如何实现机器人的高精度实时控制。通过实际案例展示EGM技术在精密装配等场景中的显著效果,帮助开发者快速掌握这一先进技术。

weixin_29057695的博客 445

Android——支持图片加视频无限轮播的banner

基于https://github.com/youth5201314/banner扩展,图片+视频无限轮播banner Demo地址 https://gitee.com/saqino/pic-video-banner-demo.git 说明 使用大佬的banner控件是很方便的,但是对视频+图片无限轮播的支持较弱,所以决定重写几个类实现功能。 不重写无法实现的原因如下: 无限轮播模式下,item大于1时, adapter会自动增加两个item,一个在最前,一个在最后,这样子做...

Saqino的博客 9886

一文看懂 SAP Integration Suite:从架构治理、接口编排到事件驱动的集成全景

SAP Integration Suite是企业数字化转型中的关键集成平台,通过统一的方法论和工具链解决系统互联、数据对齐和流程协同等复杂问题。其核心能力包括:1)集成评估(Integration Assessment)提供战略规划框架;2)迁移评估(Migration Assessment)支持从传统平台向云的平滑过渡;3)云集成(Cloud Integration)实现日常业务流程编排;4)集成顾问(Integration Advisor)简化B2B标准映射;5)贸易伙伴管理(TPM)优化外部协作流程;

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 501

华为OD技术面真题 - Python开发 - 2

汇总华为OD技术面八股Python八股,高频技术真题并提供详细解答。

qq_45776114的博客 910

RecyclerView嵌套ViewPager实现淘宝搜狐主页广告轮播图

RecyclerView嵌套ViewPager实际上就是RecyclerView复杂布局的实现,给其中一个item设置为ViewPager来实现广告轮播图。既然知道原理 那么我们实现起来也就非常的方便。使用SwipeRefreshLayout对其RecyclerView实现下拉刷新。

xy_liwp的博客 1万+

从零到一:ESP32与豆包大模型的RTC连续对话实现指南

文本实现ESP32S3 SparkBot与豆包大模型的RTC连续对话

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 4364

简单封装弧形广告轮播图(ViewPager+贝塞尔曲线)

前言通过ViewPager和贝塞尔曲线实现了一个弧形广告轮播图。效果图实现方法想要实现这个效果,现在几行代码就可以了:Step 1. Add it in your root build.gradle at the end of repositories:allprojects { repositories { ... maven { u

Simon_Crystin的博客 4271

3D 韩系风格漫剧人设 | GPT-Image2 人设生成【附完整提示词】

宁姚同款清冷剑系美人,极致小巧鹅蛋脸,下颌线紧致纤细流畅,下巴小巧精致收窄,小脸衬得五官格外舒展,韩式水光肌,面部精细水光高光,鼻梁高光、鼻尖高光、面中苹果肌高光、唇珠高光,红棕色长卷发偏分大波浪,垂在一侧肩前,发量蓬松。发量丰厚蓬松有体积感,不贴头皮,几缕碎发自然垂落脸侧修饰脸型,长度过胸及背,发丝柔顺丝滑卷度自然,发尾自然垂落,身穿香槟色缎面挂脖长裙,挂脖设计无袖露肩露背,上半身围裹式荡领胸口垂褶,腰部堆褶收腰,修身直筒包臀裙长度到脚踝,缎面光泽感强垂坠感好,极简剪裁。纯白色背景,3D漫剧写实厚涂风。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 123

【从零开始学习 UVM】1.1、UVM 概述 —— Preface

【从零开始学习 UVM】1.1、UVM 概述 —— Preface

努力,加油每一天鸭~ 824

一个例子带你深入理解ViewPager之广告轮播条的实现

ViewPager是我们android开发过程中再平常不过的例子了,几乎所有的app,都或多或少的包含了ViewPager,今天我们就来看看ViewPager到底是怎么写的。 ViewPager是对android扩展包V4包中的一个类,这个类可以让用户左右切换当前的View,我们首先看看android官网对这个类的表述:

qwli7 2336

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Android弧形广告图,简单封装弧形广告轮播图(ViewPager+贝塞尔曲线)

前言通过ViewPager和贝塞尔曲线实现了一个弧形广告轮播图。效果图弧形ViewPager实现方法想要实现这个效果,现在几行代码就可以了:Step 1. Add it in your root build.gradle at the end of repositories:allprojects {repositories {...maven { url 'https://www.jitpack...

weixin_32998893的博客 686

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

平滑的无限循环ViewPager广告轮播

无限循环的viewpager广告轮播图展示 第一步:我们先写布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="matc

又见飞的博客 1123

android 使用viewpager实现广告轮播效果

一.简介 广告轮播我们在很多应用软件上都可以看到,其实现原理也都大致相同。今天就分享一下自己写的一个广告轮播的demo,以后也方便自己看。 二.实现 首先先看一下实现之后的效果图,本人比较懒没用图片直接给图片设置了五个颜色:

JIANLIPP的博客 574

巧用ViewPager 打造不一样的广告轮播切换效果

转载请标明出处: http://blog.youkuaiyun.com/lmj623565791/article/details/51339751; 本文出自:【张鸿洋的博客】 一、概述如果大家关注了我的微信公众号的话,一定知道我在5月6号的时候推送了一篇文章,文章名为Android超高仿QQ附近的人搜索展示(一),通过该文可以利用ViewPager实现单页显示多个Item且能够添加一些炫酷的动画效

Hongyang 9万+

Android商城开发----viewPager实现广告轮播(在首页Fragment中实现)

使用ViewFlipper 在创建好的Fragment中实现【首页】广告轮播图

Qingshan_z的博客 1394

自定义View实例(二)广告轮播

学习使用自定义View实现一个可以自动无限循环轮播的广告轮播图,效果图如下: 具体实现思路: 首先利用view pager实现图片轮播 使用handle发送延时消息来实现图片自动播放 通过设置viewpager的item数量为Integer.MAX_VALUE,然后在adapter中获取当前位置item的方法里对position和我们实际的item数量进行求余来获取当前的item,以此达到...

xj531的博客 581

Android 广告轮播效果实现

使用ViewPager实现Android的广告轮播效果,广告轮播是很多电商网站的必备,比如淘宝、京东的顶部广告轮播条,今天我们就是一步步利用ViewPager来实现广告轮播效果! 界面布局 资源文件编写 实现轮播 一、界面的布局先来个效果图: 顶部就是我们的广告轮播效果,首先可以看到有图片,描述性文字,还有最后的小点,来指示当前的界面!因此布局上就需要包含上面的几个控件,其中图片的位置可以利用Vi

佳威威的专栏 2098
上一篇: [源码] Android 不要错过的7个完整项目学习
下一篇: OkHttpUtils
code_dream_wq
博客等级 码龄10年 51粉丝 199原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值