ParallaxViewPager:ViewPager的视差背景效果

2024-09-04 18:08

本文主要是介绍ParallaxViewPager:ViewPager的视差背景效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



源码:
Java代码   收藏代码
  1. import android.annotation.SuppressLint;  
  2. import android.content.Context;  
  3. import android.graphics.Bitmap;  
  4. import android.graphics.BitmapFactory;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Rect;  
  7. import android.graphics.drawable.BitmapDrawable;  
  8. import android.graphics.drawable.Drawable;  
  9. import android.support.v4.view.ViewPager;  
  10. import android.util.AttributeSet;  
  11. import android.util.Log;  
  12.   
  13. @SuppressLint("NewApi")  
  14. public class ParallaxViewPager extends ViewPager {  
  15.   
  16.     public static final int FIT_WIDTH = 0;  
  17.     public static final int FIT_HEIGHT = 1;  
  18.     public static final float OVERLAP_FULL = 1f;  
  19.     public static final float OVERLAP_HALF = 0.5f;  
  20.     public static final float OVERLAP_QUARTER = 0.25f;  
  21.     private static final float CORRECTION_PERCENTAGE = 0.01f;  
  22.     public Bitmap bitmap;  
  23.     private Rect source, destination;  
  24.     private int scaleType;  
  25.     private int chunkWidth;  
  26.     private int projectedWidth;  
  27.     private float overlap;  
  28.     private OnPageChangeListener secondOnPageChangeListener;  
  29.   
  30.     public ParallaxViewPager(Context context) {  
  31.         super(context);  
  32.         init();  
  33.     }  
  34.   
  35.     public ParallaxViewPager(Context context, AttributeSet attrs) {  
  36.         super(context, attrs);  
  37.         init();  
  38.     }  
  39.   
  40.     private void init() {  
  41.         source = new Rect();  
  42.         destination = new Rect();  
  43.         scaleType = FIT_HEIGHT;  
  44.         overlap = OVERLAP_HALF;  
  45.   
  46.         setOnPageChangeListener(new OnPageChangeListener() {  
  47.             @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  
  48.                 if (bitmap != null) {  
  49.                     source.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * chunkWidth);  
  50.                     source.right = (int) Math.ceil((position + positionOffset + CORRECTION_PERCENTAGE) * chunkWidth + projectedWidth);  
  51.                     destination.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * getWidth());  
  52.                     destination.right = (int) Math.ceil((position + positionOffset + 1 + CORRECTION_PERCENTAGE) * getWidth());  
  53.                     invalidate();  
  54.                 }  
  55.   
  56.                 if (secondOnPageChangeListener != null) {  
  57.                     secondOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);  
  58.                 }  
  59.             }  
  60.   
  61.             @Override public void onPageSelected(int position) {  
  62.                 if (secondOnPageChangeListener != null) {  
  63.                     secondOnPageChangeListener.onPageSelected(position);  
  64.                 }  
  65.             }  
  66.   
  67.             @Override public void onPageScrollStateChanged(int state) {  
  68.                 if (secondOnPageChangeListener != null) {  
  69.                     secondOnPageChangeListener.onPageScrollStateChanged(state);  
  70.                 }  
  71.             }  
  72.         });  
  73.     }  
  74.   
  75.     @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  76.         super.onSizeChanged(w, h, oldw, oldh);  
  77.         destination.top = 0;  
  78.         destination.bottom = h;  
  79.         if (getAdapter() != null && bitmap != null)  
  80.             calculateParallaxParameters();  
  81.     }  
  82.   
  83.     private void calculateParallaxParameters() {  
  84.         if (bitmap.getWidth() < getWidth() && bitmap.getWidth() < bitmap.getHeight() && scaleType == FIT_HEIGHT) {  
  85.             Log.w(ParallaxViewPager.class.getName(), "Invalid bitmap bounds for the current device, parallax effect will not work.");  
  86.         }  
  87.   
  88.         final float ratio = (float) getHeight() / bitmap.getHeight();  
  89.         if (ratio != 1) {  
  90.             switch (scaleType) {  
  91.                 case FIT_WIDTH:  
  92.                     source.top = (int) ((bitmap.getHeight() - bitmap.getHeight() / ratio) / 2);  
  93.                     source.bottom = bitmap.getHeight() - source.top;  
  94.                     chunkWidth = (int) Math.ceil((float) bitmap.getWidth() / (float) getAdapter().getCount());  
  95.                     projectedWidth = chunkWidth;  
  96.                     break;  
  97.                 case FIT_HEIGHT:  
  98.                 default:  
  99.                     source.top = 0;  
  100.                     source.bottom = bitmap.getHeight();  
  101.                     projectedWidth = (int) Math.ceil(getWidth() / ratio);  
  102.                     chunkWidth = (int) Math.ceil((bitmap.getWidth() - projectedWidth) / (float) getAdapter().getCount() * overlap);  
  103.                     break;  
  104.             }  
  105.         }  
  106.     }  
  107.   
  108.     /** 
  109.      * Sets the background from a resource file. 
  110.      * 
  111.      * @param resid 
  112.      */  
  113.     @Override public void setBackgroundResource(int resid) {  
  114.         bitmap = BitmapFactory.decodeResource(getResources(), resid);  
  115.     }  
  116.   
  117.     /** 
  118.      * Sets the background from a Drawable. 
  119.      * 
  120.      * @param background 
  121.      */  
  122.     @Override public void setBackground(Drawable background) {  
  123.         bitmap = ((BitmapDrawable) background).getBitmap();  
  124.     }  
  125.   
  126.     /** 
  127.      * Deprecated. 
  128.      * Sets the background from a Drawable. 
  129.      * 
  130.      * @param background 
  131.      */  
  132.     @Override public void setBackgroundDrawable(Drawable background) {  
  133.         bitmap = ((BitmapDrawable) background).getBitmap();  
  134.     }  
  135.   
  136.     /** 
  137.      * Sets the background from a bitmap. 
  138.      * 
  139.      * @param bitmap 
  140.      * @return The ParallaxViewPager object itself. 
  141.      */  
  142.     public ParallaxViewPager setBackground(Bitmap bitmap) {  
  143.         this.bitmap = bitmap;  
  144.         return this;  
  145.     }  
  146.   
  147.     /** 
  148.      * Sets how the view should scale the background. The available choices are: 
  149.      * <ul> 
  150.      * <li>FIT_HEIGHT - the height of the image is resized to matched the height of the View, also stretching the width to keep the aspect ratio. The non-visible part of the bitmap is divided into equal parts, each of them sliding in at the proper position.</li> 
  151.      * <li>FIT_WIDTH - the width of the background image is divided into equal chunks, each taking up the whole width of the screen.</li> 
  152.      * </ul> 
  153.      * 
  154.      * @param scaleType 
  155.      * @return 
  156.      */  
  157.     public ParallaxViewPager setScaleType(final int scaleType) {  
  158.         if (scaleType != FIT_WIDTH && scaleType != FIT_HEIGHT)  
  159.             throw new IllegalArgumentException("Illegal argument: scaleType must be FIT_WIDTH or FIT_HEIGHT");  
  160.         this.scaleType = scaleType;  
  161.         return this;  
  162.     }  
  163.   
  164.     /** 
  165.      * Sets the amount of overlapping with the setOverlapPercentage(final float percentage) method. This is a number between 0 and 1, the smaller it is, the slower is the background scrolling. 
  166.      * 
  167.      * @param percentage 
  168.      * @return The ParallaxViewPager object itself. 
  169.      */  
  170.     public ParallaxViewPager setOverlapPercentage(final float percentage) {  
  171.         if (percentage <= 0 || percentage >= 1)  
  172.             throw new IllegalArgumentException("Illegal argument: percentage must be between 0 and 1");  
  173.         overlap = percentage;  
  174.         return this;  
  175.     }  
  176.   
  177.     /** 
  178.      * Recalculates the parameters of the parallax effect, useful after changes in runtime. 
  179.      * 
  180.      * @return The ParallaxViewPager object itself. 
  181.      */  
  182.     public ParallaxViewPager invalidateParallaxParameters() {  
  183.         calculateParallaxParameters();  
  184.         return this;  
  185.     }  
  186.   
  187.     @Override protected void onDraw(Canvas canvas) {  
  188.         if (bitmap != null)  
  189.             canvas.drawBitmap(bitmap, source, destination, null);  
  190.     }  
  191.   
  192.     public void addOnPageChangeListener(OnPageChangeListener listener) {  
  193.         secondOnPageChangeListener = listener;  
  194.     }  
  195. }  


使用:
在layout xml或者程序中创建了ParallaxViewPager之后,可以使用下面的方法来设置背景,或者也可以xml设置:
Java代码   收藏代码
  1. setBackgroundResource(int resid)  
  2. setBackground(Drawable background) or setBackgroundDrawable(Drawable background)  
  3. setBackground(Bitmap bitmap)  

这就好了,你现在可以使用ParallaxViewPager的全部功能了。你可以修改背景的滚动效果来优化用户体验。你也可以使用setScaleType(final int scaleType)方法来配置视图的图像缩放方式。这个方法只能和FIT_HEIGHT搭配使用,从下面的参数中进行选择:

FIT_HEIGHT

表示缩放图像的高度以便适配视图的高度,同时缩放图像的宽度以便保持宽高比。bitmap的不可见部分被划分成相同的区域,每个区域插入到合适的位置。FIT_HEIGHT是默认值。

FIT_WIDTH

表示背景图像的宽度被划分成相同的块,每一块占满整个屏幕的宽度。这个模式不适用于视差效果,因为背景和视图的滚动速度一样。

你也可以使用setOverlapPercentage(final float percentage) 方法来设置重叠的程度。重叠程度值介于0到1之间,这个值越小背景就滚动地越慢,默认值是50%。
Java代码   收藏代码
  1. setContentView(R.layout.activity_main);  
  2. final ParallaxViewPager parallaxViewPager = ((ParallaxViewPager) findViewById(R.id.parallaxviewpager));  
  3. parallaxViewPager  
  4.         .setOverlapPercentage(0.25f)  
  5.         .setAdapter(new PagerAdapter()  
  6. //...  


Xml代码   收藏代码
  1. <com.andraskindler.parallaxviewpager.ParallaxViewPager  
  2.         xmlns:android="http://schemas.android.com/apk/res/android"  
  3.         android:id="@+id/parallaxviewpager"  
  4.         android:layout_width="match_parent"  
  5.         android:background="@drawable/background"  
  6.         android:layout_height="match_parent" />  



https://github.com/andraskindler/parallaxviewpager

滑动Viewpager时背景颜色动态过渡变化效果
http://www.itlanbao.com/code/20150816/10000/100462.html
  • 查看图片附件

这篇关于ParallaxViewPager:ViewPager的视差背景效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

使用Python实现生命之轮Wheel of life效果

《使用Python实现生命之轮Wheeloflife效果》生命之轮Wheeloflife这一概念最初由SuccessMotivation®Institute,Inc.的创始人PaulJ.Meyer... 最近看一个生命之轮的视频,让我们珍惜时间,因为一生是有限的。使用python创建生命倒计时图表,珍惜时间

防近视护眼台灯什么牌子好?五款防近视效果好的护眼台灯推荐

在家里,灯具是属于离不开的家具,每个大大小小的地方都需要的照亮,所以一盏好灯是必不可少的,每个发挥着作用。而护眼台灯就起了一个保护眼睛,预防近视的作用。可以保护我们在学习,阅读的时候提供一个合适的光线环境,保护我们的眼睛。防近视护眼台灯什么牌子好?那我们怎么选择一个优秀的护眼台灯也是很重要,才能起到最大的护眼效果。下面五款防近视效果好的护眼台灯推荐: 一:六个推荐防近视效果好的护眼台灯的

第49课 Scratch入门篇:骇客任务背景特效

骇客任务背景特效 故事背景:   骇客帝国特色背景在黑色中慢慢滚动着! 程序原理:  1 、 角色的设计技巧  2 、克隆体的应用及特效的使用 开始编程   1、使用 黑色的背景: ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7d74c872f06b4d9fbc88aecee634b074.png#pic_center)   2

数据中台出现的背景

数据中台产生背景 数据建设中出现的问题 在企业数据建设过程中,都离不开大数据平台建设,大数据平台建设涉及数据采集、数据存储、数据仓库构建、数据处理分析、数据挖掘、数据可视化等一系列流程。 随着企业体量不断增大,一个企业可能有总公司及很多子公司,随着企业各类业务多元化和垂直业务发展,从全企业角度来看,每个子公司或者某些独立的业务部都在构建大数据分析平台,在企业内部形成了很多分散、烟囱式、独立的

PNG透明背景按钮的实现(MFC)

问题描述: 当前要在对话框上添加一个以两个PNG图片作为背景的按钮,PNG图的背景是透明的,按钮也要做出相同的透明效果。并且鼠标不在按钮上时,按钮显示"bg1.png";鼠标移动到按钮上时,按钮显示"bg2.png" 开发环境为VS2010。 解决办法: 使用GDI+库装载PNG图片,并使用MFC Button Control和CMFCButton类结合,调用CMFCButton

ViewPager+fragment实现切换页面(一)

如今的很多应用中都是下面有一排按钮,点击可以切换页面,滑动也可以切换页面。下面就来简单的实现这个功能。 思路 首先肯定是会用到viewpager这个控件,为了能够向下兼容,最好用v4包下的viewpager,Activity要继承FragmentActivity 其次用一个集合来存储所有的fragment页面在设置viewpager的适配器时,把存储fragment页面的list集合传入ada

【Godot4.3】多边形的斜线填充效果基础实现

概述 图案(Pattern)填充是一个非常常见的效果。其中又以斜线填充最为简单。本篇就探讨在Godot4.3中如何使用Geometry2D和CanvasItem的绘图函数实现斜线填充效果。 基础思路 Geometry2D类提供了多边形和多边形以及多边形与折线的布尔运算。按照自然的思路,多边形的斜线填充应该属于“多边形与折线的布尔运算”范畴。 第一个问题是如何获得斜线,这条斜线应该满足什么样