Android开源 - 支持水平和垂直视差移动的ParallaxBackgroundView
wy6591731
8年前
<p style="text-align:center"><img src="https://simg.open-open.com/show/9d77c30c1bbaaa20cb977f06c414f732.gif"></p> <p style="text-align:center">horizontal_parallax_bg.gif</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d3c35578c8f3f2db36059f0c08741102.gif"></p> <p style="text-align:center">vertical_parallax_bg.gif</p> <ul> <li> <p>本文为 ParallaxBackgroundView 的使用篇,自定义原理篇后续有时间会补上。</p> </li> </ul> <h2><strong>概述</strong></h2> <h3><strong>Orientation</strong></h3> <p>ParallaxBackgroundView 是一个支持水平或者垂直方向视差移动的view。水平或者垂直方向可通过以下两种方式设置:</p> <p>代码:</p> <pre> <code class="language-java">setParallaxOrientation(ParallaxBackgroundView.PARALLAX_VERTICAL);</code></pre> <p>xml属性:</p> <pre> <code class="language-java">app:parallaxOrientation="horizontal"</code></pre> <h3><strong>Parallax Background</strong></h3> <p>视差背景可以通过代码或者xml属性设置:</p> <p>代码:</p> <pre> <code class="language-java">// setParallaxBackground(Drawable) setParallaxBackgroundResource(int);</code></pre> <p>xml属性:</p> <pre> <code class="language-java">app:parallaxBackground="@drawable/horizontal_parallax_bg"</code></pre> <p>切记不要和View的setBackground()搞混</p> <h3><strong>Parallax Offset</strong></h3> <p>视差偏移通过以下方式设置:</p> <pre> <code class="language-java">setParallaxPercent(float)</code></pre> <h3><strong>NOTE</strong></h3> <p>ParallaxBackgroundView 有两种模式:</p> <ul> <li> <p>MODE_PRE_SCALE——使用更多的内存,但视差滑动会更平滑。因为,bitmap已经在内存中预先缩放好了,在onDraw()的绘制中只是移动bitmap即可,不需要进行缩放。</p> </li> <li> <p>MODE_POST_SCALE——使用更少的内存,但会加大处理器的运算。因为缩放是在onDraw()的绘制中实时进行。</p> </li> </ul> <h3><strong>默认属性</strong></h3> <ul> <li> <p><strong>isParallax</strong> ——true</p> </li> <li> <p><strong>parallaxMode</strong> ——postScale</p> </li> <li> <p><strong>parallaxOrientation</strong> ——horizontal</p> </li> </ul> <h3><strong>lib依赖</strong></h3> <p>使用gradle:</p> <pre> <code class="language-java">compile 'com.xpleemoon.view:parallaxbackgroundview:1.0.1'</code></pre> <p>或者使用maven</p> <pre> <code class="language-java"><dependency> <groupId>com.xpleemoon.view</groupId> <artifactId>parallaxbackgroundview</artifactId> <version>1.0.1</version> <type>pom</type> </dependency></code></pre> <h2><strong>ParallaxBackgroundView 如何使用</strong></h2> <p>视差效果需要使用两层layer实现:</p> <ul> <li> <p>一层作为content,比如ScrollView、ListView or RecyclerView等可以滑动的view</p> </li> <li> <p>另一层作为background,即 ParallaxBackgroundView</p> </li> </ul> <p>下面用ViewPager作content,以xml属性和代码分别设置 ParallaxBackgroundView 来实现视差效果。</p> <h3><strong>通过xml属性设置 ParallaxBackgroundView</strong></h3> <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.xpleemoon.demo.parallaxbackgroundview.HorizontalParallaxActivity"> <com.xpleemoon.view.ParallaxBackgroundView android:id="@+id/parallax_bg" android:layout_width="match_parent" android:layout_height="match_parent" app:isParallax="true" app:parallaxMode="postScale" app:parallaxOrientation="horizontal" app:parallaxBackground="@drawable/horizontal_parallax_bg"/> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout></code></pre> <pre> <code class="language-java">final ParallaxBackgroundView bg = (ParallaxBackgroundView) findViewById(R.id.parallax_bg); ViewPager pager = (ViewPager) findViewById(R.id.pager); final PagerAdapter adapter = new MyAdapter(); pager.setAdapter(adapter); pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // this is called while user's flinging with: // position is the page number // positionOffset is the percentage scrolled (0...1) // positionOffsetPixels is the pixel offset related to that percentage // so we got everything we need .... float finalPercentage = ((position + positionOffset) * 100 / adapter.getCount()); // percentage of this page+offset respect the total pages // now you have to scroll the background layer to this position. You can either adjust the clipping or // the background X coordinate, or a scroll position if you use an image inside an scrollview ... // I personally like to extend View and draw a scaled bitmap with a clipping region (drawBitmap with Rect parameters), so just modifying the X position then calling invalidate will do. See attached source ParallaxBackground bg.setParallaxPercent(finalPercentage); } });</code></pre> <h3><strong>通过代码设置 ParallaxBackgroundView</strong></h3> <pre> <code class="language-java"><?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.xpleemoon.demo.parallaxbackgroundview.VerticalParallaxActivity"> <com.xpleemoon.view.ParallaxBackgroundView android:id="@+id/parallax_bg" android:layout_width="match_parent" android:layout_height="match_parent" /> <fr.castorflex.android.verticalviewpager.VerticalViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout></code></pre> <pre> <code class="language-java">final ParallaxBackgroundView bg = (ParallaxBackgroundView) findViewById(R.id.parallax_bg); bg.setParallax(true); bg.setParallaxMode(ParallaxBackgroundView.MODE_POST_SCALE); bg.setParallaxOrientation(ParallaxBackgroundView.PARALLAX_VERTICAL); bg.setParallaxBackgroundResource(R.drawable.vertical_parallax_bg); VerticalViewPager pager = (VerticalViewPager) findViewById(R.id.pager); final PagerAdapter adapter = new MyAdapter(); pager.setAdapter(adapter); pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // this is called while user's flinging with: // position is the page number // positionOffset is the percentage scrolled (0...1) // positionOffsetPixels is the pixel offset related to that percentage // so we got everything we need .... float finalPercentage = ((position + positionOffset) * 100 / adapter.getCount()); // percentage of this page+offset respect the total pages // now you have to scroll the background layer to this position. You can either adjust the clipping or // the background X coordinate, or a scroll position if you use an image inside an scrollview ... // I personally like to extend View and draw a scaled bitmap with a clipping region (drawBitmap with Rect parameters), so just modifying the X position then calling invalidate will do. See attached source ParallaxBackground bg.setParallaxPercent(finalPercentage); } });</code></pre> <p> </p> <p> </p> <p> </p>