├── .gitignore ├── CHNAGELOG.md ├── FlycoBanner_Lib ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── flyco │ │ └── banner │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── flyco │ │ └── banner │ │ ├── anim │ │ ├── BaseAnimator.java │ │ ├── select │ │ │ ├── RotateEnter.java │ │ │ └── ZoomInEnter.java │ │ └── unselect │ │ │ └── NoAnimExist.java │ │ ├── transform │ │ ├── DepthTransformer.java │ │ ├── FadeSlideTransformer.java │ │ ├── FlowTransformer.java │ │ ├── RotateDownTransformer.java │ │ ├── RotateUpTransformer.java │ │ └── ZoomOutSlideTransformer.java │ │ └── widget │ │ ├── Banner │ │ ├── BaseIndicatorBanner.java │ │ └── base │ │ │ └── BaseBanner.java │ │ └── LoopViewPager │ │ ├── FixedSpeedScroller.java │ │ ├── LoopPagerAdapterWrapper.java │ │ └── LoopViewPager.java │ └── res │ └── values │ └── attrs.xml ├── LICENSE ├── README.md ├── README_CN.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── flyco │ │ └── bannersamples │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── flyco │ │ └── bannersamples │ │ ├── banner │ │ ├── SimpleGuideBanner.java │ │ ├── SimpleImageBanner.java │ │ └── SimpleTextBanner.java │ │ ├── dialog │ │ └── BannerDialog.java │ │ ├── entity │ │ └── BannerItem.java │ │ ├── ui │ │ ├── BannerHomeActivity.java │ │ └── UserGuideActivity.java │ │ └── utils │ │ ├── DataProvider.java │ │ ├── T.java │ │ └── ViewFindUtils.java │ └── res │ ├── drawable │ └── corner_white.xml │ ├── layout │ ├── activity_main.xml │ ├── activity_user_guide.xml │ ├── adapter_simple_guide.xml │ ├── adapter_simple_image.xml │ ├── adapter_simple_text.xml │ └── dialog_banner.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── banner_dot_select.png │ ├── banner_dot_unselect.png │ ├── guide_img_1.png │ ├── guide_img_2.png │ ├── guide_img_3.png │ ├── guide_img_4.png │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── preview_FlycoBanner.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | build 4 | .idea 5 | *.iml 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /CHNAGELOG.md: -------------------------------------------------------------------------------- 1 | #Change Log 2 | Version 1.0.1 *(2015-09-18)* 3 | ---------------------------- 4 | * remove default scale for LoopViewPager 5 | 6 | Version 1.1.0 *(2015-09-20)* 7 | ---------------------------- 8 | * use origin ViewPager instead of ViewPagerCompat, so PageTransformer needs API 3.0 and up. 9 | if you want PageTransformer in lower version, use dependencies down V1.1.0,such as 'com.flyco.banner:FlycoBanner_Lib:1.0 10 | 11 | Version 1.1.2 *(2015-09-22)* 12 | ---------------------------- 13 | * use addOnPageChangeListener instead of setOnPageChangeListener everywhere in library. 14 | 15 | Version 1.1.4 *(2015-09-22)* 16 | ---------------------------- 17 | * fix bug:abstract method onCreateIndicator return null lead to crash. 18 | 19 | Version 1.1.6 *(2015-09-22)* 20 | ---------------------------- 21 | * use list to manage LoopViewPager OnPageChangeListener. 22 | 23 | Version 1.1.8 *(2015-10-09)* 24 | ---------------------------- 25 | * fix a small and update dependence FlycoDialog to the latest v1.1.0 26 | 27 | Version 1.2.0 *(2015-10-20)* 28 | ---------------------------- 29 | * add attribute is_smart,default false; 30 | 31 | Version 2.0.0 *(2016-2-28)* 32 | --------------------------- 33 | * code refactoring 34 | 35 | Version 2.0.2 *(2016-2-28)* 36 | --------------------------- 37 | * unify attribute prefix to bb 38 | 39 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | //apply plugin: 'com.github.dcendents.android-maven' 3 | //apply plugin: 'com.jfrog.bintray' 4 | 5 | // 这个version是区分library版本的,因此当我们需要更新library时记得修改这个version 6 | version = "2.0.2" 7 | android { 8 | compileSdkVersion 22 9 | buildToolsVersion "22.0.1" 10 | 11 | defaultConfig { 12 | minSdkVersion 8 13 | targetSdkVersion 22 14 | versionCode 202 15 | versionName version 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | compile 'com.android.support:support-v4:22.2.1' 28 | compile 'com.nineoldandroids:library:2.4.0' 29 | } 30 | 31 | //def siteUrl = 'https://github.com/H07000223' // 项目的主页 32 | //def gitUrl = 'https://github.com/H07000223' // Git仓库的url 33 | //group = "com.flyco.banner" // Maven Group ID for the artifact,一般填你唯一的包名 34 | //install { 35 | // repositories.mavenInstaller { 36 | // // This generates POM.xml with proper parameters 37 | // pom { 38 | // project { 39 | // packaging 'aar' 40 | // // Add your description here 41 | // name 'Android Banner Library' //项目描述 42 | // url siteUrl 43 | // // Set your license 44 | // licenses { 45 | // license { 46 | // name 'MIT' 47 | // url 'http://opensource.org/licenses/MIT' 48 | // } 49 | // } 50 | // developers { 51 | // developer { 52 | // id 'H07000223' //填写的一些基本信息 53 | // name 'H07000223' 54 | // email '867318349@qq.com' 55 | // } 56 | // } 57 | // scm { 58 | // connection gitUrl 59 | // developerConnection gitUrl 60 | // url siteUrl 61 | // } 62 | // } 63 | // } 64 | // } 65 | //} 66 | // 67 | //task sourcesJar(type: Jar) { 68 | // from android.sourceSets.main.java.srcDirs 69 | // classifier = 'sources' 70 | //} 71 | // 72 | //artifacts { 73 | // archives sourcesJar 74 | //} 75 | // 76 | //android.libraryVariants.all { variant -> 77 | // println variant.javaCompile.classpath.files 78 | // if (variant.name == 'release') { //我们只需 release 的 javadoc 79 | // task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) { 80 | // // title = '' 81 | // // description = '' 82 | // source = variant.javaCompile.source 83 | // classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath()) 84 | // options { 85 | // encoding "utf-8" 86 | // links "http://docs.oracle.com/javase/7/docs/api/" 87 | // linksOffline "http://d.android.com/reference", "${android.sdkDirectory}/docs/reference" 88 | // } 89 | // exclude '**/BuildConfig.java' 90 | // exclude '**/R.java' 91 | // } 92 | // task("javadoc${variant.name.capitalize()}Jar", type: Jar, dependsOn: "generate${variant.name.capitalize()}Javadoc") { 93 | // classifier = 'javadoc' 94 | // from tasks.getByName("generate${variant.name.capitalize()}Javadoc").destinationDir 95 | // } 96 | // artifacts { 97 | // archives tasks.getByName("javadoc${variant.name.capitalize()}Jar") 98 | // } 99 | // } 100 | //} 101 | // 102 | //Properties properties = new Properties() 103 | //properties.load(project.rootProject.file('local.properties').newDataInputStream()) 104 | //bintray { 105 | // user = properties.getProperty("bintray.user") 106 | // key = properties.getProperty("bintray.apikey") 107 | // configurations = ['archives'] 108 | // pkg { 109 | // repo = "maven" 110 | // name = "FlycoBanner_Lib" //发布到JCenter上的项目名字 111 | // websiteUrl = siteUrl 112 | // vcsUrl = gitUrl 113 | // licenses = ["MIT"] 114 | // publish = true 115 | // } 116 | //} 117 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/lihui/work/AndroidStudio/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/androidTest/java/com/flyco/banner/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/anim/BaseAnimator.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.anim; 2 | 3 | import android.view.View; 4 | import android.view.animation.Interpolator; 5 | 6 | import com.nineoldandroids.animation.Animator; 7 | import com.nineoldandroids.animation.AnimatorSet; 8 | import com.nineoldandroids.view.ViewHelper; 9 | 10 | public abstract class BaseAnimator { 11 | protected long mDuration = 500; 12 | protected AnimatorSet mAnimatorSet = new AnimatorSet(); 13 | private Interpolator mInterpolator; 14 | private long mDelay; 15 | private AnimatorListener mListener; 16 | 17 | public abstract void setAnimation(View view); 18 | 19 | protected void start(final View view) { 20 | reset(view); 21 | setAnimation(view); 22 | 23 | mAnimatorSet.setDuration(mDuration); 24 | if (mInterpolator != null) { 25 | mAnimatorSet.setInterpolator(mInterpolator); 26 | } 27 | 28 | if (mDelay > 0) { 29 | mAnimatorSet.setStartDelay(mDelay); 30 | } 31 | 32 | if (mListener != null) { 33 | mAnimatorSet.addListener(new Animator.AnimatorListener() { 34 | @Override 35 | public void onAnimationStart(Animator animator) { 36 | mListener.onAnimationStart(animator); 37 | } 38 | 39 | @Override 40 | public void onAnimationRepeat(Animator animator) { 41 | mListener.onAnimationRepeat(animator); 42 | } 43 | 44 | @Override 45 | public void onAnimationEnd(Animator animator) { 46 | mListener.onAnimationEnd(animator); 47 | } 48 | 49 | @Override 50 | public void onAnimationCancel(Animator animator) { 51 | mListener.onAnimationCancel(animator); 52 | } 53 | }); 54 | } 55 | 56 | mAnimatorSet.start(); 57 | } 58 | 59 | public static void reset(View view) { 60 | ViewHelper.setAlpha(view, 1); 61 | ViewHelper.setScaleX(view, 1); 62 | ViewHelper.setScaleY(view, 1); 63 | ViewHelper.setTranslationX(view, 0); 64 | ViewHelper.setTranslationY(view, 0); 65 | ViewHelper.setRotation(view, 0); 66 | ViewHelper.setRotationY(view, 0); 67 | ViewHelper.setRotationX(view, 0); 68 | } 69 | 70 | public BaseAnimator duration(long duration) { 71 | this.mDuration = duration; 72 | return this; 73 | } 74 | 75 | public BaseAnimator delay(long delay) { 76 | this.mDelay = delay; 77 | return this; 78 | } 79 | 80 | public BaseAnimator interpolator(Interpolator interpolator) { 81 | this.mInterpolator = interpolator; 82 | return this; 83 | } 84 | 85 | public BaseAnimator listener(AnimatorListener listener) { 86 | this.mListener = listener; 87 | return this; 88 | } 89 | 90 | public void playOn(View view) { 91 | start(view); 92 | } 93 | 94 | public interface AnimatorListener { 95 | void onAnimationStart(Animator animator); 96 | 97 | void onAnimationRepeat(Animator animator); 98 | 99 | void onAnimationEnd(Animator animator); 100 | 101 | void onAnimationCancel(Animator animator); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/anim/select/RotateEnter.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.anim.select; 2 | 3 | import android.view.View; 4 | 5 | import com.flyco.banner.anim.BaseAnimator; 6 | import com.nineoldandroids.animation.Animator; 7 | import com.nineoldandroids.animation.ObjectAnimator; 8 | 9 | public class RotateEnter extends BaseAnimator { 10 | public RotateEnter() { 11 | this.mDuration = 200; 12 | } 13 | 14 | public void setAnimation(View view) { 15 | this.mAnimatorSet.playTogether(new Animator[]{ 16 | ObjectAnimator.ofFloat(view, "rotation", 0, 180)}); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/anim/select/ZoomInEnter.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.anim.select; 2 | 3 | import android.view.View; 4 | 5 | import com.flyco.banner.anim.BaseAnimator; 6 | import com.nineoldandroids.animation.Animator; 7 | import com.nineoldandroids.animation.ObjectAnimator; 8 | 9 | public class ZoomInEnter extends BaseAnimator { 10 | public ZoomInEnter() { 11 | this.mDuration = 200; 12 | } 13 | 14 | public void setAnimation(View view) { 15 | this.mAnimatorSet.playTogether(new Animator[]{ 16 | ObjectAnimator.ofFloat(view, "scaleX", new float[]{1.0F, 1.5F}), 17 | ObjectAnimator.ofFloat(view, "scaleY", new float[]{1.0F, 1.5F})}); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/anim/unselect/NoAnimExist.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.anim.unselect; 2 | 3 | import android.view.View; 4 | 5 | import com.flyco.banner.anim.BaseAnimator; 6 | import com.nineoldandroids.animation.Animator; 7 | import com.nineoldandroids.animation.ObjectAnimator; 8 | 9 | public class NoAnimExist extends BaseAnimator { 10 | public NoAnimExist() { 11 | this.mDuration = 200; 12 | } 13 | 14 | public void setAnimation(View view) { 15 | this.mAnimatorSet.playTogether(new Animator[]{ 16 | ObjectAnimator.ofFloat(view, "alpha", 1, 1)}); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/DepthTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class DepthTransformer implements ViewPager.PageTransformer { 9 | private static final float MIN_SCALE_DEPTH = 0.75f; 10 | 11 | @Override 12 | public void transformPage(View page, float position) { 13 | float alpha, scale, translationX; 14 | if (position > 0 && position < 1) { 15 | // moving to the right 16 | alpha = (1 - position); 17 | scale = MIN_SCALE_DEPTH + (1 - MIN_SCALE_DEPTH) * (1 - Math.abs(position)); 18 | translationX = (page.getWidth() * -position); 19 | } else { 20 | // use default for all other cases 21 | alpha = 1; 22 | scale = 1; 23 | translationX = 0; 24 | } 25 | 26 | ViewHelper.setAlpha(page, alpha); 27 | ViewHelper.setTranslationX(page, translationX); 28 | ViewHelper.setScaleX(page, scale); 29 | ViewHelper.setScaleY(page, scale); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/FadeSlideTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class FadeSlideTransformer implements ViewPager.PageTransformer { 9 | @Override 10 | public void transformPage(View page, float position) { 11 | 12 | ViewHelper.setTranslationX(page, 0); 13 | 14 | if (position <= -1.0F || position >= 1.0F) { 15 | ViewHelper.setAlpha(page, 0.0F); 16 | } else if (position == 0.0F) { 17 | ViewHelper.setAlpha(page, 1.0F); 18 | } else { 19 | // position is between -1.0F & 0.0F OR 0.0F & 1.0F 20 | ViewHelper.setAlpha(page, 1.0F - Math.abs(position)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/FlowTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class FlowTransformer implements ViewPager.PageTransformer { 9 | 10 | @Override 11 | public void transformPage(View page, float position) { 12 | ViewHelper.setRotationY(page, position * -30f); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/RotateDownTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class RotateDownTransformer implements ViewPager.PageTransformer { 9 | 10 | private static final float ROT_MOD = -15f; 11 | 12 | @Override 13 | public void transformPage(View page, float position) { 14 | final float width = page.getWidth(); 15 | final float height = page.getHeight(); 16 | final float rotation = ROT_MOD * position * -1.25f; 17 | 18 | ViewHelper.setPivotX(page,width * 0.5f); 19 | ViewHelper.setPivotY(page,height); 20 | ViewHelper.setRotation(page,rotation); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/RotateUpTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class RotateUpTransformer implements ViewPager.PageTransformer { 9 | 10 | private static final float ROT_MOD = -15f; 11 | 12 | @Override 13 | public void transformPage(View page, float position) { 14 | final float width = page.getWidth(); 15 | final float rotation = ROT_MOD * position; 16 | 17 | ViewHelper.setPivotX(page,width * 0.5f); 18 | ViewHelper.setPivotY(page,0f); 19 | ViewHelper.setTranslationX(page,0f); 20 | ViewHelper.setRotation(page,rotation); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/transform/ZoomOutSlideTransformer.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.transform; 2 | 3 | import android.view.View; 4 | import android.support.v4.view.ViewPager; 5 | 6 | import com.nineoldandroids.view.ViewHelper; 7 | 8 | public class ZoomOutSlideTransformer implements ViewPager.PageTransformer { 9 | 10 | private static final float MIN_SCALE = 0.85f; 11 | private static final float MIN_ALPHA = 0.9f; 12 | 13 | @Override 14 | public void transformPage(View page, float position) { 15 | if (position >= -1 || position <= 1) { 16 | // Modify the default slide transition to shrink the page as well 17 | final float height = page.getHeight(); 18 | final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); 19 | final float vertMargin = height * (1 - scaleFactor) / 2; 20 | final float horzMargin = page.getWidth() * (1 - scaleFactor) / 2; 21 | 22 | // Center vertically 23 | ViewHelper.setPivotY(page, 0.5f * height); 24 | 25 | 26 | if (position < 0) { 27 | ViewHelper.setTranslationX(page, horzMargin - vertMargin / 2); 28 | } else { 29 | ViewHelper.setTranslationX(page, -horzMargin + vertMargin / 2); 30 | } 31 | 32 | // Scale the page down (between MIN_SCALE and 1) 33 | ViewHelper.setScaleX(page, scaleFactor); 34 | ViewHelper.setScaleY(page, scaleFactor); 35 | 36 | // Fade the page relative to its size. 37 | ViewHelper.setAlpha(page, MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/widget/Banner/BaseIndicatorBanner.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.widget.Banner; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Color; 7 | import android.graphics.drawable.Drawable; 8 | import android.graphics.drawable.GradientDrawable; 9 | import android.util.AttributeSet; 10 | import android.view.Gravity; 11 | import android.view.View; 12 | import android.view.animation.Interpolator; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | 16 | import com.flyco.banner.R; 17 | import com.flyco.banner.anim.BaseAnimator; 18 | import com.flyco.banner.widget.Banner.base.BaseBanner; 19 | 20 | import java.util.ArrayList; 21 | 22 | public abstract class BaseIndicatorBanner> extends BaseBanner { 23 | public static final int STYLE_DRAWABLE_RESOURCE = 0; 24 | public static final int STYLE_CORNER_RECTANGLE = 1; 25 | 26 | private ArrayList mIndicatorViews = new ArrayList<>(); 27 | private int mIndicatorStyle; 28 | private int mIndicatorWidth; 29 | private int mIndicatorHeight; 30 | private int mIndicatorGap; 31 | private int mIndicatorCornerRadius; 32 | 33 | private Drawable mSelectDrawable; 34 | private Drawable mUnSelectDrawable; 35 | private int mSelectColor; 36 | private int mUnselectColor; 37 | 38 | private Class mSelectAnimClass; 39 | private Class mUnselectAnimClass; 40 | 41 | private LinearLayout mLlIndicators; 42 | 43 | public BaseIndicatorBanner(Context context) { 44 | this(context, null, 0); 45 | } 46 | 47 | public BaseIndicatorBanner(Context context, AttributeSet attrs) { 48 | this(context, attrs, 0); 49 | } 50 | 51 | public BaseIndicatorBanner(Context context, AttributeSet attrs, int defStyle) { 52 | super(context, attrs, defStyle); 53 | 54 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BaseIndicatorBanner); 55 | mIndicatorStyle = ta.getInt(R.styleable.BaseIndicatorBanner_bb_indicatorStyle, STYLE_CORNER_RECTANGLE); 56 | mIndicatorWidth = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorWidth, dp2px(6)); 57 | mIndicatorHeight = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorHeight, dp2px(6)); 58 | mIndicatorGap = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorGap, dp2px(6)); 59 | mIndicatorCornerRadius = ta.getDimensionPixelSize(R.styleable.BaseIndicatorBanner_bb_indicatorCornerRadius, dp2px(3)); 60 | mSelectColor = ta.getColor(R.styleable.BaseIndicatorBanner_bb_indicatorSelectColor, Color.parseColor("#ffffff")); 61 | mUnselectColor = ta.getColor(R.styleable.BaseIndicatorBanner_bb_indicatorUnselectColor, Color.parseColor("#88ffffff")); 62 | 63 | int selectRes = ta.getResourceId(R.styleable.BaseIndicatorBanner_bb_indicatorSelectRes, 0); 64 | int unselectRes = ta.getResourceId(R.styleable.BaseIndicatorBanner_bb_indicatorUnselectRes, 0); 65 | ta.recycle(); 66 | 67 | //create indicator container 68 | mLlIndicators = new LinearLayout(context); 69 | mLlIndicators.setGravity(Gravity.CENTER); 70 | 71 | setIndicatorSelectorRes(unselectRes, selectRes); 72 | } 73 | 74 | @Override 75 | public View onCreateIndicator() { 76 | if (mIndicatorStyle == STYLE_CORNER_RECTANGLE) {//rectangle 77 | this.mUnSelectDrawable = getDrawable(mUnselectColor, mIndicatorCornerRadius); 78 | this.mSelectDrawable = getDrawable(mSelectColor, mIndicatorCornerRadius); 79 | } 80 | 81 | int size = mDatas.size(); 82 | mIndicatorViews.clear(); 83 | 84 | mLlIndicators.removeAllViews(); 85 | for (int i = 0; i < size; i++) { 86 | ImageView iv = new ImageView(mContext); 87 | iv.setImageDrawable(i == mCurrentPositon ? mSelectDrawable : mUnSelectDrawable); 88 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(mIndicatorWidth, 89 | mIndicatorHeight); 90 | lp.leftMargin = i == 0 ? 0 : mIndicatorGap; 91 | mLlIndicators.addView(iv, lp); 92 | mIndicatorViews.add(iv); 93 | } 94 | 95 | setCurrentIndicator(mCurrentPositon); 96 | 97 | return mLlIndicators; 98 | } 99 | 100 | @Override 101 | public void setCurrentIndicator(int position) { 102 | for (int i = 0; i < mIndicatorViews.size(); i++) { 103 | mIndicatorViews.get(i).setImageDrawable(i == position ? mSelectDrawable : mUnSelectDrawable); 104 | } 105 | try { 106 | if (mSelectAnimClass != null) { 107 | if (position == mLastPositon) { 108 | mSelectAnimClass.newInstance().playOn(mIndicatorViews.get(position)); 109 | } else { 110 | mSelectAnimClass.newInstance().playOn(mIndicatorViews.get(position)); 111 | if (mUnselectAnimClass == null) { 112 | mSelectAnimClass.newInstance().interpolator(new ReverseInterpolator()).playOn(mIndicatorViews.get(mLastPositon)); 113 | } else { 114 | mUnselectAnimClass.newInstance().playOn(mIndicatorViews.get(mLastPositon)); 115 | } 116 | } 117 | } 118 | } catch (Exception e) { 119 | e.printStackTrace(); 120 | } 121 | } 122 | 123 | /** 设置显示样式,STYLE_DRAWABLE_RESOURCE or STYLE_CORNER_RECTANGLE */ 124 | public T setIndicatorStyle(int indicatorStyle) { 125 | this.mIndicatorStyle = indicatorStyle; 126 | return (T) this; 127 | } 128 | 129 | /** 设置显示宽度,单位dp,默认6dp */ 130 | public T setIndicatorWidth(float indicatorWidth) { 131 | this.mIndicatorWidth = dp2px(indicatorWidth); 132 | return (T) this; 133 | } 134 | 135 | /** 设置显示器高度,单位dp,默认6dp */ 136 | public T setIndicatorHeight(float indicatorHeight) { 137 | this.mIndicatorHeight = dp2px(indicatorHeight); 138 | return (T) this; 139 | } 140 | 141 | /** 设置两个显示器间距,单位dp,默认6dp */ 142 | public T setIndicatorGap(float indicatorGap) { 143 | this.mIndicatorGap = dp2px(indicatorGap); 144 | return (T) this; 145 | } 146 | 147 | /** 设置显示器选中颜色(for STYLE_CORNER_RECTANGLE),默认"#ffffff" */ 148 | public T setIndicatorSelectColor(int selectColor) { 149 | this.mSelectColor = selectColor; 150 | return (T) this; 151 | } 152 | 153 | /** 设置显示器未选中颜色(for STYLE_CORNER_RECTANGLE),默认"#88ffffff" */ 154 | public T setIndicatorUnselectColor(int unselectColor) { 155 | this.mUnselectColor = unselectColor; 156 | return (T) this; 157 | } 158 | 159 | /** 设置显示器圆角弧度(for STYLE_CORNER_RECTANGLE),单位dp,默认3dp */ 160 | public T setIndicatorCornerRadius(float indicatorCornerRadius) { 161 | this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius); 162 | return (T) this; 163 | } 164 | 165 | /** 设置显示器选中以及未选中资源(for STYLE_DRAWABLE_RESOURCE) */ 166 | public T setIndicatorSelectorRes(int unselectRes, int selectRes) { 167 | try { 168 | if (mIndicatorStyle == STYLE_DRAWABLE_RESOURCE) { 169 | if (selectRes != 0) { 170 | this.mSelectDrawable = getResources().getDrawable(selectRes); 171 | } 172 | if (unselectRes != 0) { 173 | this.mUnSelectDrawable = getResources().getDrawable(unselectRes); 174 | } 175 | } 176 | } catch (Resources.NotFoundException e) { 177 | e.printStackTrace(); 178 | } 179 | return (T) this; 180 | } 181 | 182 | /** 设置显示器选中动画*/ 183 | public T setSelectAnimClass(Class selectAnimClass) { 184 | this.mSelectAnimClass = selectAnimClass; 185 | return (T) this; 186 | } 187 | 188 | /** 设置显示器未选中动画 */ 189 | public T setUnselectAnimClass(Class unselectAnimClass) { 190 | this.mUnselectAnimClass = unselectAnimClass; 191 | return (T) this; 192 | } 193 | 194 | private class ReverseInterpolator implements Interpolator { 195 | @Override 196 | public float getInterpolation(float value) { 197 | return Math.abs(1.0f - value); 198 | } 199 | } 200 | 201 | private GradientDrawable getDrawable(int color, float raduis) { 202 | GradientDrawable drawable = new GradientDrawable(); 203 | drawable.setCornerRadius(raduis); 204 | drawable.setColor(color); 205 | 206 | return drawable; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/widget/Banner/base/BaseBanner.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.widget.Banner.base; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.os.Handler; 7 | import android.os.Message; 8 | import android.support.v4.view.PagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.text.TextUtils; 11 | import android.util.AttributeSet; 12 | import android.util.DisplayMetrics; 13 | import android.util.Log; 14 | import android.util.TypedValue; 15 | import android.view.Gravity; 16 | import android.view.MotionEvent; 17 | import android.view.View; 18 | import android.view.ViewGroup; 19 | import android.view.animation.AccelerateDecelerateInterpolator; 20 | import android.widget.LinearLayout; 21 | import android.widget.RelativeLayout; 22 | import android.widget.TextView; 23 | 24 | import com.flyco.banner.R; 25 | import com.flyco.banner.widget.LoopViewPager.FixedSpeedScroller; 26 | import com.flyco.banner.widget.LoopViewPager.LoopViewPager; 27 | 28 | import java.lang.reflect.Field; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import java.util.concurrent.Executors; 32 | import java.util.concurrent.ScheduledExecutorService; 33 | import java.util.concurrent.TimeUnit; 34 | 35 | public abstract class BaseBanner> extends RelativeLayout { 36 | /** 日志 */ 37 | private static final String TAG = BaseBanner.class.getSimpleName(); 38 | /** 单线程池定时任务 */ 39 | private ScheduledExecutorService mStse; 40 | /** 上下文 */ 41 | protected Context mContext; 42 | /** 设备密度 */ 43 | protected DisplayMetrics mDisplayMetrics; 44 | /** ViewPager */ 45 | protected ViewPager mViewPager; 46 | /** 数据源 */ 47 | protected List mDatas = new ArrayList<>(); 48 | /** 当前position */ 49 | protected int mCurrentPositon; 50 | /** 上一个position */ 51 | protected int mLastPositon; 52 | /** 多久后开始滚动 */ 53 | private long mDelay; 54 | /** 滚动间隔 */ 55 | private long mPeriod; 56 | /** 是否自动滚动 */ 57 | private boolean mIsAutoScrollEnable; 58 | /** 是否正在自动滚动中 */ 59 | private boolean mIsAutoScrolling; 60 | /** 滚动速度 */ 61 | private int mScrollSpeed = 450; 62 | /** 切换动画 */ 63 | private Class mTransformerClass; 64 | 65 | /** 显示器(小点)的最顶层父容器 */ 66 | private RelativeLayout mRlBottomBarParent; 67 | private int mItemWidth; 68 | private int mItemHeight; 69 | 70 | /** 显示器和标题的直接父容器 */ 71 | private LinearLayout mLlBottomBar; 72 | /** 最后一条item是否显示背景条 */ 73 | private boolean mIsBarShowWhenLast; 74 | 75 | /** 显示器的的直接容器 */ 76 | private LinearLayout mLlIndicatorContainer; 77 | 78 | /** 标题 */ 79 | private TextView mTvTitle; 80 | 81 | private Handler mHandler = new Handler() { 82 | public void handleMessage(Message msg) { 83 | scrollToNextItem(mCurrentPositon); 84 | } 85 | }; 86 | 87 | public BaseBanner(Context context) { 88 | this(context, null, 0); 89 | } 90 | 91 | public BaseBanner(Context context, AttributeSet attrs) { 92 | this(context, attrs, 0); 93 | } 94 | 95 | public BaseBanner(Context context, AttributeSet attrs, int defStyle) { 96 | super(context, attrs, defStyle); 97 | this.mContext = context; 98 | mDisplayMetrics = context.getResources().getDisplayMetrics(); 99 | 100 | TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BaseBanner); 101 | float scale = ta.getFloat(R.styleable.BaseBanner_bb_scale, -1); 102 | 103 | boolean isLoopEnable = ta.getBoolean(R.styleable.BaseBanner_bb_isLoopEnable, true); 104 | mDelay = ta.getInt(R.styleable.BaseBanner_bb_delay, 5); 105 | mPeriod = ta.getInt(R.styleable.BaseBanner_bb_period, 5); 106 | mIsAutoScrollEnable = ta.getBoolean(R.styleable.BaseBanner_bb_isAutoScrollEnable, true); 107 | 108 | int barColor = ta.getColor(R.styleable.BaseBanner_bb_barColor, Color.TRANSPARENT); 109 | mIsBarShowWhenLast = ta.getBoolean(R.styleable.BaseBanner_bb_isBarShowWhenLast, true); 110 | int indicatorGravity = ta.getInt(R.styleable.BaseBanner_bb_indicatorGravity, Gravity.CENTER); 111 | float barPaddingLeft = ta.getDimension(R.styleable.BaseBanner_bb_barPaddingLeft, dp2px(10)); 112 | float barPaddingTop = ta.getDimension(R.styleable.BaseBanner_bb_barPaddingTop, dp2px(indicatorGravity == Gravity.CENTER ? 6 : 2)); 113 | float barPaddingRight = ta.getDimension(R.styleable.BaseBanner_bb_barPaddingRight, dp2px(10)); 114 | float barPaddingBottom = ta.getDimension(R.styleable.BaseBanner_bb_barPaddingBottom, dp2px(indicatorGravity == Gravity.CENTER ? 6 : 2)); 115 | int textColor = ta.getColor(R.styleable.BaseBanner_bb_textColor, Color.parseColor("#ffffff")); 116 | float textSize = ta.getDimension(R.styleable.BaseBanner_bb_textSize, sp2px(12.5f)); 117 | boolean isTitleShow = ta.getBoolean(R.styleable.BaseBanner_bb_isTitleShow, true); 118 | boolean isIndicatorShow = ta.getBoolean(R.styleable.BaseBanner_bb_isIndicatorShow, true); 119 | ta.recycle(); 120 | 121 | //get layout_height 122 | String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "layout_height"); 123 | 124 | //create ViewPager 125 | mViewPager = isLoopEnable ? new LoopViewPager(context) : new ViewPager(context); 126 | mItemWidth = mDisplayMetrics.widthPixels; 127 | if (scale < 0) {//scale not set in xml 128 | if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) { 129 | mItemHeight = LayoutParams.MATCH_PARENT; 130 | } else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) { 131 | mItemHeight = LayoutParams.WRAP_CONTENT; 132 | } else { 133 | int[] systemAttrs = {android.R.attr.layout_height}; 134 | TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs); 135 | int h = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT); 136 | a.recycle(); 137 | mItemHeight = h; 138 | } 139 | } else { 140 | if (scale > 1) { 141 | scale = 1; 142 | } 143 | mItemHeight = (int) (mItemWidth * scale); 144 | } 145 | 146 | LayoutParams lp = new LayoutParams(mItemWidth, mItemHeight); 147 | addView(mViewPager, lp); 148 | 149 | //top parent of indicators 150 | mRlBottomBarParent = new RelativeLayout(context); 151 | addView(mRlBottomBarParent, lp); 152 | 153 | //container of indicators and title 154 | mLlBottomBar = new LinearLayout(context); 155 | LayoutParams lp2 = new LayoutParams(mItemWidth, LayoutParams.WRAP_CONTENT); 156 | lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); 157 | mRlBottomBarParent.addView(mLlBottomBar, lp2); 158 | 159 | mLlBottomBar.setBackgroundColor(barColor); 160 | mLlBottomBar.setPadding((int) barPaddingLeft, (int) barPaddingTop, (int) barPaddingRight, (int) barPaddingBottom); 161 | mLlBottomBar.setClipChildren(false); 162 | mLlBottomBar.setClipToPadding(false); 163 | 164 | //container of indicators 165 | mLlIndicatorContainer = new LinearLayout(context); 166 | mLlIndicatorContainer.setGravity(Gravity.CENTER); 167 | mLlIndicatorContainer.setVisibility(isIndicatorShow ? VISIBLE : INVISIBLE); 168 | mLlIndicatorContainer.setClipChildren(false); 169 | mLlIndicatorContainer.setClipToPadding(false); 170 | 171 | // title 172 | mTvTitle = new TextView(context); 173 | mTvTitle.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0F)); 174 | mTvTitle.setSingleLine(true); 175 | mTvTitle.setTextColor(textColor); 176 | mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); 177 | mTvTitle.setVisibility(isTitleShow ? VISIBLE : INVISIBLE); 178 | 179 | if (indicatorGravity == Gravity.CENTER) { 180 | mLlBottomBar.setGravity(Gravity.CENTER); 181 | mLlBottomBar.addView(mLlIndicatorContainer); 182 | } else { 183 | if (indicatorGravity == Gravity.RIGHT) { 184 | mLlBottomBar.setGravity(Gravity.CENTER_VERTICAL); 185 | mLlBottomBar.addView(mTvTitle); 186 | mLlBottomBar.addView(mLlIndicatorContainer); 187 | 188 | mTvTitle.setPadding(0, 0, dp2px(7), 0); 189 | mTvTitle.setEllipsize(TextUtils.TruncateAt.END); 190 | mTvTitle.setGravity(Gravity.LEFT); 191 | } else if (indicatorGravity == Gravity.LEFT) { 192 | mLlBottomBar.setGravity(Gravity.CENTER_VERTICAL); 193 | mLlBottomBar.addView(mLlIndicatorContainer); 194 | mLlBottomBar.addView(mTvTitle); 195 | 196 | mTvTitle.setPadding(dp2px(7), 0, 0, 0); 197 | mTvTitle.setEllipsize(TextUtils.TruncateAt.END); 198 | mTvTitle.setGravity(Gravity.RIGHT); 199 | } 200 | } 201 | } 202 | 203 | /** 创建ViewPager的Item布局 */ 204 | public abstract View onCreateItemView(int position); 205 | 206 | /** 创建显示器 */ 207 | public abstract View onCreateIndicator(); 208 | 209 | /** 设置当前显示器的状态,选中或者未选中 */ 210 | public abstract void setCurrentIndicator(int position); 211 | 212 | /** 覆写这个方法设置标题 */ 213 | public void onTitleSlect(TextView tv, int position) { 214 | } 215 | 216 | /** 设置数据源 */ 217 | public T setSource(List list) { 218 | this.mDatas = list; 219 | return (T) this; 220 | } 221 | 222 | /** 滚动延时,默认5秒 */ 223 | public T setDelay(long delay) { 224 | this.mDelay = delay; 225 | return (T) this; 226 | } 227 | 228 | /** 滚动间隔,默认5秒 */ 229 | public T setPeriod(long period) { 230 | this.mPeriod = period; 231 | return (T) this; 232 | } 233 | 234 | /** 设置是否支持自动滚动,默认true.仅对LoopViewPager有效 */ 235 | public T setAutoScrollEnable(boolean isAutoScrollEnable) { 236 | this.mIsAutoScrollEnable = isAutoScrollEnable; 237 | return (T) this; 238 | } 239 | 240 | /** 设置页面切换动画 */ 241 | public T setTransformerClass(Class transformerClass) { 242 | this.mTransformerClass = transformerClass; 243 | return (T) this; 244 | } 245 | 246 | /** 设置底部背景条颜色,默认透明 */ 247 | public T setBarColor(int barColor) { 248 | mLlBottomBar.setBackgroundColor(barColor); 249 | return (T) this; 250 | } 251 | 252 | /** 设置最后一条item是否显示背景条,默认true */ 253 | public T setBarShowWhenLast(boolean isBarShowWhenLast) { 254 | this.mIsBarShowWhenLast = isBarShowWhenLast; 255 | return (T) this; 256 | } 257 | 258 | /** 设置底部背景条padding,单位dp */ 259 | public T barPadding(float left, float top, float right, float bottom) { 260 | mLlBottomBar.setPadding(dp2px(left), dp2px(top), dp2px(right), dp2px(bottom)); 261 | return (T) this; 262 | } 263 | 264 | /** 设置标题文字颜色,默认"#ffffff" */ 265 | public T setTextColor(int textColor) { 266 | mTvTitle.setTextColor(textColor); 267 | return (T) this; 268 | } 269 | 270 | /** 设置标题文字大小,单位sp,默认14sp */ 271 | public T setTextSize(float textSize) { 272 | mTvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize); 273 | return (T) this; 274 | } 275 | 276 | /** 设置是否显示标题,默认true */ 277 | public T setTitleShow(boolean isTitleShow) { 278 | mTvTitle.setVisibility(isTitleShow ? VISIBLE : INVISIBLE); 279 | return (T) this; 280 | } 281 | 282 | /** 设置是否显示显示器,默认true */ 283 | public T setIndicatorShow(boolean isIndicatorShow) { 284 | mLlIndicatorContainer.setVisibility(isIndicatorShow ? VISIBLE : INVISIBLE); 285 | return (T) this; 286 | } 287 | 288 | /** 滚动到下一个item */ 289 | private void scrollToNextItem(int position) { 290 | position++; 291 | mViewPager.setCurrentItem(position); 292 | } 293 | 294 | /** 设置viewpager */ 295 | private void setViewPager() { 296 | InnerBannerAdapter mInnerAdapter = new InnerBannerAdapter(); 297 | mViewPager.setAdapter(mInnerAdapter); 298 | mViewPager.setOffscreenPageLimit(mDatas.size()); 299 | 300 | try { 301 | if (mTransformerClass != null) { 302 | mViewPager.setPageTransformer(true, mTransformerClass.newInstance()); 303 | if (isLoopViewPager()) { 304 | mScrollSpeed = 550; 305 | setScrollSpeed(); 306 | } 307 | } else { 308 | if (isLoopViewPager()) { 309 | mScrollSpeed = 450; 310 | setScrollSpeed(); 311 | } 312 | } 313 | } catch (Exception e) { 314 | e.printStackTrace(); 315 | } 316 | 317 | if (mInternalPageListener != null) { 318 | mViewPager.removeOnPageChangeListener(mInternalPageListener); 319 | } 320 | mViewPager.addOnPageChangeListener(mInternalPageListener); 321 | } 322 | 323 | private ViewPager.OnPageChangeListener mInternalPageListener = new ViewPager.OnPageChangeListener() { 324 | @Override 325 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 326 | if (mOnPageChangeListener != null) { 327 | mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 328 | } 329 | } 330 | 331 | @Override 332 | public void onPageSelected(int position) { 333 | mCurrentPositon = position % mDatas.size(); 334 | 335 | setCurrentIndicator(mCurrentPositon); 336 | onTitleSlect(mTvTitle, mCurrentPositon); 337 | mLlBottomBar.setVisibility(mCurrentPositon == mDatas.size() - 1 && !mIsBarShowWhenLast ? GONE : VISIBLE); 338 | 339 | mLastPositon = mCurrentPositon; 340 | if (mOnPageChangeListener != null) { 341 | mOnPageChangeListener.onPageSelected(position); 342 | } 343 | } 344 | 345 | @Override 346 | public void onPageScrollStateChanged(int state) { 347 | if (mOnPageChangeListener != null) { 348 | mOnPageChangeListener.onPageScrollStateChanged(state); 349 | } 350 | } 351 | }; 352 | 353 | /** 开始滚动 */ 354 | public void startScroll() { 355 | if (mDatas == null) { 356 | throw new IllegalStateException("Data source is empty,you must setSource() before startScroll()"); 357 | } 358 | 359 | if (mDatas.size() > 0 && mCurrentPositon > mDatas.size() - 1) { 360 | mCurrentPositon = 0; 361 | } 362 | 363 | onTitleSlect(mTvTitle, mCurrentPositon); 364 | setViewPager(); 365 | //create indicator 366 | View indicatorViews = onCreateIndicator(); 367 | if (indicatorViews != null) { 368 | mLlIndicatorContainer.removeAllViews(); 369 | mLlIndicatorContainer.addView(indicatorViews); 370 | } 371 | 372 | goOnScroll(); 373 | } 374 | 375 | /** 继续滚动(for LoopViewPager) */ 376 | public void goOnScroll() { 377 | if (!isValid()) { 378 | return; 379 | } 380 | 381 | if (mIsAutoScrolling) { 382 | return; 383 | } 384 | if (isLoopViewPager() && mIsAutoScrollEnable) { 385 | pauseScroll(); 386 | mStse = Executors.newSingleThreadScheduledExecutor(); 387 | mStse.scheduleAtFixedRate(new Runnable() { 388 | @Override 389 | public void run() { 390 | mHandler.obtainMessage().sendToTarget(); 391 | } 392 | }, mDelay, mPeriod, TimeUnit.SECONDS); 393 | mIsAutoScrolling = true; 394 | Log.d(TAG, this.getClass().getSimpleName() + "--->goOnScroll()"); 395 | } else { 396 | mIsAutoScrolling = false; 397 | } 398 | } 399 | 400 | /** 停止滚动(for LoopViewPager) */ 401 | public void pauseScroll() { 402 | if (mStse != null) { 403 | mStse.shutdown(); 404 | mStse = null; 405 | } 406 | Log.d(TAG, this.getClass().getSimpleName() + "--->pauseScroll()"); 407 | 408 | mIsAutoScrolling = false; 409 | } 410 | 411 | /** 获取ViewPager对象 */ 412 | public ViewPager getViewPager() { 413 | return mViewPager; 414 | } 415 | 416 | @Override 417 | public boolean dispatchTouchEvent(MotionEvent ev) { 418 | int action = ev.getAction(); 419 | switch (action) { 420 | case MotionEvent.ACTION_DOWN: 421 | pauseScroll(); 422 | break; 423 | case MotionEvent.ACTION_UP: 424 | goOnScroll(); 425 | break; 426 | case MotionEvent.ACTION_CANCEL: 427 | goOnScroll(); 428 | break; 429 | 430 | } 431 | return super.dispatchTouchEvent(ev); 432 | } 433 | 434 | // @Override 435 | // protected void onWindowVisibilityChanged(int visibility) { 436 | // super.onWindowVisibilityChanged(visibility); 437 | // if (mIsSmart) { 438 | // if (visibility != VISIBLE) { 439 | // pauseScroll(); 440 | // } else { 441 | // goOnScroll(); 442 | // } 443 | // } 444 | // } 445 | 446 | private class InnerBannerAdapter extends PagerAdapter { 447 | @Override 448 | public int getCount() { 449 | return mDatas.size(); 450 | } 451 | 452 | @Override 453 | public Object instantiateItem(ViewGroup container, final int position) { 454 | View inflate = onCreateItemView(position); 455 | inflate.setOnClickListener(new OnClickListener() { 456 | @Override 457 | public void onClick(View v) { 458 | if (mOnItemClickL != null) { 459 | mOnItemClickL.onItemClick(position); 460 | } 461 | } 462 | }); 463 | container.addView(inflate); 464 | 465 | return inflate; 466 | } 467 | 468 | @Override 469 | public void destroyItem(ViewGroup container, int position, Object object) { 470 | container.removeView((View) object); 471 | } 472 | 473 | @Override 474 | public boolean isViewFromObject(View view, Object object) { 475 | return view == object; 476 | } 477 | 478 | public int getItemPosition(Object object) { 479 | return POSITION_NONE; 480 | } 481 | } 482 | 483 | /** 设置滚动速率 */ 484 | private void setScrollSpeed() { 485 | try { 486 | Field mScroller = ViewPager.class.getDeclaredField("mScroller"); 487 | mScroller.setAccessible(true); 488 | AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator(); 489 | FixedSpeedScroller myScroller = new FixedSpeedScroller(mContext, interpolator, mScrollSpeed); 490 | mScroller.set(mViewPager, myScroller); 491 | } catch (Exception e) { 492 | e.printStackTrace(); 493 | } 494 | } 495 | 496 | protected int dp2px(float dp) { 497 | float scale = mContext.getResources().getDisplayMetrics().density; 498 | return (int) (dp * scale + 0.5F); 499 | } 500 | 501 | private float sp2px(float sp) { 502 | final float scale = mContext.getResources().getDisplayMetrics().scaledDensity; 503 | return sp * scale; 504 | } 505 | 506 | protected boolean isLoopViewPager() { 507 | return mViewPager instanceof LoopViewPager; 508 | } 509 | 510 | protected boolean isValid() { 511 | if (mViewPager == null) { 512 | Log.e(TAG, "ViewPager is not exist!"); 513 | return false; 514 | } 515 | 516 | if (mDatas == null || mDatas.size() == 0) { 517 | Log.e(TAG, "DataList must be not empty!"); 518 | return false; 519 | } 520 | 521 | return true; 522 | } 523 | 524 | //listener 525 | private ViewPager.OnPageChangeListener mOnPageChangeListener; 526 | 527 | public void addOnPageChangeListener(ViewPager.OnPageChangeListener listener) { 528 | mOnPageChangeListener = listener; 529 | } 530 | 531 | private OnItemClickL mOnItemClickL; 532 | 533 | public void setOnItemClickL(OnItemClickL onItemClickL) { 534 | this.mOnItemClickL = onItemClickL; 535 | } 536 | 537 | public interface OnItemClickL { 538 | void onItemClick(int position); 539 | } 540 | } 541 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/widget/LoopViewPager/FixedSpeedScroller.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.widget.LoopViewPager; 2 | 3 | import android.content.Context; 4 | import android.view.animation.Interpolator; 5 | import android.widget.Scroller; 6 | 7 | public class FixedSpeedScroller extends Scroller { 8 | private int mScrollSpeed = 450; 9 | 10 | public FixedSpeedScroller(Context context) { 11 | super(context); 12 | } 13 | 14 | public FixedSpeedScroller(Context context, Interpolator interpolator, int scrollSpeed) { 15 | super(context, interpolator); 16 | this.mScrollSpeed = scrollSpeed; 17 | } 18 | 19 | @Override 20 | public void startScroll(int startX, int startY, int dx, int dy, int duration) { 21 | super.startScroll(startX, startY, dx, dy, this.mScrollSpeed); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/widget/LoopViewPager/LoopPagerAdapterWrapper.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.widget.LoopViewPager; 2 | 3 | import android.os.Parcelable; 4 | import android.support.v4.app.FragmentPagerAdapter; 5 | import android.support.v4.app.FragmentStatePagerAdapter; 6 | import android.support.v4.view.PagerAdapter; 7 | import android.util.SparseArray; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | /** 12 | * A PagerAdapter wrapper responsible for providing a proper page to 13 | * LoopViewPager 14 | * 15 | * This class shouldn't be used directly 16 | */ 17 | public class LoopPagerAdapterWrapper extends PagerAdapter { 18 | 19 | private PagerAdapter mAdapter; 20 | 21 | private SparseArray mToDestroy = new SparseArray(); 22 | 23 | private boolean mBoundaryCaching; 24 | 25 | void setBoundaryCaching(boolean flag) { 26 | mBoundaryCaching = flag; 27 | } 28 | 29 | LoopPagerAdapterWrapper(PagerAdapter adapter) { 30 | this.mAdapter = adapter; 31 | } 32 | 33 | @Override 34 | public void notifyDataSetChanged() { 35 | mToDestroy = new SparseArray(); 36 | super.notifyDataSetChanged(); 37 | } 38 | 39 | int toRealPosition(int position) { 40 | int realCount = getRealCount(); 41 | if (realCount == 0) 42 | return 0; 43 | int realPosition = (position - 1) % realCount; 44 | if (realPosition < 0) 45 | realPosition += realCount; 46 | 47 | return realPosition; 48 | } 49 | 50 | public int toInnerPosition(int realPosition) { 51 | int position = (realPosition + 1); 52 | return position; 53 | } 54 | 55 | private int getRealFirstPosition() { 56 | return 1; 57 | } 58 | 59 | private int getRealLastPosition() { 60 | return getRealFirstPosition() + getRealCount() - 1; 61 | } 62 | 63 | @Override 64 | public int getCount() { 65 | return mAdapter.getCount() + 2; 66 | } 67 | 68 | public int getRealCount() { 69 | return mAdapter.getCount(); 70 | } 71 | 72 | public PagerAdapter getRealAdapter() { 73 | return mAdapter; 74 | } 75 | 76 | @Override 77 | public Object instantiateItem(ViewGroup container, int position) { 78 | int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter) ? position 79 | : toRealPosition(position); 80 | 81 | if (mBoundaryCaching) { 82 | ToDestroy toDestroy = mToDestroy.get(position); 83 | if (toDestroy != null) { 84 | mToDestroy.remove(position); 85 | return toDestroy.object; 86 | } 87 | } 88 | return mAdapter.instantiateItem(container, realPosition); 89 | } 90 | 91 | @Override 92 | public void destroyItem(ViewGroup container, int position, Object object) { 93 | int realFirst = getRealFirstPosition(); 94 | int realLast = getRealLastPosition(); 95 | int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter) ? position 96 | : toRealPosition(position); 97 | 98 | if (mBoundaryCaching && (position == realFirst || position == realLast)) { 99 | mToDestroy.put(position, new ToDestroy(container, realPosition, object)); 100 | } else { 101 | mAdapter.destroyItem(container, realPosition, object); 102 | } 103 | } 104 | 105 | /* 106 | * Delegate rest of methods directly to the inner adapter. 107 | */ 108 | 109 | @Override 110 | public void finishUpdate(ViewGroup container) { 111 | mAdapter.finishUpdate(container); 112 | } 113 | 114 | @Override 115 | public boolean isViewFromObject(View view, Object object) { 116 | return mAdapter.isViewFromObject(view, object); 117 | } 118 | 119 | @Override 120 | public void restoreState(Parcelable bundle, ClassLoader classLoader) { 121 | mAdapter.restoreState(bundle, classLoader); 122 | } 123 | 124 | @Override 125 | public Parcelable saveState() { 126 | return mAdapter.saveState(); 127 | } 128 | 129 | @Override 130 | public void startUpdate(ViewGroup container) { 131 | mAdapter.startUpdate(container); 132 | } 133 | 134 | @Override 135 | public void setPrimaryItem(ViewGroup container, int position, Object object) { 136 | mAdapter.setPrimaryItem(container, position, object); 137 | } 138 | 139 | /* 140 | * End delegation 141 | */ 142 | 143 | /** 144 | * Container class for caching the boundary views 145 | */ 146 | static class ToDestroy { 147 | ViewGroup container; 148 | int position; 149 | Object object; 150 | 151 | public ToDestroy(ViewGroup container, int position, Object object) { 152 | this.container = container; 153 | this.position = position; 154 | this.object = object; 155 | } 156 | } 157 | 158 | } -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/java/com/flyco/banner/widget/LoopViewPager/LoopViewPager.java: -------------------------------------------------------------------------------- 1 | package com.flyco.banner.widget.LoopViewPager; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.PagerAdapter; 5 | import android.support.v4.view.ViewPager; 6 | import android.util.AttributeSet; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class LoopViewPager extends ViewPager { 12 | 13 | private static final boolean DEFAULT_BOUNDARY_CASHING = false; 14 | 15 | // OnPageChangeListener mOuterPageChangeListener; 16 | private LoopPagerAdapterWrapper mAdapter; 17 | private boolean mBoundaryCaching = DEFAULT_BOUNDARY_CASHING; 18 | private List mOnPageChangeListeners; 19 | 20 | /** 21 | * helper function which may be used when implementing FragmentPagerAdapter 22 | * 23 | * @param position 24 | * @param count 25 | * @return (position-1)%count 26 | */ 27 | public static int toRealPosition(int position, int count) { 28 | position = position - 1; 29 | if (position < 0) { 30 | position += count; 31 | } else { 32 | position = position % count; 33 | } 34 | return position; 35 | } 36 | 37 | /** 38 | * If set to true, the boundary views (i.e. first and last) will never be 39 | * destroyed This may help to prevent "blinking" of some views 40 | * 41 | * @param flag 42 | */ 43 | public void setBoundaryCaching(boolean flag) { 44 | mBoundaryCaching = flag; 45 | if (mAdapter != null) { 46 | mAdapter.setBoundaryCaching(flag); 47 | } 48 | } 49 | 50 | @Override 51 | public void setAdapter(PagerAdapter adapter) { 52 | mAdapter = new LoopPagerAdapterWrapper(adapter); 53 | mAdapter.setBoundaryCaching(mBoundaryCaching); 54 | super.setAdapter(mAdapter); 55 | setCurrentItem(0, false); 56 | } 57 | 58 | @Override 59 | public PagerAdapter getAdapter() { 60 | return mAdapter != null ? mAdapter.getRealAdapter() : mAdapter; 61 | } 62 | 63 | @Override 64 | public int getCurrentItem() { 65 | return mAdapter != null ? mAdapter.toRealPosition(super.getCurrentItem()) : 0; 66 | } 67 | 68 | public void setCurrentItem(int item, boolean smoothScroll) { 69 | int realItem = mAdapter.toInnerPosition(item); 70 | super.setCurrentItem(realItem, smoothScroll); 71 | } 72 | 73 | @Override 74 | public void setCurrentItem(int item) { 75 | if (getCurrentItem() != item) { 76 | setCurrentItem(item, true); 77 | } 78 | } 79 | 80 | @Override 81 | public void setOnPageChangeListener(OnPageChangeListener listener) { 82 | addOnPageChangeListener(listener); 83 | } 84 | 85 | @Override 86 | public void addOnPageChangeListener(OnPageChangeListener listener) { 87 | if (mOnPageChangeListeners == null) { 88 | mOnPageChangeListeners = new ArrayList<>(); 89 | } 90 | mOnPageChangeListeners.add(listener); 91 | } 92 | 93 | @Override 94 | public void removeOnPageChangeListener(OnPageChangeListener listener) { 95 | if (mOnPageChangeListeners != null) { 96 | mOnPageChangeListeners.remove(listener); 97 | } 98 | } 99 | 100 | @Override 101 | public void clearOnPageChangeListeners() { 102 | if (mOnPageChangeListeners != null) { 103 | mOnPageChangeListeners.clear(); 104 | } 105 | } 106 | 107 | public LoopViewPager(Context context) { 108 | super(context); 109 | init(context); 110 | } 111 | 112 | public LoopViewPager(Context context, AttributeSet attrs) { 113 | super(context, attrs); 114 | init(context); 115 | } 116 | 117 | private void init(Context context) { 118 | if (onPageChangeListener != null) { 119 | super.removeOnPageChangeListener(onPageChangeListener); 120 | } 121 | super.addOnPageChangeListener(onPageChangeListener); 122 | } 123 | 124 | private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() { 125 | private float mPreviousOffset = -1; 126 | private float mPreviousPosition = -1; 127 | 128 | @Override 129 | public void onPageSelected(int position) { 130 | 131 | int realPosition = mAdapter.toRealPosition(position); 132 | if (mPreviousPosition != realPosition) { 133 | mPreviousPosition = realPosition; 134 | // if (mOuterPageChangeListener != null) { 135 | // mOuterPageChangeListener.onPageSelected(realPosition); 136 | // } 137 | 138 | if (mOnPageChangeListeners != null) { 139 | for (int i = 0; i < mOnPageChangeListeners.size(); i++) { 140 | OnPageChangeListener listener = mOnPageChangeListeners.get(i); 141 | if (listener != null) { 142 | listener.onPageSelected(realPosition); 143 | } 144 | } 145 | } 146 | } 147 | } 148 | 149 | @Override 150 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 151 | int realPosition = position; 152 | if (mAdapter != null) { 153 | realPosition = mAdapter.toRealPosition(position); 154 | 155 | if (positionOffset == 0 && mPreviousOffset == 0 && (position == 0 || position == mAdapter.getCount() - 1)) { 156 | setCurrentItem(realPosition, false); 157 | } 158 | } 159 | 160 | mPreviousOffset = positionOffset; 161 | 162 | if (mOnPageChangeListeners != null) { 163 | for (int i = 0; i < mOnPageChangeListeners.size(); i++) { 164 | OnPageChangeListener listener = mOnPageChangeListeners.get(i); 165 | if (listener != null) { 166 | if (realPosition != mAdapter.getRealCount() - 1) { 167 | listener.onPageScrolled(realPosition, positionOffset, positionOffsetPixels); 168 | } else { 169 | if (positionOffset > .5) { 170 | listener.onPageScrolled(0, 0, 0); 171 | } else { 172 | listener.onPageScrolled(realPosition, 0, 0); 173 | } 174 | } 175 | } 176 | } 177 | } 178 | /* 179 | if (mOuterPageChangeListener != null) { 180 | if (realPosition != mAdapter.getRealCount() - 1) { 181 | mOuterPageChangeListener.onPageScrolled(realPosition, positionOffset, positionOffsetPixels); 182 | } else { 183 | if (positionOffset > .5) { 184 | mOuterPageChangeListener.onPageScrolled(0, 0, 0); 185 | } else { 186 | mOuterPageChangeListener.onPageScrolled(realPosition, 0, 0); 187 | } 188 | } 189 | }*/ 190 | } 191 | 192 | @Override 193 | public void onPageScrollStateChanged(int state) { 194 | if (mAdapter != null) { 195 | int position = LoopViewPager.super.getCurrentItem(); 196 | int realPosition = mAdapter.toRealPosition(position); 197 | if (state == ViewPager.SCROLL_STATE_IDLE && (position == 0 || position == mAdapter.getCount() - 1)) { 198 | setCurrentItem(realPosition, false); 199 | } 200 | } 201 | // if (mOuterPageChangeListener != null) { 202 | // mOuterPageChangeListener.onPageScrollStateChanged(state); 203 | // } 204 | 205 | if (mOnPageChangeListeners != null) { 206 | for (int i = 0; i < mOnPageChangeListeners.size(); i++) { 207 | OnPageChangeListener listener = mOnPageChangeListeners.get(i); 208 | if (listener != null) { 209 | listener.onPageScrollStateChanged(state); 210 | } 211 | } 212 | } 213 | } 214 | }; 215 | 216 | } 217 | -------------------------------------------------------------------------------- /FlycoBanner_Lib/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 H07000223 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #FlycoBanner-Master 2 | #### [中文版](https://github.com/H07000223/FlycoBanner_Master/blob/master/README_CN.md) 3 | An android view looper library. Support for Android 2.2 and up. 4 | 5 | ##Demo 6 | ![](https://github.com/H07000223/FlycoBanner_Master/blob/master/preview_FlycoBanner.gif) 7 | 8 | ####[Here is a DemoApk download](http://fir.im/7qzm) 9 | 10 | ##Gradle 11 | 12 | ```groovy 13 | dependencies{ 14 | compile 'com.android.support:support-v4:22.2.1' 15 | compile 'com.nineoldandroids:library:2.4.0' 16 | compile 'com.flyco.banner:FlycoBanner_Lib:2.0.2@aar' 17 | } 18 | ``` 19 | 20 | ##Usage 21 | 22 | ###Extends BaseIndicatorBanner and Set Data Type 23 | 24 | ```Java 25 | public class SimpleImageBanner extends BaseIndicatorBanner { 26 | private ColorDrawable colorDrawable; 27 | 28 | public SimpleImageBanner(Context context) { 29 | this(context, null, 0); 30 | } 31 | 32 | public SimpleImageBanner(Context context, AttributeSet attrs) { 33 | this(context, attrs, 0); 34 | } 35 | 36 | public SimpleImageBanner(Context context, AttributeSet attrs, int defStyle) { 37 | super(context, attrs, defStyle); 38 | colorDrawable = new ColorDrawable(Color.parseColor("#555555")); 39 | } 40 | 41 | @Override 42 | public void onTitleSlect(TextView tv, int position) { 43 | final BannerItem item = list.get(position); 44 | tv.setText(item.title); 45 | } 46 | 47 | @Override 48 | public View onCreateItemView(int position) { 49 | View inflate = View.inflate(context, R.layout.adapter_simple_image, null); 50 | ImageView iv = ViewFindUtils.find(inflate, R.id.iv); 51 | 52 | final BannerItem item = list.get(position); 53 | int itemWidth = dm.widthPixels; 54 | int itemHeight = (int) (itemWidth * 360 * 1.0f / 640); 55 | iv.setScaleType(ImageView.ScaleType.CENTER_CROP); 56 | iv.setLayoutParams(new LinearLayout.LayoutParams(itemWidth, itemHeight)); 57 | 58 | String imgUrl = item.imgUrl; 59 | 60 | if (!TextUtils.isEmpty(imgUrl)) { 61 | Glide.with(context) 62 | .load(imgUrl) 63 | .override(itemWidth, itemHeight) 64 | .centerCrop() 65 | .placeholder(colorDrawable) 66 | .into(iv); 67 | } else { 68 | iv.setImageDrawable(colorDrawable); 69 | } 70 | 71 | return inflate; 72 | } 73 | } 74 | ``` 75 | 76 | ###The Most Complex 77 | in layout xml 78 | 79 | ``` xml 80 | 107 | ``` 108 | 109 | int Java Code 110 | 111 | ``` Java 112 | sib 113 | .setSelectAnimClass(ZoomInEnter.class) //set indicator select anim 114 | .setSource(DataProvider.getList()) //data source list 115 | .setTransformerClass(ZoomOutSlideTransformer.class) //set page transformer 116 | .startScroll(); 117 | ``` 118 | 119 | ###The Simplest 120 | in layout xml 121 | 122 | ``` xml 123 | 128 | ``` 129 | 130 | int Java Code 131 | 132 | ``` Java 133 | sib 134 | .setSource(DataProvider.getList()) 135 | .startScroll(); 136 | ``` 137 | 138 | ###Attributes 139 | 140 | |name|format|description| 141 | |:---:|:---:|:---:| 142 | | bb_scale | float |scale of Banner height and width,height/screenWidth 143 | | bb_isLoopEnable | boolean |is LoopViewPager or not,default true 144 | | bb_delay | integer |delay before start scroll,unit second,default 5 seconds 145 | | bb_period | integer |scroll period,unit second,default 5 seconds 146 | | bb_isAutoScrollEnable | boolean |is auto scroll enable,default true 147 | | bb_barColor | color |set bootom bar color,default transparent 148 | | bb_isBarShowWhenLast | boolean |set bottom bar show or not when the position is the last 149 | | bb_barPaddingLeft | dimension |set bottom bar padding,unit dp 150 | | bb_barPaddingTop | dimension |set bottom bar padding,unit dp 151 | | bb_barPaddingRight | dimension |set bottom bar padding,unit dp 152 | | bb_barPaddingBottom | dimension |set bottom bar padding,unit dp 153 | | bb_textColor | color |set title text color,default "#ffffff" 154 | | bb_textSize | dimension |set title text size,unit sp,default 14sp 155 | | bb_isTitleShow | boolean |set title show or not,default true 156 | | bb_isIndicatorShow | boolean |set indicator show or not,default true 157 | | bb_indicatorGravity |enum| Gravity.CENTER or RIGHT or LEFT.if gravity equals CENTER,title will not be supported,default CENTER 158 | | bb_indicatorStyle |enum|indicator style, `STYLE_DRAWABLE_RESOURCE` or `STYLE_CORNER_RECTANGLE` 159 | | bb_indicatorWidth | dimension |indicator width, unit dp, default 6dp 160 | | bb_indicatorHeight | dimension |indicator height,unit dp,default 6dp 161 | | bb_indicatorGap | dimension |gap between two indicators,unit dp,default 6dp 162 | | bb_indicatorSelectColor | color |indicator select color for `STYLE_CORNER_RECTANGLE`, default `"#ffffff"` 163 | | bb_indicatorUnselectColor | color |indicator unselect color for `STYLE_CORNER_RECTANGLE`, default `"#88ffffff" ` 164 | | bb_indicatorCornerRadius | dimension |indicator corner raduis for `STYLE_CORNER_RECTANGLE`,unit dp, default 3dp 165 | | bb_indicatorSelectRes | reference |indicator select drawable resource for `STYLE_DRAWABLE_RESOURCE` 166 | | bb_indicatorUnselectRes | reference |indicator unselect drawable resource for `STYLE_DRAWABLE_RESOURCE` 167 | 168 | 169 | 170 | ##Thanks 171 | * [LoopingViewPager](https://github.com/imbryk/LoopingViewPager) 172 | * [NineOldAndroids](https://github.com/JakeWharton/NineOldAndroids) 173 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | #FlycoBanner-Master 2 | 3 | 一个Android View轮播库,支持2.2+. 4 | 5 | ##Demo 6 | ![](https://github.com/H07000223/FlycoBanner_Master/blob/master/preview_FlycoBanner.gif) 7 | 8 | ####[Here is a DemoApk download](http://fir.im/7qzm) 9 | 10 | ##Gradle 11 | 12 | ```groovy 13 | dependencies{ 14 | compile 'com.android.support:support-v4:22.2.1' 15 | compile 'com.nineoldandroids:library:2.4.0' 16 | compile 'com.flyco.banner:FlycoBanner_Lib:2.0.2@aar' 17 | } 18 | ``` 19 | 20 | ##Usage 21 | 22 | ###Extends BaseIndicatorBanner and Set Data Type 23 | 24 | ```Java 25 | public class SimpleImageBanner extends BaseIndicatorBanner { 26 | private ColorDrawable colorDrawable; 27 | 28 | public SimpleImageBanner(Context context) { 29 | this(context, null, 0); 30 | } 31 | 32 | public SimpleImageBanner(Context context, AttributeSet attrs) { 33 | this(context, attrs, 0); 34 | } 35 | 36 | public SimpleImageBanner(Context context, AttributeSet attrs, int defStyle) { 37 | super(context, attrs, defStyle); 38 | colorDrawable = new ColorDrawable(Color.parseColor("#555555")); 39 | } 40 | 41 | @Override 42 | public void onTitleSlect(TextView tv, int position) { 43 | final BannerItem item = list.get(position); 44 | tv.setText(item.title); 45 | } 46 | 47 | @Override 48 | public View onCreateItemView(int position) { 49 | View inflate = View.inflate(context, R.layout.adapter_simple_image, null); 50 | ImageView iv = ViewFindUtils.find(inflate, R.id.iv); 51 | 52 | final BannerItem item = list.get(position); 53 | int itemWidth = dm.widthPixels; 54 | int itemHeight = (int) (itemWidth * 360 * 1.0f / 640); 55 | iv.setScaleType(ImageView.ScaleType.CENTER_CROP); 56 | iv.setLayoutParams(new LinearLayout.LayoutParams(itemWidth, itemHeight)); 57 | 58 | String imgUrl = item.imgUrl; 59 | 60 | if (!TextUtils.isEmpty(imgUrl)) { 61 | Glide.with(context) 62 | .load(imgUrl) 63 | .override(itemWidth, itemHeight) 64 | .centerCrop() 65 | .placeholder(colorDrawable) 66 | .into(iv); 67 | } else { 68 | iv.setImageDrawable(colorDrawable); 69 | } 70 | 71 | return inflate; 72 | } 73 | } 74 | ``` 75 | 76 | ###The Most Complex 77 | in layout xml 78 | 79 | ``` xml 80 | 107 | ``` 108 | 109 | int Java Code 110 | 111 | ``` Java 112 | sib 113 | .setSelectAnimClass(ZoomInEnter.class) //set indicator select anim 114 | .setSource(DataProvider.getList()) //data source list 115 | .setTransformerClass(ZoomOutSlideTransformer.class) //set page transformer 116 | .startScroll(); 117 | ``` 118 | 119 | ###The Simplest 120 | in layout xml 121 | 122 | ``` xml 123 | 128 | ``` 129 | 130 | int Java Code 131 | 132 | ``` Java 133 | sib 134 | .setSource(DataProvider.getList()) 135 | .startScroll(); 136 | ``` 137 | 138 | ###Attributes 139 | 140 | 141 | |name|format|description| 142 | |:---:|:---:|:---:| 143 | | bb_scale | float |Banner高宽比,范围0-1,默认0.5(for LoopViewPager) 144 | | bb_isLoopEnable | boolean |是否支持循环,默认true 145 | | bb_delay | integer |滚动延时,默认5秒 146 | | bb_period | integer |滚动间隔,默认5秒 147 | | bb_isAutoScrollEnable |boolean|是否支持自动滚动,默认true 148 | | bb_barColor | color |设置底部背景条颜色,默认透明 149 | | bb_isBarShowWhenLast | boolean |设置当滚动到最后一个item时是否显示底部背景条 150 | | bb_barPaddingLeft | dimension |设置底部背景条padding,单位dp 151 | | bb_barPaddingTop | dimension |设置底部背景条padding,单位dp 152 | | bb_barPaddingRight | dimension |设置底部背景条padding,单位dp 153 | | bb_barPaddingBottom | dimension |设置底部背景条padding,单位dp 154 | | bb_textColor | color |设置标题文字颜色,默认"#ffffff" 155 | | bb_textSize | dimension |设置标题文字大小,单位sp,默认14sp 156 | | bb_isTitleShow | boolean |设置是否显示标题,默认true 157 | | bb_isIndicatorShow | boolean |设置是否显示显示器,默认true 158 | | bb_indicatorGravity |enum| 设置显示器位置.默认Gravity.CENTER.Gravity.CENTER时文字不显示 159 | | bb_indicatorStyle |enum| 设置显示器样式 160 | | bb_indicatorWidth | dimension |设置显示器宽度,单位dp,默认6dp 161 | | bb_indicatorHeight | dimension |设置显示器高度,单位dp,默认6dp 162 | | bb_indicatorGap | dimension |设置显示器间距,单位dp,默认6dp 163 | | bb_indicatorSelectColor | color |设置显示器选中颜色,默认"#ffffff" 164 | | bb_indicatorUnselectColor | color |设置显示器未选中颜色,默认"#88ffffff" 165 | | bb_indicatorCornerRadius | dimension |设置显示器圆角弧度,单位dp,默认3dp 166 | | bb_indicatorSelectRes | reference |设置显示器选中drawable资源 167 | | bb_indicatorUnselectRes | reference |设置显示器未选中drawable资源 168 | 169 | 170 | ##Thanks 171 | * [LoopingViewPager](https://github.com/imbryk/LoopingViewPager) 172 | * [NineOldAndroids](https://github.com/JakeWharton/NineOldAndroids) 173 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.flyco.bannersamples" 9 | minSdkVersion 8 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.github.bumptech.glide:glide:3.6.1' 25 | //FlycoDialog 26 | compile 'com.nineoldandroids:library:2.4.0' 27 | compile 'com.flyco.dialog:FlycoDialog_Lib:1.2.6@aar' 28 | 29 | //FlycoBanner 30 | // compile 'com.android.support:support-v4:22.2.1' 31 | // compile 'com.flyco.banner:FlycoBanner_Lib:2.0.2@aar' 32 | // compile 'com.nineoldandroids:library:2.4.0' 33 | 34 | compile project(':FlycoBanner_Lib') 35 | } 36 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/lihui/work/AndroidStudio/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/flyco/bannersamples/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/banner/SimpleGuideBanner.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.banner; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import android.widget.ImageView; 7 | import android.widget.TextView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.flyco.banner.widget.Banner.BaseIndicatorBanner; 11 | import com.flyco.bannersamples.R; 12 | import com.flyco.bannersamples.utils.ViewFindUtils; 13 | 14 | public class SimpleGuideBanner extends BaseIndicatorBanner { 15 | public SimpleGuideBanner(Context context) { 16 | this(context, null, 0); 17 | } 18 | 19 | public SimpleGuideBanner(Context context, AttributeSet attrs) { 20 | this(context, attrs, 0); 21 | } 22 | 23 | public SimpleGuideBanner(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | setBarShowWhenLast(false); 26 | } 27 | 28 | @Override 29 | public View onCreateItemView(int position) { 30 | View inflate = View.inflate(mContext, R.layout.adapter_simple_guide, null); 31 | ImageView iv = ViewFindUtils.find(inflate, R.id.iv); 32 | TextView tv_jump = ViewFindUtils.find(inflate, R.id.tv_jump); 33 | 34 | final Integer resId = mDatas.get(position); 35 | tv_jump.setVisibility(position == mDatas.size() - 1 ? VISIBLE : GONE); 36 | 37 | Glide.with(mContext) 38 | .load(resId) 39 | .into(iv); 40 | 41 | tv_jump.setOnClickListener(new OnClickListener() { 42 | @Override 43 | public void onClick(View v) { 44 | if (onJumpClickL != null) 45 | onJumpClickL.onJumpClick(); 46 | } 47 | }); 48 | 49 | return inflate; 50 | } 51 | 52 | private OnJumpClickL onJumpClickL; 53 | 54 | public interface OnJumpClickL { 55 | void onJumpClick(); 56 | } 57 | 58 | public void setOnJumpClickL(OnJumpClickL onJumpClickL) { 59 | this.onJumpClickL = onJumpClickL; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/banner/SimpleImageBanner.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.banner; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.text.TextUtils; 7 | import android.util.AttributeSet; 8 | import android.view.View; 9 | import android.widget.ImageView; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.flyco.banner.widget.Banner.BaseIndicatorBanner; 15 | import com.flyco.bannersamples.R; 16 | import com.flyco.bannersamples.entity.BannerItem; 17 | import com.flyco.bannersamples.utils.ViewFindUtils; 18 | 19 | public class SimpleImageBanner extends BaseIndicatorBanner { 20 | private ColorDrawable colorDrawable; 21 | 22 | public SimpleImageBanner(Context context) { 23 | this(context, null, 0); 24 | } 25 | 26 | public SimpleImageBanner(Context context, AttributeSet attrs) { 27 | this(context, attrs, 0); 28 | } 29 | 30 | public SimpleImageBanner(Context context, AttributeSet attrs, int defStyle) { 31 | super(context, attrs, defStyle); 32 | colorDrawable = new ColorDrawable(Color.parseColor("#555555")); 33 | } 34 | 35 | @Override 36 | public void onTitleSlect(TextView tv, int position) { 37 | final BannerItem item = mDatas.get(position); 38 | tv.setText(item.title); 39 | } 40 | 41 | @Override 42 | public View onCreateItemView(int position) { 43 | View inflate = View.inflate(mContext, R.layout.adapter_simple_image, null); 44 | ImageView iv = ViewFindUtils.find(inflate, R.id.iv); 45 | 46 | final BannerItem item = mDatas.get(position); 47 | int itemWidth = mDisplayMetrics.widthPixels; 48 | int itemHeight = (int) (itemWidth * 360 * 1.0f / 640); 49 | iv.setScaleType(ImageView.ScaleType.CENTER_CROP); 50 | iv.setLayoutParams(new LinearLayout.LayoutParams(itemWidth, itemHeight)); 51 | 52 | String imgUrl = item.imgUrl; 53 | 54 | if (!TextUtils.isEmpty(imgUrl)) { 55 | Glide.with(mContext) 56 | .load(imgUrl) 57 | .override(itemWidth, itemHeight) 58 | .centerCrop() 59 | .placeholder(colorDrawable) 60 | .into(iv); 61 | } else { 62 | iv.setImageDrawable(colorDrawable); 63 | } 64 | 65 | return inflate; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/banner/SimpleTextBanner.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.banner; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import com.flyco.banner.widget.Banner.BaseIndicatorBanner; 9 | import com.flyco.bannersamples.R; 10 | import com.flyco.bannersamples.utils.ViewFindUtils; 11 | 12 | public class SimpleTextBanner extends BaseIndicatorBanner { 13 | public SimpleTextBanner(Context context) { 14 | this(context, null, 0); 15 | } 16 | 17 | public SimpleTextBanner(Context context, AttributeSet attrs) { 18 | this(context, attrs, 0); 19 | } 20 | 21 | public SimpleTextBanner(Context context, AttributeSet attrs, int defStyle) { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | @Override 26 | public void onTitleSlect(TextView tv, int position) { 27 | } 28 | 29 | @Override 30 | public View onCreateItemView(int position) { 31 | View inflate = View.inflate(mContext, R.layout.adapter_simple_text, null); 32 | TextView tv = ViewFindUtils.find(inflate, R.id.tv); 33 | tv.setText(mDatas.get(position)); 34 | 35 | return inflate; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/dialog/BannerDialog.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.dialog; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.support.v4.view.ViewPager; 6 | import android.view.View; 7 | 8 | import com.flyco.banner.anim.select.ZoomInEnter; 9 | import com.flyco.bannersamples.R; 10 | import com.flyco.bannersamples.banner.SimpleImageBanner; 11 | import com.flyco.bannersamples.utils.DataProvider; 12 | import com.flyco.bannersamples.utils.T; 13 | import com.flyco.bannersamples.utils.ViewFindUtils; 14 | import com.flyco.dialog.widget.base.BottomBaseDialog; 15 | 16 | public class BannerDialog extends BottomBaseDialog { 17 | private SimpleImageBanner sib; 18 | private Class transformerClass; 19 | 20 | public BannerDialog(Context context) { 21 | super(context); 22 | } 23 | 24 | @Override 25 | public View onCreateView() { 26 | View inflate = View.inflate(mContext, R.layout.dialog_banner, null); 27 | sib = ViewFindUtils.find(inflate, R.id.sib); 28 | 29 | return inflate; 30 | } 31 | 32 | @Override 33 | public void setUiBeforShow() { 34 | sib(); 35 | } 36 | 37 | public BannerDialog transformerClass(Class transformerClass) { 38 | this.transformerClass = transformerClass; 39 | return this; 40 | } 41 | 42 | private void sib() { 43 | sib 44 | .setIndicatorGap(8) //set gap btween two indicators 45 | .setSelectAnimClass(ZoomInEnter.class) //set indicator select anim 46 | .setBarColor(Color.parseColor("#88000000")) //set bootom bar color 47 | .setSource(DataProvider.getList()) //data source list 48 | .setTransformerClass(transformerClass) //set page transformer 49 | .startScroll(); //start scroll,the last method to call 50 | 51 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 52 | @Override 53 | public void onItemClick(int position) { 54 | T.showShort(mContext, "position--->" + position); 55 | } 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/entity/BannerItem.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.entity; 2 | 3 | public class BannerItem { 4 | public String imgUrl; 5 | public String title; 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/ui/BannerHomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.util.DisplayMetrics; 8 | import android.view.View; 9 | import android.widget.AdapterView; 10 | 11 | import com.flyco.animation.BounceEnter.BounceTopEnter; 12 | import com.flyco.animation.SlideExit.SlideBottomExit; 13 | import com.flyco.banner.anim.select.RotateEnter; 14 | import com.flyco.banner.anim.select.ZoomInEnter; 15 | import com.flyco.banner.anim.unselect.NoAnimExist; 16 | import com.flyco.banner.transform.ZoomOutSlideTransformer; 17 | import com.flyco.bannersamples.R; 18 | import com.flyco.bannersamples.banner.SimpleImageBanner; 19 | import com.flyco.bannersamples.banner.SimpleTextBanner; 20 | import com.flyco.bannersamples.dialog.BannerDialog; 21 | import com.flyco.bannersamples.utils.DataProvider; 22 | import com.flyco.bannersamples.utils.T; 23 | import com.flyco.bannersamples.utils.ViewFindUtils; 24 | import com.flyco.dialog.listener.OnBtnClickL; 25 | import com.flyco.dialog.listener.OnOperItemClickL; 26 | import com.flyco.dialog.widget.MaterialDialog; 27 | import com.flyco.dialog.widget.NormalListDialog; 28 | 29 | import java.util.ArrayList; 30 | 31 | public class BannerHomeActivity extends Activity { 32 | private Context context = this; 33 | private View decorView; 34 | private DisplayMetrics dm; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_main); 40 | 41 | decorView = getWindow().getDecorView(); 42 | dm = getResources().getDisplayMetrics(); 43 | 44 | sib_simple_usage(); 45 | sib_the_most_comlex_usage(); 46 | sib_res(); 47 | sib_rectangle(); 48 | sib_corner_rectangle(); 49 | sib_indicator_right_with_text(); 50 | sib_indicator_left_with_text(); 51 | sib_anim(); 52 | sib_anim2(); 53 | stb(); 54 | 55 | 56 | ViewFindUtils.find(decorView, R.id.tv_user_guide).setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | Intent intent = new Intent(context, UserGuideActivity.class); 60 | intent.putExtra("isFromBannerHome", true); 61 | startActivity(intent); 62 | } 63 | }); 64 | 65 | ViewFindUtils.find(decorView, R.id.tv_select_transformer).setOnClickListener(new View.OnClickListener() { 66 | @Override 67 | public void onClick(View v) { 68 | showSelectDialog(false); 69 | } 70 | }); 71 | 72 | ViewFindUtils.find(decorView, R.id.tv_select_transformer2).setOnClickListener(new View.OnClickListener() { 73 | @Override 74 | public void onClick(View v) { 75 | showSelectDialog(true); 76 | } 77 | }); 78 | } 79 | 80 | private void sib_simple_usage() { 81 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_simple_usage); 82 | 83 | sib 84 | .setSource(DataProvider.getList()) 85 | .startScroll(); 86 | 87 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 88 | @Override 89 | public void onItemClick(int position) { 90 | T.showShort(context, "position--->" + position); 91 | } 92 | }); 93 | } 94 | 95 | private void sib_the_most_comlex_usage() { 96 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_the_most_comlex_usage); 97 | sib 98 | /** methods in BaseIndicatorBanner */ 99 | // .setIndicatorStyle(BaseIndicaorBanner.STYLE_CORNER_RECTANGLE)//set indicator style 100 | // .setIndicatorWidth(6) //set indicator width 101 | // .setIndicatorHeight(6) //set indicator height 102 | // .setIndicatorGap(8) //set gap btween two indicators 103 | // .setIndicatorCornerRadius(3) //set indicator corner raduis 104 | .setSelectAnimClass(ZoomInEnter.class) //set indicator select anim 105 | /** methods in BaseBanner */ 106 | // .setBarColor(Color.parseColor("#88000000")) //set bootom bar color 107 | // .barPadding(5, 2, 5, 2) //set bottom bar padding 108 | // .setBarShowWhenLast(true) //set bottom bar show or not when the position is the last 109 | // .setTextColor(Color.parseColor("#ffffff")) //set title text color 110 | // .setTextSize(12.5f) //set title text size 111 | // .setTitleShow(true) //set title show or not 112 | // .setIndicatorShow(true) //set indicator show or not 113 | // .setDelay(2) //setDelay before start scroll 114 | // .setPeriod(10) //scroll setPeriod 115 | .setSource(DataProvider.getList()) //data source list 116 | .setTransformerClass(ZoomOutSlideTransformer.class) //set page transformer 117 | .startScroll(); //start scroll,the last method to call 118 | 119 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 120 | @Override 121 | public void onItemClick(int position) { 122 | T.showShort(context, "position--->" + position); 123 | } 124 | }); 125 | } 126 | 127 | private void sib_res() { 128 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_res); 129 | 130 | sib 131 | // .setIndicatorStyle(SimpleImageBanner.STYLE_DRAWABLE_RESOURCE) 132 | // .setIndicatorSelectorRes(R.mipmap.banner_dot_unselect, R.mipmap.banner_dot_select) 133 | .setSource(DataProvider.getList()) 134 | .startScroll(); 135 | 136 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 137 | @Override 138 | public void onItemClick(int position) { 139 | T.showShort(context, "position--->" + position); 140 | } 141 | }); 142 | } 143 | 144 | private void sib_rectangle() { 145 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_rectangle); 146 | sib 147 | // .setIndicatorCornerRadius(0) 148 | .setSource(DataProvider.getList()) 149 | .startScroll(); 150 | 151 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 152 | @Override 153 | public void onItemClick(int position) { 154 | T.showShort(context, "position--->" + position); 155 | } 156 | }); 157 | } 158 | 159 | private void sib_corner_rectangle() { 160 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_corner_rectangle); 161 | sib 162 | // .setIndicatorWidth(10) 163 | // .setIndicatorHeight(4) 164 | // .setIndicatorCornerRadius(2) 165 | .setSource(DataProvider.getList()) 166 | .startScroll(); 167 | 168 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 169 | @Override 170 | public void onItemClick(int position) { 171 | T.showShort(context, "position--->" + position); 172 | } 173 | }); 174 | } 175 | 176 | 177 | private void sib_indicator_right_with_text() { 178 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_indicator_right_with_text); 179 | sib 180 | .setSource(DataProvider.getList()) 181 | .startScroll(); 182 | 183 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 184 | @Override 185 | public void onItemClick(int position) { 186 | T.showShort(context, "position--->" + position); 187 | } 188 | }); 189 | } 190 | 191 | private void sib_indicator_left_with_text() { 192 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_indicator_left_with_text); 193 | sib 194 | .setSource(DataProvider.getList()) 195 | .startScroll(); 196 | 197 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 198 | @Override 199 | public void onItemClick(int position) { 200 | T.showShort(context, "position--->" + position); 201 | } 202 | }); 203 | } 204 | 205 | private void sib_anim() { 206 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_anim); 207 | sib 208 | .setSelectAnimClass(ZoomInEnter.class) 209 | .setSource(DataProvider.getList()) 210 | .startScroll(); 211 | 212 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 213 | @Override 214 | public void onItemClick(int position) { 215 | T.showShort(context, "position--->" + position); 216 | } 217 | }); 218 | } 219 | 220 | private void sib_anim2() { 221 | SimpleImageBanner sib = ViewFindUtils.find(decorView, R.id.sib_anim2); 222 | sib 223 | // .setIndicatorWidth(10) 224 | // .setIndicatorHeight(4) 225 | // .setIndicatorCornerRadius(2) 226 | .setSelectAnimClass(RotateEnter.class) 227 | .setUnselectAnimClass(NoAnimExist.class) 228 | .setSource(DataProvider.getList()) 229 | .startScroll(); 230 | 231 | sib.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 232 | @Override 233 | public void onItemClick(int position) { 234 | T.showShort(context, "position--->" + position); 235 | } 236 | }); 237 | } 238 | 239 | private void stb() { 240 | SimpleTextBanner stb = ViewFindUtils.find(decorView, R.id.stb); 241 | 242 | ArrayList titles = new ArrayList<>(); 243 | for (String title : DataProvider.titles) { 244 | titles.add(title); 245 | } 246 | stb 247 | .setSource(titles) 248 | .startScroll(); 249 | 250 | stb.setOnItemClickL(new SimpleImageBanner.OnItemClickL() { 251 | @Override 252 | public void onItemClick(int position) { 253 | T.showShort(context, "position--->" + position); 254 | } 255 | }); 256 | } 257 | 258 | private void showSelectDialog(final boolean isSimpleImageBanner) { 259 | 260 | ArrayList itemList = new ArrayList<>(); 261 | for (Class c : DataProvider.transformers) { 262 | itemList.add(c.getSimpleName()); 263 | } 264 | final String[] contents = new String[itemList.size()]; 265 | final NormalListDialog dialog = new NormalListDialog(context, itemList.toArray(contents)); 266 | dialog.title("Select Transformer")// 267 | .cornerRadius(2) 268 | .show(); 269 | dialog.setOnOperItemClickL(new OnOperItemClickL() { 270 | @Override 271 | public void onOperItemClick(AdapterView parent, View view, int position, long id) { 272 | if (isSimpleImageBanner) { 273 | new BannerDialog(context) 274 | .transformerClass(DataProvider.transformers[position]) 275 | .show(); 276 | return; 277 | } 278 | 279 | Intent intent = new Intent(context, UserGuideActivity.class); 280 | intent.putExtra("isFromBannerHome", true); 281 | intent.putExtra("position", position); 282 | startActivity(intent); 283 | } 284 | }); 285 | } 286 | 287 | 288 | @Override 289 | public void onBackPressed() { 290 | final MaterialDialog dialog = new MaterialDialog(context); 291 | dialog.isTitleShow(false)// 292 | .content("是否确定退出当前App?")// 293 | .contentTextSize(18) 294 | .btnText("取消", "退出")// 295 | .showAnim(new BounceTopEnter())// 296 | .dismissAnim(new SlideBottomExit())// 297 | .show(); 298 | 299 | dialog.setOnBtnClickL(new OnBtnClickL() { 300 | @Override 301 | public void onBtnClick() { 302 | dialog.dismiss(); 303 | } 304 | }, new OnBtnClickL() { 305 | @Override 306 | public void onBtnClick() { 307 | dialog.superDismiss(); 308 | finish(); 309 | System.exit(0); 310 | } 311 | }); 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/ui/UserGuideActivity.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.support.v4.view.ViewPager; 8 | import android.view.View; 9 | 10 | import com.flyco.banner.anim.select.ZoomInEnter; 11 | import com.flyco.bannersamples.R; 12 | import com.flyco.bannersamples.banner.SimpleGuideBanner; 13 | import com.flyco.bannersamples.utils.DataProvider; 14 | import com.flyco.bannersamples.utils.ViewFindUtils; 15 | 16 | public class UserGuideActivity extends Activity { 17 | private Context context = this; 18 | private View decorView; 19 | private boolean isFromBannerHome; 20 | private Class transformerClass; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_user_guide); 26 | 27 | isFromBannerHome = getIntent().getBooleanExtra("isFromBannerHome", false); 28 | int position = getIntent().getIntExtra("position", -1); 29 | transformerClass = position != -1 ? DataProvider.transformers[position] : null; 30 | 31 | decorView = getWindow().getDecorView(); 32 | sgb(); 33 | } 34 | 35 | 36 | private void sgb() { 37 | SimpleGuideBanner sgb = ViewFindUtils.find(decorView, R.id.sgb); 38 | 39 | sgb 40 | .setIndicatorWidth(6) 41 | .setIndicatorHeight(6) 42 | .setIndicatorGap(12) 43 | .setIndicatorCornerRadius(3.5f) 44 | .setSelectAnimClass(ZoomInEnter.class) 45 | .setTransformerClass(transformerClass) 46 | .barPadding(0, 10, 0, 10) 47 | .setSource(DataProvider.geUsertGuides()) 48 | .startScroll(); 49 | 50 | sgb.setOnJumpClickL(new SimpleGuideBanner.OnJumpClickL() { 51 | @Override 52 | public void onJumpClick() { 53 | if (isFromBannerHome) { 54 | finish(); 55 | return; 56 | } 57 | 58 | Intent intent = new Intent(context, BannerHomeActivity.class); 59 | startActivity(intent); 60 | finish(); 61 | } 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/utils/DataProvider.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.utils; 2 | 3 | import android.support.v4.view.ViewPager; 4 | 5 | import com.flyco.banner.transform.DepthTransformer; 6 | import com.flyco.banner.transform.FadeSlideTransformer; 7 | import com.flyco.banner.transform.FlowTransformer; 8 | import com.flyco.banner.transform.RotateDownTransformer; 9 | import com.flyco.banner.transform.RotateUpTransformer; 10 | import com.flyco.banner.transform.ZoomOutSlideTransformer; 11 | import com.flyco.bannersamples.R; 12 | import com.flyco.bannersamples.entity.BannerItem; 13 | 14 | import java.util.ArrayList; 15 | 16 | public class DataProvider { 17 | public static String[] titles = new String[]{ 18 | "伪装者:胡歌演绎'痞子特工'", 19 | "无心法师:生死离别!月牙遭虐杀", 20 | "花千骨:尊上沦为花千骨", 21 | "综艺饭:胖轩偷看夏天洗澡掀波澜", 22 | "碟中谍4:阿汤哥高塔命悬一线,超越不可能", 23 | }; 24 | public static String[] urls = new String[]{//640*360 360/640=0.5625 25 | "http://photocdn.sohu.com/tvmobilemvms/20150907/144160323071011277.jpg",//伪装者:胡歌演绎"痞子特工" 26 | "http://photocdn.sohu.com/tvmobilemvms/20150907/144158380433341332.jpg",//无心法师:生死离别!月牙遭虐杀 27 | "http://photocdn.sohu.com/tvmobilemvms/20150907/144160286644953923.jpg",//花千骨:尊上沦为花千骨 28 | "http://photocdn.sohu.com/tvmobilemvms/20150902/144115156939164801.jpg",//综艺饭:胖轩偷看夏天洗澡掀波澜 29 | "http://photocdn.sohu.com/tvmobilemvms/20150907/144159406950245847.jpg",//碟中谍4:阿汤哥高塔命悬一线,超越不可能 30 | }; 31 | 32 | public static ArrayList getList() { 33 | ArrayList list = new ArrayList<>(); 34 | for (int i = 0; i < urls.length; i++) { 35 | BannerItem item = new BannerItem(); 36 | item.imgUrl = urls[i]; 37 | item.title = titles[i]; 38 | 39 | list.add(item); 40 | } 41 | 42 | return list; 43 | } 44 | 45 | public static ArrayList geUsertGuides() { 46 | ArrayList list = new ArrayList<>(); 47 | list.add(R.mipmap.guide_img_1); 48 | list.add(R.mipmap.guide_img_2); 49 | list.add(R.mipmap.guide_img_3); 50 | list.add(R.mipmap.guide_img_4); 51 | 52 | return list; 53 | } 54 | 55 | public static Class transformers[] = new Class[]{ 56 | DepthTransformer.class, 57 | FadeSlideTransformer.class, 58 | FlowTransformer.class, 59 | RotateDownTransformer.class, 60 | RotateUpTransformer.class, 61 | ZoomOutSlideTransformer.class, 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/utils/T.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.utils; 2 | 3 | import android.content.Context; 4 | import android.widget.Toast; 5 | 6 | /** 7 | * Toast统一管理类 8 | */ 9 | public class T 10 | { 11 | private static Toast toast; 12 | 13 | /** 14 | * 短时间显示Toast 15 | */ 16 | public static void showShort(Context context, CharSequence message) 17 | { 18 | if (null == toast) 19 | { 20 | toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); 21 | // toast.setGravity(Gravity.CENTER, 0, 0); 22 | } 23 | else 24 | { 25 | toast.setText(message); 26 | } 27 | toast.show(); 28 | } 29 | 30 | /** 31 | * 短时间显示Toast 32 | */ 33 | public static void showShort(Context context, int message) 34 | { 35 | if (null == toast) 36 | { 37 | toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); 38 | // toast.setGravity(Gravity.CENTER, 0, 0); 39 | } 40 | else 41 | { 42 | toast.setText(message); 43 | } 44 | toast.show(); 45 | } 46 | 47 | /** 48 | * 长时间显示Toast 49 | */ 50 | public static void showLong(Context context, CharSequence message) 51 | { 52 | if (null == toast) 53 | { 54 | toast = Toast.makeText(context, message, Toast.LENGTH_LONG); 55 | // toast.setGravity(Gravity.CENTER, 0, 0); 56 | } 57 | else 58 | { 59 | toast.setText(message); 60 | } 61 | toast.show(); 62 | } 63 | 64 | /** 65 | * 长时间显示Toast 66 | */ 67 | public static void showLong(Context context, int message) 68 | { 69 | if (null == toast) 70 | { 71 | toast = Toast.makeText(context, message, Toast.LENGTH_LONG); 72 | // toast.setGravity(Gravity.CENTER, 0, 0); 73 | } 74 | else 75 | { 76 | toast.setText(message); 77 | } 78 | toast.show(); 79 | } 80 | 81 | /** 82 | * 自定义显示Toast时间 83 | */ 84 | public static void show(Context context, CharSequence message, int duration) 85 | { 86 | if (null == toast) 87 | { 88 | toast = Toast.makeText(context, message, duration); 89 | // toast.setGravity(Gravity.CENTER, 0, 0); 90 | } 91 | else 92 | { 93 | toast.setText(message); 94 | } 95 | toast.show(); 96 | } 97 | 98 | /** 99 | * 自定义显示Toast时间 100 | */ 101 | public static void show(Context context, int message, int duration) 102 | { 103 | if (null == toast) 104 | { 105 | toast = Toast.makeText(context, message, duration); 106 | // toast.setGravity(Gravity.CENTER, 0, 0); 107 | } 108 | else 109 | { 110 | toast.setText(message); 111 | } 112 | toast.show(); 113 | } 114 | 115 | /** Hide the toast, if any. */ 116 | public static void hideToast() 117 | { 118 | if (null != toast) 119 | { 120 | toast.cancel(); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/flyco/bannersamples/utils/ViewFindUtils.java: -------------------------------------------------------------------------------- 1 | package com.flyco.bannersamples.utils; 2 | 3 | import android.util.SparseArray; 4 | import android.view.View; 5 | 6 | @SuppressWarnings({ "unchecked" }) 7 | public class ViewFindUtils 8 | { 9 | /** 10 | * ViewHolder简洁写法,避免适配器中重复定义ViewHolder,减少代码量 用法: 11 | * 12 | *
13 | 	 * if (convertView == null)
14 | 	 * {
15 | 	 * 	convertView = View.inflate(context, R.layout.ad_demo, null);
16 | 	 * }
17 | 	 * TextView tv_demo = ViewHolderUtils.get(convertView, R.id.tv_demo);
18 | 	 * ImageView iv_demo = ViewHolderUtils.get(convertView, R.id.iv_demo);
19 | 	 * 
20 | */ 21 | public static T hold(View view, int id) 22 | { 23 | SparseArray viewHolder = (SparseArray) view.getTag(); 24 | 25 | if (viewHolder == null) 26 | { 27 | viewHolder = new SparseArray(); 28 | view.setTag(viewHolder); 29 | } 30 | 31 | View childView = viewHolder.get(id); 32 | 33 | if (childView == null) 34 | { 35 | childView = view.findViewById(id); 36 | viewHolder.put(id, childView); 37 | } 38 | 39 | return (T) childView; 40 | } 41 | 42 | /** 43 | * 替代findviewById方法 44 | */ 45 | public static T find(View view, int id) 46 | { 47 | return (T) view.findViewById(id); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corner_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | 21 | 22 | 26 | 27 | 35 | 36 | 37 | 45 | 46 | 51 | 52 | 60 | 61 | 88 | 89 | 97 | 98 | 110 | 111 | 119 | 120 | 121 | 129 | 130 | 138 | 139 | 147 | 148 | 156 | 157 | 168 | 169 | 177 | 178 | 186 | 187 | 195 | 196 | 203 | 204 | 214 | 215 | 221 | 222 | 226 | 227 | 235 | 236 | 237 | 246 | 247 | 253 | 254 | 258 | 259 | 267 | 268 | 269 | 278 | 279 | 288 | 289 | 295 | 296 | 300 | 301 | 309 | 310 | 311 | 319 | 320 | 325 | 326 | 327 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_user_guide.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_simple_guide.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_simple_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_simple_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_banner.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/banner_dot_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/banner_dot_select.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/banner_dot_unselect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/banner_dot_unselect.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/guide_img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/guide_img_1.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/guide_img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/guide_img_2.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/guide_img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/guide_img_3.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/guide_img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/guide_img_4.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | FlycoBanner 3 | 4 | Hello world! 5 | Settings 6 | UserGuideActivity 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.5.0' 9 | // classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' 10 | // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | jcenter() 19 | // maven { 20 | // url "http://dl.bintray.com/h07000223/maven" 21 | // } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 02 15:37:36 CST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /preview_FlycoBanner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/H07000223/FlycoBanner_Master/b4d22170ba328ee99ce442582996930ea085b465/preview_FlycoBanner.gif -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':FlycoBanner_Lib' 2 | --------------------------------------------------------------------------------