diff --git a/.travis.yml b/.travis.yml index 515d331..452e48d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,33 +1,25 @@ -language: java -jdk: oraclejdk7 -env: - matrix: - - ANDROID_TARGET=android-20 ANDROID_ABI=armeabi-v7a +language: android +android: + components: + # Uncomment the lines below if you want to + # use the latest revision of Android SDK Tools + # - platform-tools + # - tools -before_install: - # Install base Android SDK - - sudo apt-get update -qq - - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch > /dev/null; fi - - wget http://dl.google.com/android/android-sdk_r23-linux.tgz - - tar xzf android-sdk_r23-linux.tgz - - export ANDROID_HOME=$PWD/android-sdk-linux - - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools + # The BuildTools version used by your project + - build-tools-22.0.1 - # Gradle - - wget http://services.gradle.org/distributions/gradle-1.12-bin.zip - - unzip gradle-1.12-bin.zip - - export GRADLE_HOME=$PWD/gradle-1.12 - - export PATH=$GRADLE_HOME/bin:$PATH + # The SDK version used to compile your project + - android-22 - # Install required components - # For a full list, run `android list sdk -a --extended` - # Note that sysimg-19 downloads only ARM, because only the first license query is accepted. - - echo yes | android update sdk --filter platform-tools --no-ui --force > /dev/null - - echo yes | android update sdk --all --filter build-tools-20.0.0 --no-ui --force > /dev/null - - echo yes | android update sdk --filter android-20 --no-ui --force > /dev/null - - echo yes | android update sdk --filter sys-img-x86-android-19 --no-ui --force > /dev/null - - echo yes | android update sdk --filter extra-android-support --no-ui --force > /dev/null - - echo yes | android update sdk --filter extra-android-m2repository --no-ui --force > /dev/null + # Additional components + - extra-google-google_play_services + - extra-google-m2repository + - extra-android-m2repository + - addon-google_apis-google-19 -install: - - ./gradlew assemble \ No newline at end of file + # Specify at least one system image, + # if you need to run emulator(s) during your tests + - sys-img-armeabi-v7a-android-19 + - sys-img-x86-android-17 +script: ./gradlew assembleDebug diff --git a/README.md b/README.md index 60db822..a96a07a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ dependencies { compile "com.android.support:support-v4:+" compile 'com.squareup.picasso:picasso:2.3.2' compile 'com.nineoldandroids:library:2.4.0' - compile 'com.daimajia.slider:library:1.1.2@aar' + compile 'com.daimajia.slider:library:1.1.5@aar' } ``` diff --git a/build.gradle b/build.gradle index 2d50cf7..49166ee 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,15 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +task wrapper(type: Wrapper) { + gradleVersion = '2.2.1' +} + buildscript { repositories { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.12.+' + classpath 'com.android.tools.build:gradle:1.1.2' classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.10.+' } } diff --git a/demo/build.gradle b/demo/build.gradle index b227c58..de31b19 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -1,20 +1,19 @@ apply plugin: 'android-sdk-manager' -apply plugin: 'android' +apply plugin: 'com.android.application' android { - compileSdkVersion 20 - buildToolsVersion "20" + compileSdkVersion 22 + buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 8 - targetSdkVersion 20 + targetSdkVersion 22 versionCode 2 versionName "1.0.1" } buildTypes { release { - runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } @@ -23,7 +22,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':library') - compile 'com.android.support:appcompat-v7:20.+' + compile 'com.android.support:appcompat-v7:22.+' compile 'com.nineoldandroids:library:2.4.0' compile 'com.daimajia.androidanimations:library:1.0.3@aar' } diff --git a/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java b/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java index c150044..8037dcf 100644 --- a/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java +++ b/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java @@ -4,6 +4,7 @@ import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -18,11 +19,12 @@ import com.daimajia.slider.library.SliderLayout; import com.daimajia.slider.library.SliderTypes.BaseSliderView; import com.daimajia.slider.library.SliderTypes.TextSliderView; +import com.daimajia.slider.library.Tricks.ViewPagerEx; import java.util.HashMap; -public class MainActivity extends ActionBarActivity implements BaseSliderView.OnSliderClickListener{ +public class MainActivity extends ActionBarActivity implements BaseSliderView.OnSliderClickListener, ViewPagerEx.OnPageChangeListener{ private SliderLayout mDemoSlider; @@ -54,8 +56,9 @@ protected void onCreate(Bundle savedInstanceState) { .setOnSliderClickListener(this); //add your extra information + textSliderView.bundle(new Bundle()); textSliderView.getBundle() - .putString("extra",name); + .putString("extra",name); mDemoSlider.addSlider(textSliderView); } @@ -63,6 +66,7 @@ protected void onCreate(Bundle savedInstanceState) { mDemoSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom); mDemoSlider.setCustomAnimation(new DescriptionAnimation()); mDemoSlider.setDuration(4000); + mDemoSlider.addOnPageChangeListener(this); ListView l = (ListView)findViewById(R.id.transformers); l.setAdapter(new TransformerAdapter(this)); l.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -76,6 +80,13 @@ public void onItemClick(AdapterView parent, View view, int position, long id) } + @Override + protected void onStop() { + // To prevent a memory leak on rotation, make sure to call stopAutoCycle() on the slider before activity or fragment is destroyed + mDemoSlider.stopAutoCycle(); + super.onStop(); + } + @Override public void onSliderClick(BaseSliderView slider) { Toast.makeText(this,slider.getBundle().get("extra") + "",Toast.LENGTH_SHORT).show(); @@ -108,4 +119,15 @@ public boolean onOptionsItemSelected(MenuItem item) { } return super.onOptionsItemSelected(item); } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} + + @Override + public void onPageSelected(int position) { + Log.d("Slider Demo", "Page Changed: " + position); + } + + @Override + public void onPageScrollStateChanged(int state) {} } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8c0fb64..085a1cd 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94e85da..918e0f3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Jun 09 09:36:23 CST 2014 +#Sun May 03 23:34:25 CST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/library/build.gradle b/library/build.gradle index 5d9aa29..b2e8cc6 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,18 +1,17 @@ -apply plugin: 'android-library' +apply plugin: 'com.android.library' android { - compileSdkVersion 20 - buildToolsVersion "20" + compileSdkVersion 22 + buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 8 - targetSdkVersion 20 - versionCode 10 - versionName "1.0.9" + targetSdkVersion 22 + versionCode 15 + versionName "1.1.5" } buildTypes { release { - runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } @@ -23,9 +22,9 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:20.+' - compile "com.android.support:support-v4:20.0.+" - compile 'com.squareup.picasso:picasso:+' - compile 'com.nineoldandroids:library:+' + compile 'com.android.support:appcompat-v7:22.1.1' + compile "com.android.support:support-v4:22.1.1" + compile 'com.squareup.picasso:picasso:2.5.2' + compile 'com.nineoldandroids:library:2.4.0' } -apply from: './gradle-mvn-push.gradle' \ No newline at end of file +apply from: './gradle-mvn-push.gradle' diff --git a/library/gradle-mvn-push.gradle b/library/gradle-mvn-push.gradle index ae4b440..873d7b0 100644 --- a/library/gradle-mvn-push.gradle +++ b/library/gradle-mvn-push.gradle @@ -104,9 +104,15 @@ afterEvaluate { project -> } } + task androidJavadocs(type: Javadoc) { - source = android.sourceSets.main - classpath += project.files(android.getBootClasspath() .join(File.pathSeparator)) + source = android.sourceSets.main.java.srcDirs + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + options.links("http://docs.oracle.com/javase/7/docs/api/"); + options.linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference" + exclude '**/BuildConfig.java' + exclude '**/R.java' + failOnError = false } task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { @@ -116,12 +122,12 @@ afterEvaluate { project -> task androidSourcesJar(type: Jar) { classifier = 'sources' - from android.sourceSets.main + from android.sourceSets.main.java.sourceFiles } artifacts { archives androidSourcesJar archives androidJavadocsJar - archives apklib + archives apklib } -} +} \ No newline at end of file diff --git a/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java b/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java index ec14093..b10abee 100644 --- a/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java +++ b/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java @@ -328,7 +328,7 @@ public void setViewPager(ViewPagerEx pager){ throw new IllegalStateException("Viewpager does not have adapter instance"); } mPager = pager; - mPager.setOnPageChangeListener(this); + mPager.addOnPageChangeListener(this); ((InfinitePagerAdapter)mPager.getAdapter()).getRealAdapter().registerDataSetObserver(dataChangeObserver); } @@ -444,11 +444,6 @@ private void setItemAsSelected(int position){ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - if(mItemCount == 0){ - return; - } - int n = position % mItemCount; - setItemAsSelected(n - 1); } public IndicatorVisibility getIndicatorVisibility(){ @@ -457,7 +452,10 @@ public IndicatorVisibility getIndicatorVisibility(){ @Override public void onPageSelected(int position) { - + if(mItemCount == 0){ + return; + } + setItemAsSelected(position-1); } @Override public void onPageScrollStateChanged(int state) { diff --git a/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java b/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java index 238564c..bc0a90a 100644 --- a/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java +++ b/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java @@ -49,7 +49,7 @@ public void removeSlider(T slider){ } public void removeSliderAt(int position){ - if(mImageContents.size() < position){ + if(mImageContents.size() > position){ mImageContents.remove(position); notifyDataSetChanged(); } diff --git a/library/src/main/java/com/daimajia/slider/library/SliderLayout.java b/library/src/main/java/com/daimajia/slider/library/SliderLayout.java index 149f36b..ba36e5e 100644 --- a/library/src/main/java/com/daimajia/slider/library/SliderLayout.java +++ b/library/src/main/java/com/daimajia/slider/library/SliderLayout.java @@ -213,6 +213,16 @@ public boolean onTouch(View v, MotionEvent event) { } } + public void addOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener){ + if(onPageChangeListener != null){ + mViewPager.addOnPageChangeListener(onPageChangeListener); + } + } + + public void removeOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener) { + mViewPager.removeOnPageChangeListener(onPageChangeListener); + } + public void setCustomIndicator(PagerIndicator indicator){ if(mIndicator != null){ mIndicator.destroySelf(); @@ -236,7 +246,7 @@ public void handleMessage(Message msg) { }; public void startAutoCycle(){ - startAutoCycle(1000, mSliderDuration, mAutoRecover); + startAutoCycle(mSliderDuration, mSliderDuration, mAutoRecover); } /** diff --git a/library/src/main/java/com/daimajia/slider/library/SliderTypes/BaseSliderView.java b/library/src/main/java/com/daimajia/slider/library/SliderTypes/BaseSliderView.java index aeaf2b2..8ad1d35 100644 --- a/library/src/main/java/com/daimajia/slider/library/SliderTypes/BaseSliderView.java +++ b/library/src/main/java/com/daimajia/slider/library/SliderTypes/BaseSliderView.java @@ -47,6 +47,8 @@ public abstract class BaseSliderView { private String mDescription; + private Picasso mPicasso; + /** * Scale type of the image. */ @@ -58,7 +60,6 @@ public enum ScaleType{ protected BaseSliderView(Context context) { mContext = context; - this.mBundle = new Bundle(); } /** @@ -138,6 +139,16 @@ public BaseSliderView image(int res){ return this; } + /** + * lets users add a bundle of additional information + * @param bundle + * @return + */ + public BaseSliderView bundle(Bundle bundle){ + mBundle = bundle; + return this; + } + public String getUrl(){ return mUrl; } @@ -192,9 +203,11 @@ public void onClick(View v) { if (targetImageView == null) return; - mLoadListener.onStart(me); + if (mLoadListener != null) { + mLoadListener.onStart(me); + } - Picasso p = Picasso.with(mContext); + Picasso p = (mPicasso != null) ? mPicasso : Picasso.with(mContext); RequestCreator rq = null; if(mUrl!=null){ rq = p.load(mUrl); @@ -293,4 +306,23 @@ public interface ImageLoadListener{ public void onEnd(boolean result,BaseSliderView target); } + /** + * Get the last instance set via setPicasso(), or null if no user provided instance was set + * + * @return The current user-provided Picasso instance, or null if none + */ + public Picasso getPicasso() { + return mPicasso; + } + + /** + * Provide a Picasso instance to use when loading pictures, this is useful if you have a + * particular HTTP cache you would like to share. + * + * @param picasso The Picasso instance to use, may be null to let the system use the default + * instance + */ + public void setPicasso(Picasso picasso) { + mPicasso = picasso; + } } diff --git a/library/src/main/java/com/daimajia/slider/library/Tricks/ViewPagerEx.java b/library/src/main/java/com/daimajia/slider/library/Tricks/ViewPagerEx.java index 6df86fa..8927d26 100644 --- a/library/src/main/java/com/daimajia/slider/library/Tricks/ViewPagerEx.java +++ b/library/src/main/java/com/daimajia/slider/library/Tricks/ViewPagerEx.java @@ -208,7 +208,7 @@ public float getInterpolation(float t) { private boolean mCalledSuper; private int mDecorChildCount; - private OnPageChangeListener mOnPageChangeListener; + private ArrayList mOnPageChangeListeners = new ArrayList<>(); private OnPageChangeListener mInternalPageChangeListener; private OnAdapterChangeListener mAdapterChangeListener; private PageTransformer mPageTransformer; @@ -305,6 +305,21 @@ public void onPageScrollStateChanged(int state) { } } + private void triggerOnPageChangeEvent(int position) { + for (OnPageChangeListener eachListener : mOnPageChangeListeners) { + if (eachListener != null) { + InfinitePagerAdapter infiniteAdapter = (InfinitePagerAdapter)mAdapter; + if (infiniteAdapter.getRealCount() == 0) { + return; + } + int n = position % infiniteAdapter.getRealCount(); + eachListener.onPageSelected(n); + } + } + if (mInternalPageChangeListener != null) { + mInternalPageChangeListener.onPageSelected(position); + } + } /** * A PageTransformer is invoked whenever a visible/attached page is scrolled. * This offers an opportunity for the application to apply a custom transformation @@ -394,8 +409,10 @@ private void setScrollState(int newState) { // PageTransformers can do complex things that benefit from hardware layers. enableLayers(newState != SCROLL_STATE_IDLE); } - if (mOnPageChangeListener != null) { - mOnPageChangeListener.onPageScrollStateChanged(newState); + for (OnPageChangeListener eachListener : mOnPageChangeListeners) { + if (eachListener != null) { + eachListener.onPageScrollStateChanged(newState); + } } } @@ -539,12 +556,7 @@ void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int // We don't have any idea how big we are yet and shouldn't have any pages either. // Just set things up and let the pending layout handle things. mCurItem = item; - if (dispatchSelected && mOnPageChangeListener != null) { - mOnPageChangeListener.onPageSelected(item); - } - if (dispatchSelected && mInternalPageChangeListener != null) { - mInternalPageChangeListener.onPageSelected(item); - } + triggerOnPageChangeEvent(item); requestLayout(); } else { populate(item); @@ -563,18 +575,12 @@ private void scrollToItem(int item, boolean smoothScroll, int velocity, } if (smoothScroll) { smoothScrollTo(destX, 0, velocity); - if (dispatchSelected && mOnPageChangeListener != null) { - mOnPageChangeListener.onPageSelected(item); - } - if (dispatchSelected && mInternalPageChangeListener != null) { - mInternalPageChangeListener.onPageSelected(item); + if (dispatchSelected) { + triggerOnPageChangeEvent(item); } } else { - if (dispatchSelected && mOnPageChangeListener != null) { - mOnPageChangeListener.onPageSelected(item); - } - if (dispatchSelected && mInternalPageChangeListener != null) { - mInternalPageChangeListener.onPageSelected(item); + if (dispatchSelected) { + triggerOnPageChangeEvent(item); } completeScroll(false); scrollTo(destX, 0); @@ -583,13 +589,25 @@ private void scrollToItem(int item, boolean smoothScroll, int velocity, } /** - * Set a listener that will be invoked whenever the page changes or is incrementally + * Add a listener that will be invoked whenever the page changes or is incrementally * scrolled. See {@link OnPageChangeListener}. * - * @param listener Listener to set + * @param listener Listener to add + */ + public void addOnPageChangeListener(OnPageChangeListener listener) { + if (!mOnPageChangeListeners.contains(listener)) { + mOnPageChangeListeners.add(listener); + } + } + + /** + * Remove a listener that was added with addOnPageChangeListener + * See {@link OnPageChangeListener}. + * + * @param listener Listener to remove */ - public void setOnPageChangeListener(OnPageChangeListener listener) { - mOnPageChangeListener = listener; + public void removeOnPageChangeListener(OnPageChangeListener listener) { + mOnPageChangeListeners.remove(listener); } /** @@ -1706,9 +1724,10 @@ protected void onPageScrolled(int position, float offset, int offsetPixels) { } } } - - if (mOnPageChangeListener != null) { - mOnPageChangeListener.onPageScrolled(position, offset, offsetPixels); + for (OnPageChangeListener eachListener : mOnPageChangeListeners) { + if (eachListener != null) { + eachListener.onPageScrolled(position, offset, offsetPixels); + } } if (mInternalPageChangeListener != null) { mInternalPageChangeListener.onPageScrolled(position, offset, offsetPixels);