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

相关文章

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

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

第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类提供了多边形和多边形以及多边形与折线的布尔运算。按照自然的思路,多边形的斜线填充应该属于“多边形与折线的布尔运算”范畴。 第一个问题是如何获得斜线,这条斜线应该满足什么样

UniApp实现漂亮的音乐歌词滚动播放效果

在现代的音乐播放应用中,歌词的展示和滚动播放已经成为了一个非常常见的功能。今天,我们将通过UniApp来实现一个漂亮的歌词滚动播放功能。我们将使用UniApp提供的组件和API来完成这个任务。 页面结构 在页面的模板部分,我们需要创建一个音频播放器和歌词展示区域。使用<scroll-view>组件来实现歌词的滚动效果。 <template><view class="audio-co

Nuxt3入门:过渡效果(第5节)

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果,以便对所有页面应用自动过渡效果。 nuxt.config.js export default defineNuxtConfig({app: {pageTransition: {name: 'fade',mode

安卓中的fragment与viewPager的使用问题的解决

最近使用viewPager,结合fragment使用,发现fragment的周期将不符合他的原有的周期流程,多个fragment将会产生错位问题。       通过研究相关代码,发现fragment的切换实际调用的函数为setUserVisibleHint,通过在其中重写方法,将会达到fragment正确切换的效果。       public void setUserVisible