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>