├── settings.gradle ├── assets ├── screen1.png └── screen2.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── paralloidexample ├── src │ └── main │ │ ├── ic_launcher-web.png │ │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-nodpi │ │ │ ├── example_sky.jpg │ │ │ ├── example_image.jpg │ │ │ └── example_rainbow.jpg │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── values-sw600dp │ │ │ └── dimens.xml │ │ ├── menu │ │ │ └── home.xml │ │ ├── values-sw720dp-land │ │ │ └── dimens.xml │ │ ├── layout │ │ │ ├── fragment_parallax_list_background.xml │ │ │ ├── activity_home.xml │ │ │ ├── fragment_parallax_background.xml │ │ │ ├── fragment_home_dummy.xml │ │ │ ├── fragment_invert_transformer.xml │ │ │ └── fragment_combi_transformer.xml │ │ ├── drawable │ │ │ ├── bg_gradient.xml │ │ │ ├── bg_gradient_invert.xml │ │ │ └── bg_gradient_with_middle.xml │ │ ├── values │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v11 │ │ │ └── styles.xml │ │ └── values-v14 │ │ │ └── styles.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── uk │ │ └── co │ │ └── chrisjenx │ │ └── paralloidexample │ │ ├── ParallaxBackgroundFragment.java │ │ ├── ShiftBackgroundFragment.java │ │ ├── ParallaxViewRightFragment.java │ │ ├── ParallaxViewUpFragment.java │ │ ├── ParallaxViewDownFragment.java │ │ ├── ParallaxViewCombiFragment.java │ │ ├── ParallaxBackgroundListFragment.java │ │ ├── OverParallaxBackgroundListFragment.java │ │ └── HomeActivity.java ├── keystore │ └── paralloidkeystore.jks └── build.gradle ├── CHANGELOG.md ├── paralloidviews ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── uk │ │ └── co │ │ └── chrisjenx │ │ └── paralloid │ │ └── views │ │ ├── ParallaxListView.java │ │ ├── ParallaxScrollView.java │ │ └── ParallaxHorizontalScrollView.java └── build.gradle ├── paralloid ├── src │ └── main │ │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── chrisjenx │ │ │ └── paralloid │ │ │ ├── measure │ │ │ ├── ScrollSize.java │ │ │ ├── ViewScrollSize.java │ │ │ └── AbsListScrollSize.java │ │ │ ├── OnScrollChangedListener.java │ │ │ ├── transform │ │ │ ├── Transformer.java │ │ │ ├── InvertTransformer.java │ │ │ ├── LinearTransformer.java │ │ │ ├── LeftAngleTransformer.java │ │ │ └── RightAngleTransformer.java │ │ │ ├── ParallaxorListener.java │ │ │ ├── ParallaxViewInfo.java │ │ │ ├── ParallaxViewController.java │ │ │ ├── Parallaxor.java │ │ │ ├── graphics │ │ │ └── ParallaxDrawable.java │ │ │ ├── utils │ │ │ └── ParallaxHelper.java │ │ │ └── ParallaxController.java │ │ └── AndroidManifest.xml └── build.gradle ├── .gitignore ├── gradlew.bat ├── README.md ├── gradlew └── LICENSE /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':paralloid', ':paralloidexample', ':paralloidviews' -------------------------------------------------------------------------------- /assets/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/assets/screen1.png -------------------------------------------------------------------------------- /assets/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/assets/screen2.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /paralloidexample/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /paralloidexample/keystore/paralloidkeystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/keystore/paralloidkeystore.jks -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-nodpi/example_sky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-nodpi/example_sky.jpg -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-nodpi/example_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-nodpi/example_image.jpg -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable-nodpi/example_rainbow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chrisjenx/Paralloid/HEAD/paralloidexample/src/main/res/drawable-nodpi/example_rainbow.jpg -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 0.3.0 4 | - Added Concept of Transformers 5 | 6 | ## 0.2.0 7 | - API Change 8 | - Added the ability to scroll multiple backgrounds. 9 | 10 | ## 0.1.0 11 | Initial Release -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /paralloidviews/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Oct 20 22:09:45 BST 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-all.zip 7 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/menu/home.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/measure/ScrollSize.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.measure; 2 | 3 | /** 4 | * Created by chris on 23/10/2013 5 | * Project: Paralloid 6 | */ 7 | public interface ScrollSize { 8 | 9 | int getMaxScrollX(); 10 | 11 | int getMaxScrollY(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 128dp 5 | 6 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/fragment_parallax_list_background.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/OnScrollChangedListener.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | /** 4 | * OnScrolled changed Listener for {@link android.view.View} and this alike to implement 5 | */ 6 | public interface OnScrollChangedListener { 7 | void onScrollChanged(Object who, int l, int t, int oldl, int oldt); 8 | } -------------------------------------------------------------------------------- /paralloid/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable/bg_gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable/bg_gradient_invert.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 172dp 7 | 16dp 8 | 9 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/transform/Transformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.transform; 2 | 3 | /** 4 | * Created by chris on 23/10/2013 5 | * Project: Paralloid 6 | */ 7 | public interface Transformer { 8 | 9 | /** 10 | * @return can not be null, otherwise scroll will fail 11 | */ 12 | int[] scroll(float x, float y, float factor); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Gradle + Project files 23 | .idea/ 24 | build/ 25 | .gradle/ 26 | *.iml 27 | .DS_Store -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/transform/InvertTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.transform; 2 | 3 | /** 4 | * Created by chris on 23/10/2013 5 | * Project: Paralloid 6 | */ 7 | public class InvertTransformer implements Transformer { 8 | @Override 9 | public int[] scroll(float x, float y, float factor) { 10 | return new int[]{(int) -(x * factor), (int) -(y * factor)}; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/transform/LinearTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.transform; 2 | 3 | /** 4 | * Created by chris on 23/10/2013 5 | * Project: Paralloid 6 | */ 7 | public class LinearTransformer implements Transformer { 8 | 9 | @Override 10 | public int[] scroll(float x, float y, float factor) { 11 | return new int[]{(int) (x * factor), (int) (y * factor)}; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/drawable/bg_gradient_with_middle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/transform/LeftAngleTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.transform; 2 | 3 | /** 4 | * Put simply turns up into left, left into down, down into right, right into up. 5 | * 6 | * Created by chris on 23/10/2013 7 | * Project: Paralloid 8 | */ 9 | public class LeftAngleTransformer implements Transformer { 10 | 11 | @Override 12 | public int[] scroll(float x, float y, float factor) { 13 | return new int[]{(int) (y * factor), (int) (x * factor)}; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/transform/RightAngleTransformer.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.transform; 2 | 3 | /** 4 | * Put simply turns up into right, right into down, down into left, left into up. 5 | * 6 | * Created by chris on 23/10/2013 7 | * Project: Paralloid 8 | */ 9 | public class RightAngleTransformer implements Transformer { 10 | 11 | @Override 12 | public int[] scroll(float x, float y, float factor) { 13 | return new int[]{(int) -(y * factor), (int) -(x * factor)}; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/ParallaxorListener.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | /** 4 | * Created by chris on 20/10/2013 5 | * Project: Paralloid 6 | */ 7 | public interface ParallaxorListener extends Parallaxor, OnScrollChangedListener { 8 | 9 | /** 10 | * Add a scroll listener you can listen too if you want to do something custom your end as well. 11 | * 12 | * @param onScrollChangedListener Null is valid (it will remove it if set). 13 | */ 14 | public void setOnScrollListener(OnScrollChangedListener onScrollChangedListener); 15 | } 16 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/measure/ViewScrollSize.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.measure; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by chris on 23/10/2013 7 | * Project: Paralloid 8 | */ 9 | 10 | public class ViewScrollSize implements ScrollSize { 11 | 12 | final T viewToSize; 13 | 14 | public ViewScrollSize(T viewToSize) { 15 | this.viewToSize = viewToSize; 16 | } 17 | 18 | /** 19 | * Default impl returns the View width 20 | */ 21 | @Override 22 | public int getMaxScrollX() { 23 | return viewToSize.getWidth(); 24 | } 25 | 26 | /** 27 | * Default impl returns the View height 28 | */ 29 | @Override 30 | public int getMaxScrollY() { 31 | return viewToSize.getHeight(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/ParallaxViewInfo.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | import uk.co.chrisjenx.paralloid.transform.LinearTransformer; 4 | import uk.co.chrisjenx.paralloid.transform.Transformer; 5 | 6 | class ParallaxViewInfo { 7 | 8 | final float factor; 9 | final Transformer interpolator; 10 | 11 | private int maxX; 12 | private int maxY; 13 | 14 | ParallaxViewInfo(float factor, Transformer transformer) { 15 | this.factor = factor; 16 | this.interpolator = transformer == null ? new LinearTransformer() : transformer; 17 | } 18 | 19 | public int getMaxX() { 20 | return maxX; 21 | } 22 | 23 | public void setMaxX(int maxX) { 24 | this.maxX = maxX; 25 | } 26 | 27 | public int getMaxY() { 28 | return maxY; 29 | } 30 | 31 | public void setMaxY(int maxY) { 32 | this.maxY = maxY; 33 | } 34 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/activity_home.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /paralloidexample/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.6.+' 7 | } 8 | } 9 | apply plugin: 'android' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | android { 16 | compileSdkVersion 18 17 | buildToolsVersion "18.1.1" 18 | 19 | defaultConfig { 20 | minSdkVersion 14 21 | targetSdkVersion 18 22 | } 23 | 24 | signingConfigs { 25 | release { 26 | // We can leave these in environment variables 27 | storeFile file("keystore/paralloidkeystore.jks") 28 | keyAlias "paralloid" 29 | 30 | storePassword 'paralloid' 31 | keyPassword 'paralloid' 32 | } 33 | } 34 | 35 | buildTypes { 36 | release { 37 | signingConfig signingConfigs.release 38 | } 39 | } 40 | } 41 | 42 | dependencies { 43 | compile 'com.android.support:appcompat-v7:18.0.+' 44 | compile project(':paralloidviews') 45 | } 46 | -------------------------------------------------------------------------------- /paralloidexample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Paralloid Example 5 | Settings 6 | Parallax View 7 | Shift Background 8 | Parallax Background 9 | Parallax List Background 10 | OverParallax Background 11 | Invert Transformer 12 | RightAngle Transformer 13 | Transformer Combination 14 | Peek a boo! 15 | 16 | Bacon ipsum dolor sit amet ut t-bone ham hock pariatur. Ex aliquip est dolore strip steak enim. Fugiat reprehenderit tenderloin ham hock. Pork minim chicken, jowl do strip steak short loin meatball bacon doner proident nulla eiusmod. Elit veniam beef sunt. 17 | 18 | 19 | -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxBackgroundFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import uk.co.chrisjenx.paralloid.views.ParallaxScrollView; 10 | 11 | /** 12 | * A dummy fragment representing a section of the app, but that simply 13 | * displays dummy text. 14 | */ 15 | public class ParallaxBackgroundFragment extends Fragment { 16 | 17 | public ParallaxBackgroundFragment() { 18 | } 19 | 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 22 | Bundle savedInstanceState) { 23 | View rootView = inflater.inflate(R.layout.fragment_parallax_background, container, false); 24 | ParallaxScrollView scrollView = (ParallaxScrollView) rootView.findViewById(R.id.scroll_view); 25 | scrollView.parallaxViewBackgroundBy(scrollView, getResources().getDrawable(R.drawable.example_image), .2f); 26 | 27 | return rootView; 28 | } 29 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ShiftBackgroundFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ScrollView; 9 | 10 | import uk.co.chrisjenx.paralloid.Parallaxor; 11 | 12 | /** 13 | * A dummy fragment representing a section of the app, but that simply 14 | * displays dummy text. 15 | */ 16 | public class ShiftBackgroundFragment extends Fragment { 17 | 18 | public ShiftBackgroundFragment() { 19 | } 20 | 21 | @Override 22 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 23 | Bundle savedInstanceState) { 24 | View rootView = inflater.inflate(R.layout.fragment_parallax_background, container, false); 25 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 26 | if (scrollView instanceof Parallaxor) { 27 | ((Parallaxor) scrollView).parallaxViewBackgroundBy(scrollView, getResources().getDrawable(R.drawable.example_rainbow), 1f); 28 | } 29 | 30 | return rootView; 31 | } 32 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxViewRightFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | import android.widget.ScrollView; 10 | 11 | import uk.co.chrisjenx.paralloid.Parallaxor; 12 | import uk.co.chrisjenx.paralloid.transform.RightAngleTransformer; 13 | 14 | /** 15 | * A dummy fragment representing a section of the app, but that simply 16 | * displays dummy text. 17 | */ 18 | public class ParallaxViewRightFragment extends Fragment { 19 | 20 | public ParallaxViewRightFragment() { 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 25 | Bundle savedInstanceState) { 26 | View rootView = inflater.inflate(R.layout.fragment_invert_transformer, container, false); 27 | ImageView imageView = (ImageView) rootView.findViewById(R.id.image_view); 28 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 29 | if (scrollView instanceof Parallaxor) { 30 | ((Parallaxor) scrollView).parallaxViewBy(imageView, new RightAngleTransformer(), 0.4f); 31 | } 32 | 33 | return rootView; 34 | } 35 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxViewUpFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | import android.widget.ScrollView; 10 | 11 | import uk.co.chrisjenx.paralloid.Parallaxor; 12 | 13 | /** 14 | * A dummy fragment representing a section of the app, but that simply 15 | * displays dummy text. 16 | */ 17 | public class ParallaxViewUpFragment extends Fragment { 18 | /** 19 | * The fragment argument representing the section number for this 20 | * fragment. 21 | */ 22 | public static final String ARG_SECTION_NUMBER = "section_number"; 23 | 24 | public ParallaxViewUpFragment() { 25 | } 26 | 27 | @Override 28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 29 | Bundle savedInstanceState) { 30 | View rootView = inflater.inflate(R.layout.fragment_home_dummy, container, false); 31 | ImageView imageView = (ImageView) rootView.findViewById(R.id.image_view); 32 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 33 | if (scrollView instanceof Parallaxor) { 34 | ((Parallaxor) scrollView).parallaxViewBy(imageView, 0.5f); 35 | } 36 | 37 | return rootView; 38 | } 39 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxViewDownFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | import android.widget.ScrollView; 10 | 11 | import uk.co.chrisjenx.paralloid.Parallaxor; 12 | import uk.co.chrisjenx.paralloid.transform.InvertTransformer; 13 | 14 | /** 15 | * A dummy fragment representing a section of the app, but that simply 16 | * displays dummy text. 17 | */ 18 | public class ParallaxViewDownFragment extends Fragment { 19 | /** 20 | * The fragment argument representing the section number for this 21 | * fragment. 22 | */ 23 | public static final String ARG_SECTION_NUMBER = "section_number"; 24 | 25 | public ParallaxViewDownFragment() { 26 | } 27 | 28 | @Override 29 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 30 | Bundle savedInstanceState) { 31 | View rootView = inflater.inflate(R.layout.fragment_invert_transformer, container, false); 32 | ImageView imageView = (ImageView) rootView.findViewById(R.id.image_view); 33 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 34 | if (scrollView instanceof Parallaxor) { 35 | ((Parallaxor) scrollView).parallaxViewBy(imageView, new InvertTransformer(), 0.35f); 36 | } 37 | 38 | return rootView; 39 | } 40 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxViewCombiFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ImageView; 9 | import android.widget.ScrollView; 10 | 11 | import uk.co.chrisjenx.paralloid.Parallaxor; 12 | import uk.co.chrisjenx.paralloid.transform.LeftAngleTransformer; 13 | import uk.co.chrisjenx.paralloid.transform.RightAngleTransformer; 14 | 15 | /** 16 | * A dummy fragment representing a section of the app, but that simply 17 | * displays dummy text. 18 | */ 19 | public class ParallaxViewCombiFragment extends Fragment { 20 | 21 | public ParallaxViewCombiFragment() { 22 | } 23 | 24 | @Override 25 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 26 | Bundle savedInstanceState) { 27 | View rootView = inflater.inflate(R.layout.fragment_combi_transformer, container, false); 28 | ImageView imageView = (ImageView) rootView.findViewById(R.id.image_view); 29 | ImageView imageView2 = (ImageView) rootView.findViewById(R.id.image_view2); 30 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 31 | if (scrollView instanceof Parallaxor) { 32 | ((Parallaxor) scrollView).parallaxViewBy(imageView, new LeftAngleTransformer(), 0.2f); 33 | ((Parallaxor) scrollView).parallaxViewBy(imageView2, new RightAngleTransformer(), 0.2f); 34 | } 35 | 36 | return rootView; 37 | } 38 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/fragment_parallax_background.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 16 | 17 | 20 | 21 | 24 | 25 | 28 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /paralloidviews/src/main/java/uk/co/chrisjenx/paralloid/views/ParallaxListView.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.views; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.ListView; 8 | 9 | import uk.co.chrisjenx.paralloid.ParallaxViewController; 10 | import uk.co.chrisjenx.paralloid.Parallaxor; 11 | import uk.co.chrisjenx.paralloid.transform.Transformer; 12 | 13 | /** 14 | * Created by chris on 02/10/2013 15 | * Project: Paralloid 16 | */ 17 | public class ParallaxListView extends ListView implements Parallaxor { 18 | 19 | ParallaxViewController mParallaxViewController; 20 | 21 | public ParallaxListView(Context context) { 22 | super(context); 23 | init(); 24 | } 25 | 26 | public ParallaxListView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | init(); 29 | } 30 | 31 | public ParallaxListView(Context context, AttributeSet attrs, int defStyle) { 32 | super(context, attrs, defStyle); 33 | init(); 34 | } 35 | 36 | private void init() { 37 | mParallaxViewController = ParallaxViewController.wrap(this); 38 | } 39 | 40 | @Override 41 | public void parallaxViewBy(View view, float multiplier) { 42 | mParallaxViewController.parallaxViewBy(view, multiplier); 43 | } 44 | 45 | @Override 46 | public void parallaxViewBy(View view, Transformer transformer, float multiplier) { 47 | mParallaxViewController.parallaxViewBy(view, transformer, multiplier); 48 | } 49 | 50 | @Override 51 | public void parallaxViewBackgroundBy(View view, Drawable drawable, float multiplier) { 52 | mParallaxViewController.parallaxViewBackgroundBy(view, drawable, multiplier); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/ParallaxViewController.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | import android.view.View; 4 | import android.widget.AbsListView; 5 | 6 | import uk.co.chrisjenx.paralloid.measure.AbsListScrollSize; 7 | 8 | /** 9 | * Created by chris on 02/10/2013 10 | * Project: Paralloid 11 | */ 12 | public class ParallaxViewController extends ParallaxController implements AbsListView.OnScrollListener { 13 | 14 | public static ParallaxViewController wrap(T wrappedView) { 15 | return new ParallaxViewController(wrappedView); 16 | } 17 | 18 | protected ParallaxViewController(T wrappedView) { 19 | super(wrappedView); 20 | init(); 21 | } 22 | 23 | /** 24 | * Init this controller 25 | */ 26 | private void init() { 27 | if (mWrapped == null) 28 | throw new IllegalArgumentException("The wrapped view cannot be null"); 29 | 30 | if (mWrapped instanceof AbsListView) { 31 | ((AbsListView) mWrapped).setOnScrollListener(this); 32 | } 33 | } 34 | 35 | @Override 36 | public void onScrollStateChanged(AbsListView view, int scrollState) { 37 | } 38 | 39 | /** 40 | * Used internally by the AbsListView implementation, calling through to this is unnecessary, the controller 41 | * will happily set the OnScrollListener 42 | */ 43 | @Override 44 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 45 | final int offsetY = AbsListScrollSize.calculateOffset(view); 46 | mIgnoreOnScrollListener = false; 47 | onScrollChanged(getWrapped(), mWrapped.getScrollX(), offsetY, mLastScrollX, mLastScrollY); 48 | mIgnoreOnScrollListener = true; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/Parallaxor.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.view.View; 5 | 6 | import uk.co.chrisjenx.paralloid.transform.Transformer; 7 | 8 | /** 9 | * Suggests that this view will let you parallax others. 10 | */ 11 | public interface Parallaxor { 12 | /** 13 | * Which view we want to move by. 14 | *

15 | * The view that implements this should call too {@link ParallaxViewController#parallaxViewBy(android.view.View, float)} 16 | * 17 | * @param view View to move when this moves 18 | * @param multiplier 1.0f is the normal amount, a 1:1 ratio, 0.5f would move at half the distance of this view etc.. 19 | */ 20 | public void parallaxViewBy(View view, float multiplier); 21 | 22 | /** 23 | * Which view we want to move by. 24 | *

25 | * The view that implements this should call too {@link ParallaxViewController#parallaxViewBy(android.view.View, float)} 26 | * 27 | * @param view View to move when this moves 28 | * @param transformer how do we want to move the view? (null default to {@link uk.co.chrisjenx.paralloid.transform.LinearTransformer}) 29 | * @param multiplier 1.0f is the normal amount, a 1:1 ratio, 0.5f would move at half the distance of this view etc.. 30 | */ 31 | public void parallaxViewBy(View view, Transformer transformer, float multiplier); 32 | 33 | /** 34 | * This does a bit more than move the background, it will make it fit the view in a way that 35 | * it will reach out side its bounds to take into account 36 | * 37 | * @param drawable Drawable to Parallax 38 | * @param multiplier How much to move it by, 1 would be a 1:1 relationship. 0.5 would move the 39 | * background and half the rate of the scrolling. 40 | */ 41 | public void parallaxViewBackgroundBy(View view, Drawable drawable, float multiplier); 42 | } -------------------------------------------------------------------------------- /paralloidviews/src/main/java/uk/co/chrisjenx/paralloid/views/ParallaxScrollView.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.views; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.ScrollView; 8 | 9 | import uk.co.chrisjenx.paralloid.ParallaxViewController; 10 | import uk.co.chrisjenx.paralloid.Parallaxor; 11 | import uk.co.chrisjenx.paralloid.transform.Transformer; 12 | 13 | /** 14 | * Created by chris on 02/10/2013 15 | * Project: Paralloid 16 | */ 17 | public class ParallaxScrollView extends ScrollView implements Parallaxor { 18 | 19 | ParallaxViewController mParallaxViewController; 20 | 21 | public ParallaxScrollView(Context context) { 22 | super(context); 23 | init(); 24 | } 25 | 26 | public ParallaxScrollView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | init(); 29 | } 30 | 31 | public ParallaxScrollView(Context context, AttributeSet attrs, int defStyle) { 32 | super(context, attrs, defStyle); 33 | init(); 34 | } 35 | 36 | private void init() { 37 | mParallaxViewController = ParallaxViewController.wrap(this); 38 | } 39 | 40 | @Override 41 | public void parallaxViewBy(View view, float multiplier) { 42 | mParallaxViewController.parallaxViewBy(view, multiplier); 43 | } 44 | 45 | @Override 46 | public void parallaxViewBy(View view, Transformer transformer, float multiplier) { 47 | mParallaxViewController.parallaxViewBy(view, transformer, multiplier); 48 | } 49 | 50 | @Override 51 | public void parallaxViewBackgroundBy(View view, Drawable drawable, float multiplier) { 52 | mParallaxViewController.parallaxViewBackgroundBy(view, drawable, multiplier); 53 | } 54 | 55 | @Override 56 | protected void onScrollChanged(int l, int t, int oldl, int oldt) { 57 | super.onScrollChanged(l, t, oldl, oldt); 58 | mParallaxViewController.onScrollChanged(this, l, t, oldl, oldt); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /paralloid/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.6.+' 7 | } 8 | } 9 | apply plugin: 'android-library' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | android { 16 | compileSdkVersion 19 17 | buildToolsVersion "19.0.0" 18 | 19 | defaultConfig { 20 | minSdkVersion 7 21 | targetSdkVersion 19 22 | } 23 | } 24 | 25 | dependencies { 26 | compile "com.android.support:support-v4:18.0.+" 27 | } 28 | 29 | uploadArchives { 30 | configuration = configurations.archives 31 | repositories.mavenDeployer { 32 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 33 | 34 | repository(url: sonatypeRepo) { 35 | authentication( 36 | userName: sonatypeUsername, 37 | password: sonatypePassword 38 | ) 39 | } 40 | 41 | pom.project { 42 | name 'Paralloid' 43 | artifactId = 'paralloid' 44 | packaging 'aar' 45 | description 'Parallax library for Android' 46 | url 'https://github.com/chrisjenx/Paralloid' 47 | 48 | scm { 49 | url 'scm:git@github.com:chrisjenx/Paralloid.git' 50 | connection 'scm:git@github.com:chrisjenx/Paralloid.git' 51 | developerConnection 'scm:git@github.com:chrisjenx/Paralloid.git' 52 | } 53 | 54 | licenses { 55 | license { 56 | name 'The Apache Software License, Version 2.0' 57 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 58 | distribution 'repo' 59 | } 60 | } 61 | 62 | developers { 63 | developer { 64 | id 'chrisjenx' 65 | name 'Christopher Jenkins' 66 | email 'chris.mark.jenkins@gmail.com' 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /paralloidviews/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.6.+' 7 | } 8 | } 9 | apply plugin: 'android-library' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | android { 16 | compileSdkVersion 19 17 | buildToolsVersion "19.0.0" 18 | 19 | defaultConfig { 20 | minSdkVersion 14 21 | targetSdkVersion 19 22 | } 23 | } 24 | 25 | dependencies { 26 | compile project(':paralloid') 27 | } 28 | 29 | uploadArchives { 30 | configuration = configurations.archives 31 | repositories.mavenDeployer { 32 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 33 | 34 | repository(url: sonatypeRepo) { 35 | authentication( 36 | userName: sonatypeUsername, 37 | password: sonatypePassword 38 | ) 39 | } 40 | 41 | pom.project { 42 | name 'Paralloid Views' 43 | artifactId = 'paralloidviews' 44 | packaging 'aar' 45 | description 'Parallax library for Android Extra Views' 46 | url 'https://github.com/chrisjenx/Paralloid' 47 | 48 | scm { 49 | url 'scm:git@github.com:chrisjenx/Paralloid.git' 50 | connection 'scm:git@github.com:chrisjenx/Paralloid.git' 51 | developerConnection 'scm:git@github.com:chrisjenx/Paralloid.git' 52 | } 53 | 54 | licenses { 55 | license { 56 | name 'The Apache Software License, Version 2.0' 57 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 58 | distribution 'repo' 59 | } 60 | } 61 | 62 | developers { 63 | developer { 64 | id 'chrisjenx' 65 | name 'Christopher Jenkins' 66 | email 'chris.mark.jenkins@gmail.com' 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /paralloidviews/src/main/java/uk/co/chrisjenx/paralloid/views/ParallaxHorizontalScrollView.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.views; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.HorizontalScrollView; 8 | 9 | import uk.co.chrisjenx.paralloid.ParallaxViewController; 10 | import uk.co.chrisjenx.paralloid.Parallaxor; 11 | import uk.co.chrisjenx.paralloid.transform.Transformer; 12 | 13 | /** 14 | * Created by chris on 02/10/2013 15 | * Project: Paralloid 16 | */ 17 | public class ParallaxHorizontalScrollView extends HorizontalScrollView implements Parallaxor { 18 | 19 | ParallaxViewController mParallaxViewController; 20 | 21 | public ParallaxHorizontalScrollView(Context context) { 22 | super(context); 23 | init(); 24 | } 25 | 26 | public ParallaxHorizontalScrollView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | init(); 29 | } 30 | 31 | public ParallaxHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) { 32 | super(context, attrs, defStyle); 33 | init(); 34 | } 35 | 36 | private void init() { 37 | mParallaxViewController = ParallaxViewController.wrap(this); 38 | 39 | } 40 | 41 | @Override 42 | public void parallaxViewBy(View view, float multiplier) { 43 | mParallaxViewController.parallaxViewBy(view, multiplier); 44 | } 45 | 46 | @Override 47 | public void parallaxViewBy(View view, Transformer transformer, float multiplier) { 48 | mParallaxViewController.parallaxViewBy(view, transformer, multiplier); 49 | } 50 | 51 | @Override 52 | public void parallaxViewBackgroundBy(View view, Drawable drawable, float multiplier) { 53 | mParallaxViewController.parallaxViewBackgroundBy(view, drawable, multiplier); 54 | } 55 | 56 | @Override 57 | protected void onScrollChanged(int l, int t, int oldl, int oldt) { 58 | super.onScrollChanged(l, t, oldl, oldt); 59 | mParallaxViewController.onScrollChanged(this, l, t, oldl, oldt); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/fragment_home_dummy.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | 11 | 16 | 17 | 22 | 23 | 26 | 27 | 30 | 31 | 34 | 35 | 38 | 39 | 42 | 43 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/ParallaxBackgroundListFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ListView; 9 | import android.widget.SimpleAdapter; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | import uk.co.chrisjenx.paralloid.Parallaxor; 17 | 18 | /** 19 | * A dummy fragment representing a section of the app, but that simply 20 | * displays dummy text. 21 | */ 22 | public class ParallaxBackgroundListFragment extends Fragment { 23 | 24 | public ParallaxBackgroundListFragment() { 25 | } 26 | 27 | @Override 28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 29 | Bundle savedInstanceState) { 30 | return inflater.inflate(R.layout.fragment_parallax_list_background, container, false); 31 | } 32 | 33 | @Override 34 | public void onViewCreated(View view, Bundle savedInstanceState) { 35 | super.onViewCreated(view, savedInstanceState); 36 | final ListView listView = (ListView) view.findViewById(R.id.list_view); 37 | 38 | List> maps = new ArrayList>(50); 39 | Map map; 40 | for (int i = 0; i < 50; i++) { 41 | map = new HashMap(); 42 | map.put("text", "Example Text " + i); 43 | maps.add(map); 44 | } 45 | 46 | SimpleAdapter adapter = new SimpleAdapter( 47 | getActivity(), 48 | maps, 49 | android.R.layout.simple_list_item_1, 50 | new String[]{"text"}, 51 | new int[]{android.R.id.text1}); 52 | 53 | listView.setAdapter(adapter); 54 | 55 | // Set the background after the setting the Adapter, it shouldn't matter until the view is drawn. 56 | // If you have difficulty getting this to work, just make sure this is called after adapter is added/view drawn for 57 | // ListViews, they have a limited support unfortunately. 58 | if (listView instanceof Parallaxor) { 59 | ((Parallaxor) listView).parallaxViewBackgroundBy(listView, getResources().getDrawable(R.drawable.example_image), .25f); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/fragment_invert_transformer.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 18 | 19 | 24 | 25 | 29 | 30 | 33 | 34 | 37 | 38 | 41 | 42 | 45 | 46 | 49 | 50 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/OverParallaxBackgroundListFragment.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.ListView; 9 | import android.widget.SimpleAdapter; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | import uk.co.chrisjenx.paralloid.Parallaxor; 17 | 18 | /** 19 | * A dummy fragment representing a section of the app, but that simply 20 | * displays dummy text. 21 | */ 22 | public class OverParallaxBackgroundListFragment extends Fragment { 23 | 24 | public OverParallaxBackgroundListFragment() { 25 | } 26 | 27 | @Override 28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 29 | Bundle savedInstanceState) { 30 | return inflater.inflate(R.layout.fragment_parallax_list_background, container, false); 31 | } 32 | 33 | @Override 34 | public void onViewCreated(View view, Bundle savedInstanceState) { 35 | super.onViewCreated(view, savedInstanceState); 36 | final ListView listView = (ListView) view.findViewById(R.id.list_view); 37 | 38 | List> maps = new ArrayList>(50); 39 | Map map; 40 | for (int i = 0; i < 50; i++) { 41 | map = new HashMap(); 42 | map.put("text", "Example Text " + i); 43 | maps.add(map); 44 | } 45 | 46 | SimpleAdapter adapter = new SimpleAdapter( 47 | getActivity(), 48 | maps, 49 | android.R.layout.simple_list_item_1, 50 | new String[]{"text"}, 51 | new int[]{android.R.id.text1}); 52 | 53 | listView.setAdapter(adapter); 54 | 55 | // Set the background after the setting the Adapter, it shouldn't matter until the view is drawn. 56 | // If you have difficulty getting this to work, just make sure this is called after adapter is added/view drawn for 57 | // ListViews, they have a limited support unfortunately. 58 | if (listView instanceof Parallaxor) { 59 | ((Parallaxor) listView).parallaxViewBackgroundBy(listView, getResources().getDrawable(R.drawable.example_rainbow), 2.0f); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/measure/AbsListScrollSize.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.measure; 2 | 3 | import android.view.View; 4 | import android.widget.AbsListView; 5 | import android.widget.ListAdapter; 6 | import android.widget.ListView; 7 | 8 | /** 9 | * Created by chris on 25/10/2013 10 | * Project: Paralloid 11 | */ 12 | public class AbsListScrollSize extends ViewScrollSize { 13 | 14 | 15 | public AbsListScrollSize(AbsListView viewToSize) { 16 | super(viewToSize); 17 | } 18 | 19 | @Override 20 | public int getMaxScrollY() { 21 | return calculateApproximateHeight(viewToSize); 22 | } 23 | 24 | /** 25 | * This method is by no means accurate, and Will only work to any degree of accuracy if your list items 26 | * are the same height. 27 | * Otherwise it becomes vastly more difficult to calculate the correct height. 28 | * 29 | * @param listView listView to get height of, if no adapter is attached then nothing will happen. 30 | * @return 0 for failure. 31 | */ 32 | public static int calculateApproximateHeight(AbsListView listView) { 33 | final ListAdapter adapter = listView.getAdapter(); 34 | int onScreenHeight = 0, totalHeight = 0; 35 | final int totalCount = adapter.getCount(); 36 | final int visibleCount = listView.getLastVisiblePosition() - listView.getFirstVisiblePosition(); 37 | if (totalCount > 0) { 38 | View view; 39 | for (int i = 0; i < visibleCount; i++) { 40 | // final View view = adapter.getView(0, null, listView); 41 | view = listView.getChildAt(i); 42 | // view.measure( 43 | // View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), 44 | // View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 45 | onScreenHeight += view.getMeasuredHeight(); 46 | } 47 | // Get the average on screen height, then multiply it up. 48 | totalHeight = (onScreenHeight / visibleCount) * totalCount; 49 | // Add the divider height. 50 | if (listView instanceof ListView) { 51 | totalHeight += ((ListView) listView).getDividerHeight() * (totalCount - 1); 52 | } 53 | } 54 | return totalHeight; 55 | } 56 | 57 | /** 58 | * Call from an AbsListView.OnScrollListener to calculate the incremental offset (change in scroll offset 59 | * since the last calculation). 60 | * 61 | * @return The offset, or 0 if it wasn't possible to calculate the offset. 62 | */ 63 | public static int calculateOffset(final AbsListView listView) { 64 | final View c = listView.getChildAt(0); 65 | if (c == null) return 0; 66 | return -c.getTop() + listView.getFirstVisiblePosition() * c.getHeight(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /paralloidexample/src/main/res/layout/fragment_combi_transformer.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 18 | 19 | 25 | 26 | 32 | 33 | 34 | 39 | 40 | 44 | 45 | 48 | 49 | 52 | 53 | 56 | 57 | 60 | 61 | 64 | 65 | 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/graphics/ParallaxDrawable.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.graphics; 2 | 3 | import android.annotation.TargetApi; 4 | import android.graphics.Canvas; 5 | import android.graphics.ColorFilter; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.os.Build; 9 | 10 | /** 11 | * Created by chris on 20/10/2013 12 | * Project: Paralloid 13 | */ 14 | public class ParallaxDrawable extends Drawable { 15 | 16 | private final Drawable mWrappedDrawable; 17 | private float mFactor; 18 | private int mWidth; 19 | private int mHeight; 20 | private float mOffsetX; 21 | private float mOffsetY; 22 | 23 | public ParallaxDrawable(Drawable wrappedDrawable, float factor) { 24 | mWrappedDrawable = wrappedDrawable; 25 | mFactor = factor; 26 | } 27 | 28 | public Drawable getWrappedDrawable() { 29 | return mWrappedDrawable; 30 | } 31 | 32 | public void setFactor(float factor) { 33 | mFactor = factor; 34 | } 35 | 36 | public float getFactor() { 37 | return mFactor; 38 | } 39 | 40 | public void setParallaxExtraWidthHeight(float width, float height) { 41 | mWidth = (int) width; 42 | mHeight = (int) height; 43 | } 44 | 45 | public void setScrollTo(float x, float y) { 46 | mOffsetX = x * mFactor; 47 | mOffsetY = y * mFactor; 48 | } 49 | 50 | @Override 51 | protected void onBoundsChange(Rect bounds) { 52 | // Changed the bounds of the Wrapped Drawable 53 | mWrappedDrawable.setBounds(bounds.left, bounds.top, bounds.left + mWidth, bounds.top + mHeight); 54 | } 55 | 56 | @Override 57 | public void draw(final Canvas canvas) { 58 | canvas.translate(-mOffsetX, -mOffsetY); 59 | mWrappedDrawable.draw(canvas); 60 | canvas.translate(mOffsetX, mOffsetY); 61 | } 62 | 63 | // ---- 64 | // Wrapped methods 65 | // ---- 66 | 67 | @Override 68 | public void setAlpha(int alpha) { 69 | mWrappedDrawable.setAlpha(alpha); 70 | } 71 | 72 | @Override 73 | public void setColorFilter(ColorFilter cf) { 74 | mWrappedDrawable.setColorFilter(cf); 75 | } 76 | 77 | @Override 78 | public int getOpacity() { 79 | return mWrappedDrawable.getOpacity(); 80 | } 81 | 82 | @Override 83 | public boolean setState(int[] stateSet) { 84 | super.setState(stateSet); 85 | return mWrappedDrawable.setState(stateSet); 86 | } 87 | 88 | @Override 89 | public ConstantState getConstantState() { 90 | return mWrappedDrawable.getConstantState(); 91 | } 92 | 93 | @Override 94 | public void invalidateSelf() { 95 | super.invalidateSelf(); 96 | mWrappedDrawable.invalidateSelf(); 97 | } 98 | 99 | @Override 100 | public boolean isStateful() { 101 | return mWrappedDrawable.isStateful(); 102 | } 103 | 104 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 105 | @Override 106 | public void jumpToCurrentState() { 107 | mWrappedDrawable.jumpToCurrentState(); 108 | } 109 | 110 | @Override 111 | public int[] getState() { 112 | return mWrappedDrawable.getState(); 113 | } 114 | 115 | @Override 116 | public Drawable mutate() { 117 | return mWrappedDrawable.mutate(); 118 | } 119 | 120 | @Override 121 | public int getIntrinsicHeight() { 122 | return 0; 123 | } 124 | 125 | @Override 126 | public int getIntrinsicWidth() { 127 | return 0; 128 | } 129 | 130 | @Override 131 | public int getMinimumWidth() { 132 | return 0; 133 | } 134 | 135 | @Override 136 | public int getMinimumHeight() { 137 | return 0; 138 | } 139 | 140 | @Override 141 | public boolean getPadding(Rect padding) { 142 | return mWrappedDrawable.getPadding(padding); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /paralloidexample/src/main/java/uk/co/chrisjenx/paralloidexample/HomeActivity.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloidexample; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentActivity; 6 | import android.support.v4.app.FragmentManager; 7 | import android.support.v4.app.FragmentPagerAdapter; 8 | import android.support.v4.app.FragmentStatePagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.view.Menu; 11 | 12 | public class HomeActivity extends FragmentActivity { 13 | 14 | /** 15 | * The {@link android.support.v4.view.PagerAdapter} that will provide 16 | * fragments for each of the sections. We use a 17 | * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which 18 | * will keep every loaded fragment in memory. If this becomes too memory 19 | * intensive, it may be best to switch to a 20 | * {@link android.support.v4.app.FragmentStatePagerAdapter}. 21 | */ 22 | SectionsPagerAdapter mSectionsPagerAdapter; 23 | 24 | /** 25 | * The {@link ViewPager} that will host the section contents. 26 | */ 27 | ViewPager mViewPager; 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_home); 33 | 34 | 35 | // Create the adapter that will return a fragment for each of the three 36 | // primary sections of the app. 37 | mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 38 | 39 | // Set up the ViewPager with the sections adapter. 40 | mViewPager = (ViewPager) findViewById(R.id.pager); 41 | mViewPager.setAdapter(mSectionsPagerAdapter); 42 | 43 | } 44 | 45 | @Override 46 | public boolean onCreateOptionsMenu(Menu menu) { 47 | // Inflate the menu; this adds items to the action bar if it is present. 48 | getMenuInflater().inflate(R.menu.home, menu); 49 | return true; 50 | } 51 | 52 | 53 | /** 54 | * A {@link FragmentPagerAdapter} that returns a fragment corresponding to 55 | * one of the sections/tabs/pages. 56 | */ 57 | public class SectionsPagerAdapter extends FragmentStatePagerAdapter { 58 | 59 | public SectionsPagerAdapter(FragmentManager fm) { 60 | super(fm); 61 | } 62 | 63 | @Override 64 | public Fragment getItem(int position) { 65 | switch (position) { 66 | default: 67 | case 0: 68 | return new ParallaxViewUpFragment(); 69 | case 1: 70 | return new ShiftBackgroundFragment(); 71 | case 2: 72 | return new ParallaxBackgroundFragment(); 73 | case 3: 74 | return new ParallaxBackgroundListFragment(); 75 | case 4: 76 | return new OverParallaxBackgroundListFragment(); 77 | case 5: 78 | return new ParallaxViewDownFragment(); 79 | case 6: 80 | return new ParallaxViewRightFragment(); 81 | case 7: 82 | return new ParallaxViewCombiFragment(); 83 | } 84 | } 85 | 86 | @Override 87 | public int getCount() { 88 | return 8; 89 | } 90 | 91 | @Override 92 | public CharSequence getPageTitle(int position) { 93 | switch (position) { 94 | case 0: 95 | return getString(R.string.title_section1); 96 | case 1: 97 | return getString(R.string.title_section2); 98 | case 2: 99 | return getString(R.string.title_section3); 100 | case 3: 101 | return getString(R.string.title_section4); 102 | case 4: 103 | return getString(R.string.title_section5); 104 | case 5: 105 | return getString(R.string.title_invert_transformer); 106 | case 6: 107 | return getString(R.string.title_transform_right); 108 | case 7: 109 | return getString(R.string.title_transform_combi); 110 | } 111 | return null; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Paralloid - DEPRECATED 2 | ========= 3 | 4 | DEPRECATED - Use the project for more of guide and ideas how to apply parallax techniques. I will not support this library anymore. 5 | 6 | Paralloid - (Pah-rah-loid) The Android Parallax library 7 | 8 | Compatible back to API 7 9 | 10 | An example application, [Paralloid Library Example](https://play.google.com/store/apps/details?id=uk.co.chrisjenx.paralloidexample&hl=en), can be downloaded from the Play Store. 11 | 12 | ParallaxScrollView is dead.. 13 | ---------------------------- 14 | 15 | I originally wrote ParallaxScrollView a while back as proof of concept, people took surprisingly well to it; 16 | but from the get-go it was a fundamentally flawed. 17 | 18 | Tightly-coupled and inflexible, made it difficult to maintain and confusing for people to use. 19 | 20 | Features 21 | -------- 22 | 23 | Currently limited but will expand when requests. 24 | 25 | + Parallax another view when the parent scrolls. 26 | + Parallax multiple backgrounds. 27 | + Transformers, Parallax in different ways and directions 28 | 29 | __Supports:__ 30 | 31 | - `ListView` 32 | - `ScrollView` 33 | - `HorizontalScrollView` 34 | 35 | 36 | Modular 37 | ------- 38 | 39 | Paralloid is designed to be modular and very loosely coupled (to an extent). 40 | 41 | Two high level modules exist 42 | 43 | - `paralloid` - which is the library which everything extends from. 44 | - `paralloidviews` - which extends the library with a couple of pre-extended ScrollableViews. 45 | - `paralloidexamples` - which is of course the examples App. 46 | 47 | Generally use `paralloidviews` as it contains everything you need to get going. 48 | 49 | Getting Started 50 | --------------- 51 | 52 | ### Dependency 53 | 54 | _Currently I only support Gradle_ 55 | 56 | #### Locally: 57 | 58 | Temporary steps from @therealkris. 59 | 60 | - First, I cloned the library into `myproject/libs/paralloid`. 61 | - In my `settings.gradle`, I added include `':libs:paralloid:paralloid'`, `':libs:paralloid:paralloidviews'`. 62 | - In my `build.gradle`, I added `compile project(':libs:paralloid:paralloid')`, `project(':libs:paralloid:paralloidviews')`. 63 | - In `libs/paralloid/paralloid`, I removed the `uploadArchives {}` block. 64 | - In `libs/paralloid/paralloidviews`, I removed the `uploadArchives {}` block AND changed the dependency to read: `compile project(':libs:paralloid:paralloid')` instead of `compile project(':paralloid')` 65 | 66 | #### Or Repository (coming soon): 67 | 68 | dependencies { 69 | compile 'uk.co.chrisjenx.paralloid:paralloid:0.1.+' 70 | } 71 | 72 | ### Layout 73 | 74 | #### ScrollView 75 | 76 | This is an example, please refer to the `paralloidexample` App for full code. 77 | 78 | 79 | 83 | 84 | 89 | 90 | 96 | 97 | 98 | 99 | 100 | 101 | ### Fragment 102 | 103 | Inside your `onViewCreated()` or `onCreateView()`. 104 | 105 | //... 106 | FrameLayout topContent = (FrameLayout) rootView.findViewById(R.id.top_content); 107 | ScrollView scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view); 108 | if (scrollView instanceof Parallaxor) { 109 | ((Parallaxor) scrollView).parallaxViewBy(topContent, 0.5f); 110 | } 111 | // TODO: add content to top/scroll content 112 | 113 | 114 | Thats it! 115 | 116 | Have a look at the `Parallaxor` interface for applicable Parallax methods. 117 | 118 | 119 | Custom Views 120 | ------------- 121 | 122 | I tried to keep this as simple as possible, you can nearly copy and paste this. 123 | 124 | - Extend the Scrollable view (or the one you allready have). 125 | - Implement the `Parallaxor` interface. 126 | - Job done! See below for an example 127 | 128 | __Example implementation:__ 129 | 130 | public class MyScrollView extends ScrollView implements Parallaxor { 131 | //... 132 | ParallaxViewController mParallaxViewController; 133 | 134 | // Call init() in constructors 135 | private void init() { 136 | mParallaxViewController = ParallaxViewController.wrap(this); 137 | } 138 | 139 | @Override 140 | protected void onScrollChanged(int l, int t, int oldl, int oldt) { 141 | super.onScrollChanged(l, t, oldl, oldt); 142 | mParallaxViewController.onScrollChanged(this, l, t, oldl, oldt); 143 | } 144 | 145 | // region Implementation of Parallaxor 146 | 147 | @Override 148 | public void parallaxViewBy(View view, float multiplier) { 149 | mParallaxViewController.parallaxViewBy(view, multiplier); 150 | } 151 | 152 | @Override 153 | public void parallaxViewBy(View view, Transformer transformer, float multiplier) { 154 | mParallaxViewController.parallaxViewBy(view, transformer, multiplier); 155 | } 156 | 157 | @Override 158 | public void parallaxViewBackgroundBy(View view, Drawable drawable, float multiplier) { 159 | mParallaxViewController.parallaxViewBackgroundBy(view, drawable, multiplier); 160 | } 161 | 162 | // endregion 163 | } 164 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/utils/ParallaxHelper.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid.utils; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.os.Build; 5 | import android.view.View; 6 | import android.view.ViewTreeObserver; 7 | import android.widget.AbsListView; 8 | import android.widget.HorizontalScrollView; 9 | import android.widget.ScrollView; 10 | 11 | import uk.co.chrisjenx.paralloid.graphics.ParallaxDrawable; 12 | import uk.co.chrisjenx.paralloid.measure.AbsListScrollSize; 13 | import uk.co.chrisjenx.paralloid.transform.Transformer; 14 | 15 | /** 16 | * Created by chris on 02/10/2013 17 | * Project: Paralloid 18 | */ 19 | public final class ParallaxHelper { 20 | 21 | public static void scrollViewBy(final View view, final int x, final int y, final float factor) { 22 | if (view == null) return; 23 | view.scrollTo((int) (x * factor), (int) (y * factor)); 24 | } 25 | 26 | public static void scrollViewBy(final View view, final int x, final int y, final Transformer transformer, final float factor) { 27 | if (view == null || transformer == null) return; 28 | final int[] transform = transformer.scroll(x, y, factor); 29 | view.scrollTo(transform[0], transform[1]); 30 | } 31 | 32 | public static void scrollParallaxDrawableBy(final ParallaxDrawable drawable, final int scrollX, final int scrollY) { 33 | if (drawable == null) return; 34 | drawable.setScrollTo(scrollX, scrollY); 35 | } 36 | 37 | 38 | public static ParallaxDrawable getParallaxDrawable(final Drawable drawable, float factor) { 39 | if(drawable == null) return null; 40 | return new ParallaxDrawable(drawable, factor); 41 | } 42 | 43 | 44 | public static void setParallaxBackground(final View view, final ParallaxDrawable parallaxDrawable) { 45 | if (view == null || parallaxDrawable == null) return; 46 | // We request the size before attaching just incase the view has drawn we can pre populate the drawable with the extra height/width 47 | requestScrollableWidthHeight(view, parallaxDrawable.getFactor(), new ParallaxHelper.ScrollableWidthHeightCallback() { 48 | @Override 49 | public void onScrollableWidthHeight(final float width, final float height) { 50 | // This is called back when the view has (hopefully) the correct width/height 51 | parallaxDrawable.setParallaxExtraWidthHeight(width, height); 52 | } 53 | }); 54 | view.setBackgroundDrawable(parallaxDrawable); 55 | fixParallaxBackgroundPreJBMR1(view, parallaxDrawable); 56 | } 57 | 58 | static void requestScrollableWidthHeight(final View view, final float multiplier, final ScrollableWidthHeightCallback callback) { 59 | if (callback == null) return; 60 | // Have we done a layout pass? 61 | if (view.getHeight() > 0 || view.getWidth() > 0) { 62 | final float[] xy = calculateScrollableWidthHeightFromView(view, multiplier); 63 | callback.onScrollableWidthHeight(xy[0], xy[1]); 64 | } else { 65 | // Call back to self when we have laid out 66 | view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 67 | @Override 68 | public boolean onPreDraw() { 69 | view.getViewTreeObserver().removeOnPreDrawListener(this); 70 | requestScrollableWidthHeight(view, multiplier, callback); 71 | return true; 72 | } 73 | }); 74 | } 75 | } 76 | 77 | static float[] calculateScrollableWidthHeightFromView(View view, float factor) { 78 | if (view == null) return new float[2]; 79 | if (view instanceof ScrollView) { 80 | // Get the ScrollView's only child 81 | final View child = ((ScrollView) view).getChildAt(0); 82 | 83 | return new float[]{view.getWidth(), calculateExtraScroll(view.getHeight(), child.getHeight(), factor)}; 84 | } 85 | if (view instanceof HorizontalScrollView) { 86 | // Get the ScrollView's only child 87 | final View child = ((HorizontalScrollView) view).getChildAt(0); 88 | return new float[]{calculateExtraScroll(view.getWidth(), child.getWidth(), factor), view.getHeight()}; 89 | } 90 | if (view instanceof AbsListView) { 91 | final AbsListScrollSize absListScrollSize = new AbsListScrollSize((AbsListView) view); 92 | float estimatedHeight = calculateExtraScroll( 93 | view.getHeight(), 94 | absListScrollSize.getMaxScrollY(), 95 | factor); 96 | // Log.d("Parallax", "Est Height: " + estimatedHeight); 97 | return new float[]{absListScrollSize.getMaxScrollX(), estimatedHeight}; 98 | } 99 | // Not sure what it is? Just use the width/height 100 | return new float[]{ 101 | calculateExtraScroll(view.getWidth(), view.getWidth(), factor), 102 | calculateExtraScroll(view.getHeight(), view.getHeight(), factor) 103 | }; 104 | } 105 | 106 | static float calculateExtraScroll(float parent, float child, float factor) { 107 | return parent + (child - parent) * factor; 108 | } 109 | 110 | /** 111 | * Hack to fix pre JB MR1 Kudos to @cyrilmottier 112 | * 113 | * @param view view drawable attached too. 114 | * @param drawable drawable which gets invalidated 115 | */ 116 | static void fixParallaxBackgroundPreJBMR1(final View view, final Drawable drawable) { 117 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 118 | drawable.setCallback(new Drawable.Callback() { 119 | @Override 120 | public void invalidateDrawable(Drawable who) { 121 | view.setBackgroundDrawable(who); 122 | } 123 | 124 | @Override 125 | public void scheduleDrawable(Drawable who, Runnable what, long when) { 126 | } 127 | 128 | @Override 129 | public void unscheduleDrawable(Drawable who, Runnable what) { 130 | } 131 | }); 132 | } 133 | } 134 | 135 | static interface ScrollableWidthHeightCallback { 136 | void onScrollableWidthHeight(float width, float height); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /paralloid/src/main/java/uk/co/chrisjenx/paralloid/ParallaxController.java: -------------------------------------------------------------------------------- 1 | package uk.co.chrisjenx.paralloid; 2 | 3 | import android.graphics.drawable.Drawable; 4 | import android.view.View; 5 | 6 | import java.util.Iterator; 7 | import java.util.Set; 8 | import java.util.WeakHashMap; 9 | 10 | import uk.co.chrisjenx.paralloid.graphics.ParallaxDrawable; 11 | import uk.co.chrisjenx.paralloid.transform.Transformer; 12 | import uk.co.chrisjenx.paralloid.utils.ParallaxHelper; 13 | 14 | /** 15 | * Parallax Controller that take input from anything. 16 | *

17 | * Created by chris on 23/10/2013 18 | * Project: Paralloid 19 | */ 20 | public class ParallaxController implements ParallaxorListener { 21 | 22 | public static final String TAG = ParallaxController.class.getSimpleName(); 23 | /** 24 | * HashMap which contains the parallaxed views. 25 | */ 26 | protected WeakHashMap mViewHashMap; 27 | /** 28 | * The Background of Views to Parallax 29 | */ 30 | protected WeakHashMap mParallaxDrawableMap; 31 | /** 32 | * The Optional Scroll Changed Listener for the user to listen to scroll events. 33 | */ 34 | protected OnScrollChangedListener mScrollChangedListener; 35 | /** 36 | * Gets set to true if a View which has its own OnScrollListener 37 | */ 38 | protected boolean mIgnoreOnScrollListener; 39 | // 40 | protected int mLastScrollX = 0; 41 | protected int mLastScrollY = 0; 42 | 43 | /** 44 | * The Wrapped Object 45 | */ 46 | protected final T mWrapped; 47 | 48 | protected ParallaxController(T wrapped) { 49 | mWrapped = wrapped; 50 | } 51 | 52 | public T getWrapped() { 53 | return mWrapped; 54 | } 55 | 56 | /** 57 | * Add a view to be parallax'd by. If already set this will replace the current factor. 58 | * 59 | * @param view passing in yourself will throw an exception. 60 | * @param multiplier passing in 61 | */ 62 | public void parallaxViewBy(View view, float multiplier) { 63 | parallaxViewBy(view, null, multiplier); 64 | } 65 | 66 | @Override 67 | public void parallaxViewBy(View view, Transformer transformer, float multiplier) { 68 | if (view == null) return; 69 | if (view == mWrapped) 70 | throw new IllegalArgumentException("You can't parallax yourself, this would end badly, Parallax other Views"); 71 | checkViewMap(); 72 | 73 | mViewHashMap.put(view, new ParallaxViewInfo(multiplier, transformer)); 74 | // We force this to update the view just added 75 | onScrollChanged(mLastScrollX, mLastScrollY, mLastScrollX, mLastScrollY, true); 76 | } 77 | 78 | /** 79 | * @param view View which to attach the drawable to. (null will do nothing) 80 | * @param drawable Drawable to Parallax (null will do nothing) 81 | * @param multiplier How much to move it by, 1 would be a 1:1 relationship. 0.5 would move the. 82 | * Passing in 0 will make the background not move at all. 83 | */ 84 | @Override 85 | public void parallaxViewBackgroundBy(final View view, final Drawable drawable, final float multiplier) { 86 | if (view == null) return; 87 | checkBackgroundMap(); 88 | 89 | final ParallaxDrawable parallaxBackground = ParallaxHelper.getParallaxDrawable(drawable, multiplier); 90 | ParallaxHelper.setParallaxBackground(view, parallaxBackground); 91 | mParallaxDrawableMap.put(view, parallaxBackground); 92 | } 93 | 94 | /** 95 | * Feel free to implement {@link OnScrollChangedListener} to get call 96 | * backs to the wrapped view for scroll changed events. 97 | *

98 | * Note: this will get called, AFTER any parallax modification. 99 | * 100 | * @param onScrollChangedListener Null is valid (it will remove it if set). 101 | */ 102 | @Override 103 | public void setOnScrollListener(OnScrollChangedListener onScrollChangedListener) { 104 | mScrollChangedListener = onScrollChangedListener; 105 | } 106 | 107 | /** 108 | * Used to do parallax, Your implementation should call directly through to this. Some implementations ignore this 109 | * on purpose (e.g. the ListView) 110 | * 111 | * @param who if Who != getWrapped we ignore scrolling, only the object the controller is attached too can 112 | * scroll it. 113 | */ 114 | @Override 115 | public final void onScrollChanged(Object who, int l, int t, int oldl, int oldt) { 116 | if (who != getWrapped() || mIgnoreOnScrollListener) return; 117 | onScrollChanged(l, t, oldl, oldt, false); 118 | } 119 | 120 | protected final void onScrollChanged(int offsetX, int offsetY, int oldOffsetX, int oldOffsetY, boolean force) { 121 | if (offsetX != oldOffsetX || offsetY != oldOffsetY || force) { 122 | doScrollChanged(offsetX, offsetY, oldOffsetX, oldOffsetY); 123 | } 124 | } 125 | 126 | /** 127 | * Will do the scroll changed stuff. 128 | * 129 | * @param x currentX of Parallaxor View 130 | * @param y currentX of Parallaxor View 131 | * @param oldX Previous X 132 | * @param oldY Previous Y 133 | */ 134 | protected final void doScrollChanged(final int x, final int y, final int oldX, final int oldY) { 135 | doScrollViews(x, y); 136 | //Parallax this background if we can 137 | doScrollBackground(x, y); 138 | // Scroll Changed Listener 139 | doScrollListener(getWrapped(), x, y, oldX, oldY); 140 | 141 | // Set new LastScrollPos 142 | mLastScrollX = x; 143 | mLastScrollY = y; 144 | } 145 | 146 | // -- 147 | // doScrollChanged Pointers to keep memory consumption down during fast scrolling 148 | // 149 | private Set keySetPointer; 150 | private Iterator iteratorPointer; 151 | private ParallaxViewInfo parallaxInfoPointer; 152 | private ParallaxDrawable parallaxDrawablePointer; 153 | private View viewPointer; 154 | // -- 155 | 156 | private final void doScrollViews(final int x, final int y) { 157 | if (mViewHashMap == null) return; 158 | keySetPointer = mViewHashMap.keySet(); 159 | iteratorPointer = keySetPointer.iterator(); 160 | while (iteratorPointer.hasNext()) { 161 | viewPointer = iteratorPointer.next(); 162 | 163 | if (viewPointer == null) 164 | continue; 165 | 166 | // Get Value 167 | parallaxInfoPointer = mViewHashMap.get(viewPointer); 168 | 169 | // Parallax the other view 170 | ParallaxHelper.scrollViewBy(viewPointer, x, y, parallaxInfoPointer.interpolator, parallaxInfoPointer.factor); 171 | } 172 | } 173 | 174 | private final void doScrollBackground(final int x, final int y) { 175 | if (mParallaxDrawableMap == null) return; 176 | 177 | keySetPointer = mParallaxDrawableMap.keySet(); 178 | iteratorPointer = keySetPointer.iterator(); 179 | while (iteratorPointer.hasNext()) { 180 | viewPointer = iteratorPointer.next(); 181 | 182 | if (viewPointer == null) 183 | continue; 184 | 185 | // Get Value 186 | parallaxDrawablePointer = mParallaxDrawableMap.get(viewPointer); 187 | 188 | // Parallax the drawable 189 | ParallaxHelper.scrollParallaxDrawableBy(parallaxDrawablePointer, x, y); 190 | } 191 | 192 | } 193 | 194 | private final void doScrollListener(final Object who, final int x, final int y, final int oldX, final int oldY) { 195 | if (mScrollChangedListener != null && (x != oldX || y != oldY)) { 196 | mScrollChangedListener.onScrollChanged(who, x, y, oldX, oldY); 197 | } 198 | } 199 | 200 | /** 201 | * Checks the viewMap is ready to use. 202 | */ 203 | private final void checkViewMap() { 204 | if (mViewHashMap == null) 205 | mViewHashMap = new WeakHashMap(); 206 | } 207 | 208 | /** 209 | * Checks the BackgroundMap is ready to use. 210 | */ 211 | private final void checkBackgroundMap() { 212 | if (mParallaxDrawableMap == null) 213 | mParallaxDrawableMap = new WeakHashMap(); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | --------------------------------------------------------------------------------