├── BannerProj ├── app │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── layout │ │ │ │ │ └── activity_main.xml │ │ │ │ ├── drawable-v24 │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ └── drawable │ │ │ │ │ └── ic_launcher_background.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── zy │ │ │ │ └── adproj │ │ │ │ └── MainActivity.java │ │ ├── test │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── zy │ │ │ │ └── adproj │ │ │ │ └── ExampleUnitTest.java │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── zy │ │ │ └── adproj │ │ │ └── ExampleInstrumentedTest.java │ ├── proguard-rules.pro │ └── build.gradle ├── bannermul │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ └── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── attrs.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── zy │ │ │ │ └── bannermul │ │ │ │ ├── MyFileNameGenerator.java │ │ │ │ ├── BannerPage.java │ │ │ │ ├── MVideoView.java │ │ │ │ ├── MImageView.java │ │ │ │ ├── ViewPagerBanner.java │ │ │ │ ├── BannerModel.java │ │ │ │ ├── BannerViewAdapter.java │ │ │ │ ├── BannerMul.java │ │ │ │ └── Banner.java │ │ ├── test │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── zy │ │ │ │ └── bannermul │ │ │ │ └── ExampleUnitTest.java │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── zy │ │ │ └── bannermul │ │ │ └── ExampleInstrumentedTest.java │ ├── proguard-rules.pro │ ├── build.gradle │ └── bintrayUpload.gradle ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── .idea │ ├── runConfigurations.xml │ ├── gradle.xml │ ├── codeStyles │ │ └── Project.xml │ └── misc.xml ├── gradle.properties ├── build.gradle ├── gradlew.bat └── gradlew ├── showImg ├── banner.gif ├── layout.png ├── activity.png └── compile.png ├── .idea ├── markdown-navigator │ └── profiles_settings.xml ├── vcs.xml ├── markdown-exported-files.xml ├── modules.xml ├── BannerMul.iml ├── codeStyles │ └── Project.xml ├── markdown-navigator.xml └── workspace.xml ├── LICENSE └── README.md /BannerProj/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /BannerProj/bannermul/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /BannerProj/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':bannermul' 2 | -------------------------------------------------------------------------------- /showImg/banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/showImg/banner.gif -------------------------------------------------------------------------------- /showImg/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/showImg/layout.png -------------------------------------------------------------------------------- /showImg/activity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/showImg/activity.png -------------------------------------------------------------------------------- /showImg/compile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/showImg/compile.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | BannerProj 3 | 4 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | bannermul 3 | 4 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /BannerProj/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gegeyang0124/Android-BannerMul/HEAD/BannerProj/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/markdown-exported-files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BannerProj/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /BannerProj/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | #distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 4 | distributionUrl=http\://services.gradle.org/distributions/gradle-4.6-all.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BannerProj/app/src/test/java/com/zy/adproj/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.zy.adproj; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /.idea/BannerMul.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/test/java/com/zy/bannermul/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/MyFileNameGenerator.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.net.Uri; 4 | 5 | import com.danikula.videocache.file.FileNameGenerator; 6 | 7 | /** 8 | * Created by steven on 2018/5/15. 9 | */ 10 | 11 | public class MyFileNameGenerator implements FileNameGenerator 12 | { 13 | @Override 14 | public String generate(String url) 15 | { 16 | String name = url.substring(url.lastIndexOf("/") + 1, url.length()); 17 | return name; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /BannerProj/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/BannerPage.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | public class BannerPage { 4 | public String url;//图片/视频地址 5 | public int imgDelyed = 2000;//图片轮播延时时间 6 | 7 | public BannerPage(){} 8 | 9 | /** 10 | * 构造函数 11 | * @param url String;//图片/视频地址 12 | * **/ 13 | public BannerPage(String url) 14 | { 15 | this.url = url; 16 | } 17 | 18 | /** 19 | * 构造函数 20 | * @param url String;//图片/视频地址 21 | * @param imgDelyed int;//图片轮播延时时间 22 | * **/ 23 | public BannerPage(String url,int imgDelyed) 24 | { 25 | this.url = url; 26 | this.imgDelyed = imgDelyed; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /BannerProj/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /BannerProj/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /BannerProj/bannermul/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /BannerProj/app/src/androidTest/java/com/zy/adproj/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.zy.adproj; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.zy.adproj", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/androidTest/java/com/zy/bannermul/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.zy.bannermul.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /BannerProj/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | #project 16 | project.name=bannermul 17 | project.groupId=com.zy 18 | project.artifactId=bannermul 19 | project.packaging=aar 20 | project.siteUrl=https://github.com/gegeyang0124/BannerMul 21 | project.gitUrl=https://github.com/gegeyang0124/BannerMul.git 22 | 23 | #javadoc 24 | javadoc.name=bannermul -------------------------------------------------------------------------------- /BannerProj/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.zy.adproj" 7 | minSdkVersion 15 8 | targetSdkVersion 27 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | implementation 'com.android.support:appcompat-v7:27.1.1' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | 29 | // compile 'com.zy:bannermul:1.0.0' 30 | compile project(':bannermul') 31 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 gegeyang0124 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 | -------------------------------------------------------------------------------- /BannerProj/bannermul/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 27 5 | 6 | 7 | 8 | defaultConfig { 9 | minSdkVersion 15 10 | targetSdkVersion 27 11 | versionCode 1 12 | versionName "1.0.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | implementation fileTree(dir: 'libs', include: ['*.jar']) 29 | 30 | implementation 'com.android.support:appcompat-v7:27.1.1' 31 | testImplementation 'junit:junit:4.12' 32 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 34 | 35 | //最新版本 //远程依赖,com.android.support是域名部分,appcompat-v7是组名称,26.+是版本号 36 | compile 'com.danikula:videocache:2.7.0' 37 | compile 'com.github.bumptech.glide:glide:4.0.0' 38 | } 39 | 40 | apply from: "bintrayUpload.gradle" -------------------------------------------------------------------------------- /BannerProj/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.2.1' 11 | 12 | //maven的插件,注意下版本号,建议改为1.5。以前的版本很有可能会导致编译失败 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 14 | 15 | //bintray的插件 16 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 17 | // classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4' 18 | 19 | //classpath 'com.novoda:bintray-release:0.3.4' 20 | /*classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' 21 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'*/ 22 | 23 | // NOTE: Do not place your application dependencies here; they belong 24 | // in the individual module build.gradle files 25 | } 26 | } 27 | 28 | allprojects { 29 | repositories { 30 | google() 31 | jcenter() 32 | } 33 | } 34 | 35 | task clean(type: Delete) { 36 | delete rootProject.buildDir 37 | } 38 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/MVideoView.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.RectF; 8 | import android.util.AttributeSet; 9 | import android.widget.VideoView; 10 | 11 | /** 12 | * Created by steven on 2017/9/29. 13 | */ 14 | public class MVideoView extends VideoView 15 | { 16 | public MVideoView(Context context) 17 | { 18 | super(context); 19 | } 20 | 21 | public MVideoView(Context context, AttributeSet attrs) 22 | { 23 | super(context, attrs); 24 | } 25 | 26 | public MVideoView(Context context, AttributeSet attrs, int defStyle) 27 | { 28 | super(context, attrs, defStyle); 29 | } 30 | 31 | @Override 32 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 33 | { 34 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 35 | /* int width = getDefaultSize(getWidth(), widthMeasureSpec); 36 | int height = getDefaultSize(getHeight(), heightMeasureSpec); 37 | setMeasuredDimension(width, height);*/ 38 | } 39 | } -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/MImageView.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.AppCompatImageView; 5 | import android.util.AttributeSet; 6 | import android.util.Log; 7 | //import android.widget.ImageView; 8 | 9 | public class MImageView extends AppCompatImageView { 10 | public MImageView(Context context) 11 | { 12 | super(context); 13 | } 14 | 15 | public MImageView(Context context, AttributeSet attrs) 16 | { 17 | super(context, attrs); 18 | } 19 | 20 | public MImageView(Context context, AttributeSet attrs, int defStyle) 21 | { 22 | super(context, attrs, defStyle); 23 | } 24 | 25 | @Override 26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 27 | { 28 | Log.i("widthMeasureSpec",widthMeasureSpec + ""); 29 | Log.i("heightMeasureSpec",heightMeasureSpec + ""); 30 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 31 | /* int width = getDefaultSize(getWidth(), widthMeasureSpec); 32 | int height = getDefaultSize(getHeight(), heightMeasureSpec); 33 | setMeasuredDimension(width, height);*/ 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /BannerProj/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/ViewPagerBanner.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.view.ViewPager; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | 10 | public class ViewPagerBanner extends ViewPager { 11 | //是否可以进行滑动 12 | private boolean isSlide = false;//false:不可以滑动;true:可以滑动 13 | 14 | public ViewPagerBanner(@NonNull Context context) { 15 | super(context); 16 | } 17 | 18 | /** 19 | * //@Nullable ,可以传入空指针 20 | * //@Nonnull ,不可以传入空指针 21 | * **/ 22 | public ViewPagerBanner(@NonNull Context context, @Nullable AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public void setSlide(boolean slide) { 27 | isSlide = slide; 28 | } 29 | 30 | /** 31 | * 1.dispatchTouchEvent一般情况不做处理 32 | * ,如果修改了默认的返回值,子孩子都无法收到事件 33 | */ 34 | @Override 35 | public boolean dispatchTouchEvent(MotionEvent ev) { 36 | return super.dispatchTouchEvent(ev); // return true;不行 37 | } 38 | 39 | /** 40 | * 是否拦截 41 | * 拦截:会走到自己的onTouchEvent方法里面来 42 | * 不拦截:事件传递给子孩子 43 | */ 44 | @Override 45 | public boolean onInterceptTouchEvent(MotionEvent ev) { 46 | return super.onInterceptTouchEvent(ev); 47 | // return false;//可行,不拦截事件, 48 | // return true;//不行,孩子无法处理事件 49 | //return super.onInterceptTouchEvent(ev);//不行,会有细微移动 50 | //return !isSlide; 51 | } 52 | 53 | /** 54 | * 是否消费事件 55 | * 消费:事件就结束 56 | * 不消费:往父控件传 57 | */ 58 | @Override 59 | public boolean onTouchEvent(MotionEvent ev) { 60 | super.onTouchEvent(ev); 61 | //return false;// 可行,不消费,传给父控件 62 | //return true;// 可行,消费,拦截事件 63 | //super.onTouchEvent(ev); //不行, 64 | //虽然onInterceptTouchEvent中拦截了, 65 | //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法. 66 | return isSlide;// 可行,消费,拦截事件 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /BannerProj/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | -------------------------------------------------------------------------------- /BannerProj/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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/BannerModel.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.danikula.videocache.HttpProxyCacheServer; 7 | 8 | import java.util.List; 9 | 10 | public class BannerModel { 11 | 12 | public static HttpProxyCacheServer proxy;//缓存对象 13 | 14 | public static final int MONE_ONE = 1;//轮播模式1 15 | public static final int MONE_TWO = 2;//轮播模式2 16 | public static final int MONE_THREE = 3;//轮播模式3 17 | 18 | public static final float SCREEN_PERCENT = 10;//屏幕总的权重百分比 19 | public static float screenPercent1 = 5;//屏幕一占屏幕的大小(大于1屏有效) 20 | public static float screenPercent2 = 5;//屏幕二占屏幕的大小(大于2屏有效) 21 | 22 | public static String isChange = null;//返回数据的指纹。即当数据没有变化的时候不会发生变化,可以帮助前端快速判断数据是否发生变化 23 | 24 | public static String UNIQUE_ID = null;//设备ID 25 | public static String CodeAuth = null;//授权码 26 | public static String CodeDevice = null;//后台的设备编码 27 | public static int mode = 1;//当前轮播模式 28 | 29 | //public List list;//当前轮播列表 30 | public List list;//当前轮播列表 31 | public int imgDelyed = 1000;//图片轮播延时时间 32 | public Banner banner = null;//轮播UI 33 | public int index = -1;//当前插播地址 34 | public boolean isSlide = false;//false:不可以滑动;true:可以滑动;默认是false 35 | 36 | /** 37 | * 屏幕一,占屏幕的大小(大于1屏有效) 必传 38 | * @param screenPer float;//0~1的浮点数 39 | * **/ 40 | public static void setScreenPercent1(float screenPer){ 41 | screenPercent1 = SCREEN_PERCENT - screenPer * SCREEN_PERCENT; 42 | } 43 | 44 | /** 45 | * 屏幕二,占屏幕的大小(大于2屏有效) 必传 46 | * @param screenPer float;//0~1的浮点数 47 | * **/ 48 | public static void setScreenPercent2(float screenPer){ 49 | screenPercent2 = SCREEN_PERCENT - screenPer * SCREEN_PERCENT; 50 | } 51 | 52 | /** 53 | * 创建缓存对象 54 | * @param context Context;//上下文对象 55 | * **/ 56 | public static HttpProxyCacheServer newProxy(Context context) { 57 | if(proxy == null){ 58 | proxy = new HttpProxyCacheServer.Builder(context) 59 | .fileNameGenerator(new MyFileNameGenerator()) 60 | .build(); 61 | } 62 | 63 | return proxy; 64 | } 65 | 66 | /** 67 | * 创建音视频缓存,返回路径 68 | * @param url String;//音视频地址 69 | * **/ 70 | public static String getProxyUrl(String url) { 71 | return getProxyUrl(null,url); 72 | } 73 | 74 | /** 75 | * 创建音视频缓存,返回路径 76 | * @param context Context;//上下文对象 77 | * @param url String;//音视频地址 78 | * **/ 79 | public static String getProxyUrl(@Nullable Context context, String url) { 80 | if(context != null) 81 | { 82 | newProxy(context); 83 | } 84 | 85 | if(proxy != null){ 86 | return proxy.getProxyUrl(url); 87 | } 88 | 89 | return url; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/BannerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Color; 6 | import android.media.MediaMetadataRetriever; 7 | import android.net.Uri; 8 | import android.support.v4.view.PagerAdapter; 9 | import android.view.Gravity; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.webkit.MimeTypeMap; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | import android.widget.VideoView; 16 | 17 | import com.bumptech.glide.Glide; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * Created by steven on 2018/5/14. 24 | */ 25 | public class BannerViewAdapter extends PagerAdapter 26 | { 27 | private List listBean; 28 | 29 | public BannerViewAdapter(List list,Context context){ 30 | if (list == null){ 31 | list = new ArrayList<>(); 32 | } 33 | 34 | setDataList(list,context); 35 | // this.listBean = list; 36 | } 37 | 38 | public void setDataList(List list,Context context){ 39 | if (list != null && list.size() > 0){ 40 | this.listBean = list; 41 | this.listBean = new ArrayList<>(); 42 | for(int i = 0; i < list.size(); i++){ 43 | View view = list.get(i); 44 | /** 45 | * LinearLayout有两个非常相似的属性:android:gravity与android:layout_gravity。 46 | * 他们的区别在于:android:gravity用于设置View组件的对齐方式, 47 | * 而android:layout_gravity用于设置Container组件的对齐方式。 48 | * View view = list.get(i); 49 | * 举个例子,我们可以通过设置android:gravity="center"来让view中的内容在view组件中居中显示; 50 | * 同时我们设置view的android:layout_gravity="right"来让view组件在LinearLayout中居中显示。 51 | * **/ 52 | LinearLayout linearLayout = new LinearLayout(context); 53 | //设置LinearLayout属性(宽和高) 54 | LinearLayout.LayoutParams layoutParams = new LinearLayout 55 | .LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 56 | LinearLayout.LayoutParams.MATCH_PARENT); 57 | //layoutParams.gravity = Gravity.CENTER_VERTICAL;//android:gravity用于设置View组件的对齐方式, 58 | linearLayout.setGravity(Gravity.CENTER);//用于设置,android:layout_gravity用于设置Container组件的对齐方式 59 | linearLayout.setLayoutParams(layoutParams); 60 | //linearLayout.setBackgroundColor(Color.BLUE); 61 | linearLayout.addView(view); 62 | this.listBean.add(linearLayout); 63 | }; 64 | } 65 | } 66 | 67 | //目的是展示title上的文字, 68 | /* @Override 69 | public CharSequence getPageTitle(int position) { 70 | return mainTitlesArray[position]; 71 | }*/ 72 | 73 | //数量 74 | @Override 75 | public int getCount() 76 | { 77 | return listBean.size(); 78 | } 79 | 80 | //判断是否是否为同一张图片(ui),这里返回方法中的两个参数做比较就可以 81 | @Override 82 | public boolean isViewFromObject(View view, Object object) 83 | { 84 | return view == object; 85 | } 86 | 87 | //设置viewpage内部东西的方法,如果viewpage内没有子控件 滑动产生不了动画效果 88 | @Override 89 | public Object instantiateItem(ViewGroup container, int position) 90 | { 91 | View view = listBean.get(position); 92 | container.addView(view); 93 | return view; 94 | } 95 | 96 | //因为它默认是看三张图片,第四张图片的时候就会报错,还有就是不要返回父类的作用 97 | @Override 98 | public void destroyItem(ViewGroup container, int position, Object object) 99 | { 100 | container.removeView((View) object); 101 | } 102 | 103 | //刷新ViewPager时缓存页面默认是不会刷新的, 只有将PagerAdapter的getItemPosition方法, 104 | // 返回值改为POSITION_NONE时才会刷新, 但是如果都改为POSITION_NONE的话,那开销有点大 105 | @Override 106 | public int getItemPosition(Object object) 107 | { 108 | return POSITION_NONE; 109 | } 110 | 111 | } -------------------------------------------------------------------------------- /BannerProj/bannermul/bintrayUpload.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | apply plugin: 'com.jfrog.bintray' 3 | 4 | // load properties 5 | Properties properties = new Properties() 6 | //File localPropertiesFile = project.file("local.properties"); 7 | File localPropertiesFile = project.rootProject.file("local.properties"); 8 | if(localPropertiesFile.exists()){ 9 | properties.load(localPropertiesFile.newDataInputStream()) 10 | } 11 | //File projectPropertiesFile = project.file("gradle.properties"); 12 | File projectPropertiesFile = project.rootProject.file("gradle.properties"); 13 | if(projectPropertiesFile.exists()){ 14 | properties.load(projectPropertiesFile.newDataInputStream()) 15 | } 16 | 17 | // read properties 18 | def projectName = properties.getProperty("project.name") 19 | def projectGroupId = properties.getProperty("project.groupId") 20 | def projectArtifactId = properties.getProperty("project.artifactId") 21 | def projectVersionName = android.defaultConfig.versionName 22 | def projectPackaging = properties.getProperty("project.packaging") 23 | def projectSiteUrl = properties.getProperty("project.siteUrl") 24 | def projectGitUrl = properties.getProperty("project.gitUrl") 25 | 26 | def developerId = properties.getProperty("developer.id") 27 | def developerName = properties.getProperty("developer.name") 28 | def developerEmail = properties.getProperty("developer.email") 29 | 30 | def bintrayUser = properties.getProperty("bintray.user") 31 | def bintrayApikey = properties.getProperty("bintray.apikey") 32 | 33 | def javadocName = properties.getProperty("javadoc.name") 34 | 35 | group = projectGroupId 36 | 37 | // This generates POM.xml with proper parameters 38 | install { 39 | repositories.mavenInstaller { 40 | pom { 41 | project { 42 | name projectName 43 | groupId projectGroupId 44 | artifactId projectArtifactId 45 | version projectVersionName 46 | packaging projectPackaging 47 | url projectSiteUrl 48 | licenses { 49 | license { 50 | name 'The Apache Software License, Version 2.0' 51 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 52 | } 53 | } 54 | developers { 55 | developer { 56 | id developerId 57 | name developerName 58 | email developerEmail 59 | } 60 | } 61 | scm { 62 | connection projectGitUrl 63 | developerConnection projectGitUrl 64 | url projectSiteUrl 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | // This generates sources.jar 72 | task sourcesJar(type: Jar) { 73 | from android.sourceSets.main.java.srcDirs 74 | classifier = 'sources' 75 | } 76 | 77 | task javadoc(type: Javadoc) { 78 | source = android.sourceSets.main.java.srcDirs 79 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 80 | } 81 | 82 | // Add compile dependencies to javadoc 83 | afterEvaluate { 84 | javadoc.classpath += files(android.libraryVariants.collect { variant -> 85 | variant.javaCompile.classpath.files 86 | }) 87 | } 88 | 89 | // This generates javadoc.jar 90 | task javadocJar(type: Jar, dependsOn: javadoc) { 91 | classifier = 'javadoc' 92 | from javadoc.destinationDir 93 | } 94 | 95 | artifacts { 96 | archives javadocJar 97 | archives sourcesJar 98 | } 99 | 100 | // javadoc configuration 101 | javadoc { 102 | options{ 103 | encoding "UTF-8" 104 | charSet 'UTF-8' 105 | author true 106 | version projectVersionName 107 | links "http://docs.oracle.com/javase/7/docs/api" 108 | title javadocName 109 | } 110 | } 111 | 112 | // bintray configuration 113 | bintray { 114 | user = bintrayUser 115 | key = bintrayApikey 116 | configurations = ['archives'] 117 | pkg { 118 | // repo = "maven" 119 | repo = projectName 120 | name = projectName 121 | // userOrg = 'yehun'//Bintray的组织id 122 | websiteUrl = projectSiteUrl 123 | vcsUrl = projectGitUrl 124 | licenses = ["Apache-2.0"] 125 | publish = true 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/java/com/zy/adproj/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.zy.adproj; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | 7 | import com.danikula.videocache.HttpProxyCacheServer; 8 | import com.zy.bannermul.Banner; 9 | import com.zy.bannermul.BannerModel; 10 | import com.zy.bannermul.BannerMul; 11 | import com.zy.bannermul.BannerPage; 12 | import com.zy.bannermul.MyFileNameGenerator; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class MainActivity extends AppCompatActivity { 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | 24 | init(); 25 | } 26 | 27 | private void init(){ 28 | BannerMul bannermul = (BannerMul) findViewById(R.id.bannermul); 29 | List listbm = new ArrayList<>(); 30 | 31 | /** 32 | * mode 模式(1,2,3),可不传,默认是1; 33 | * // 1.一屏(data一个成员); 34 | * // 2.二屏(data二个成员); 35 | * // 3.三屏(data三个成员) 36 | * */ 37 | BannerModel.mode = 2; 38 | 39 | BannerModel.setScreenPercent1(0.5f);//屏幕1占整个屏幕的高度的的百分比(大于1屏有效)可不传,默认0.5 40 | BannerModel.setScreenPercent2(0.5f);//屏幕2占整个屏幕的宽度的的百分比(大于2屏有效)可不传,默认0.5 41 | 42 | BannerModel bannerModel = new BannerModel(); 43 | bannerModel.index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 44 | bannerModel.isSlide = true;//false:不可以滑动;true:可以滑动;默认是false 45 | List listAddress = new ArrayList<>(); 46 | BannerPage bannerPage1 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",2000); 47 | listAddress.add(bannerPage1); 48 | BannerPage bannerPage2 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",3000); 49 | listAddress.add(bannerPage2); 50 | BannerPage bannerPage3 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 51 | listAddress.add(bannerPage3); 52 | BannerPage bannerPage4 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 53 | listAddress.add(bannerPage4); 54 | bannerModel.list = listAddress; 55 | listbm.add(bannerModel); 56 | 57 | BannerModel bannerModel2 = new BannerModel(); 58 | bannerModel2.index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 59 | //bannerModel2.isSlide = true;//false:不可以滑动;true:可以滑动;默认是false 60 | List listAddress2 = new ArrayList<>(); 61 | BannerPage bannerPage21 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",1000); 62 | listAddress2.add(bannerPage21); 63 | BannerPage bannerPage22 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",2000); 64 | listAddress2.add(bannerPage22); 65 | BannerPage bannerPage23 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 66 | listAddress2.add(bannerPage23); 67 | BannerPage bannerPage24 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 68 | listAddress2.add(bannerPage24); 69 | bannerModel2.list = listAddress2; 70 | listbm.add(bannerModel2); 71 | 72 | bannermul.setDataList(listbm); 73 | 74 | Banner banner = (Banner) findViewById(R.id.banner); 75 | List listAddress3 = new ArrayList<>(); 76 | BannerPage bannerPage31 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",1000); 77 | listAddress3.add(bannerPage31); 78 | BannerPage bannerPage32 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",3000); 79 | listAddress3.add(bannerPage32); 80 | //BannerPage bannerPage33 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 81 | BannerPage bannerPage33 = new BannerPage("http://img1.imgtn.bdimg.com/it/u=562676990,100871093&fm=26&gp=0.jpg"); 82 | listAddress3.add(bannerPage33); 83 | BannerPage bannerPage34 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 84 | listAddress3.add(bannerPage34); 85 | 86 | int index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 87 | banner.setSlide(true); 88 | banner.setDataPlay(listAddress3,index); 89 | //banner.setDataList(listAddress3); 90 | //banner.setDataPlay(listAddress3); 91 | //banner.setDataList(listAddress3,index); 92 | //banner.startBanner(); 93 | //banner.startAutoPlay(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 36 | 37 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BannerMul 2 | 轮播UI库,支持图片轮播(每张图片的都可设置停留时间),
3 | 视频轮播(自动播放,播放完毕可自动切换),
4 | 并支持多屏或单屏幕,自定义屏幕大小,图片和视频自动缓存,不用时自动清理。
5 | 下载解压后Android studio 打开BannerProj编译即可运行 6 | 本项目中的bannermul库,即是com.zy:bannermul:1.0.0的源码 7 | 8 | ### 效果展示 9 | 10 | 11 | 12 | ### 使用 13 | ##### 1.在项目依赖中添加 compile 'com.zy:bannermul:1.0.0' 14 | 15 | 16 | 17 | ##### 2.代码调用 18 | 19 | ###### 2.1 layout布局文件代码,Banner是单个轮播(如‘效果展示’的第一个轮播),BannerMul是多个轮播(由Banner构建) 20 | ![](./showImg/layout.png) 21 | 22 | ###### 2.2 Acitivity文件代码 23 | 24 | 25 | 26 | ```java 27 | package com.zy.adproj; 28 | 29 | import android.support.v7.app.AppCompatActivity; 30 | import android.os.Bundle; 31 | import android.util.Log; 32 | 33 | import com.danikula.videocache.HttpProxyCacheServer; 34 | import com.zy.bannermul.Banner; 35 | import com.zy.bannermul.BannerModel; 36 | import com.zy.bannermul.BannerMul; 37 | import com.zy.bannermul.BannerPage; 38 | import com.zy.bannermul.MyFileNameGenerator; 39 | 40 | import java.util.ArrayList; 41 | import java.util.List; 42 | 43 | public class MainActivity extends AppCompatActivity { 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_main); 49 | 50 | init(); 51 | } 52 | 53 | private void init(){ 54 | BannerMul bannermul = (BannerMul) findViewById(R.id.bannermul); 55 | 56 | List listbm = new ArrayList<>(); 57 | 58 | /** 59 | * mode 模式(1,2,3),可不传,默认是1; 60 | * // 1.一屏(data一个成员); 61 | * // 2.二屏(data二个成员); 62 | * // 3.三屏(data三个成员) 63 | * **/ 64 | BannerModel.mode = 2; 65 | 66 | BannerModel.setScreenPercent1(0.5f);//屏幕1占整个屏幕的高度的的百分比(大于1屏有效)可不传,默认0.5 67 | BannerModel.setScreenPercent2(0.5f);//屏幕2占整个屏幕的宽度的的百分比(大于2屏有效)可不传,默认0.5 68 | 69 | BannerModel bannerModel = new BannerModel(); 70 | bannerModel.index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 71 | List listAddress = new ArrayList<>(); 72 | BannerPage bannerPage1 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",2000); 73 | listAddress.add(bannerPage1); 74 | BannerPage bannerPage2 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",3000); 75 | listAddress.add(bannerPage2); 76 | BannerPage bannerPage3 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 77 | listAddress.add(bannerPage3); 78 | BannerPage bannerPage4 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 79 | listAddress.add(bannerPage4); 80 | bannerModel.list = listAddress; 81 | listbm.add(bannerModel); 82 | 83 | BannerModel bannerModel2 = new BannerModel(); 84 | bannerModel.index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 85 | List listAddress2 = new ArrayList<>(); 86 | BannerPage bannerPage21 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",1000); 87 | listAddress2.add(bannerPage21); 88 | BannerPage bannerPage22 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",2000); 89 | listAddress2.add(bannerPage22); 90 | BannerPage bannerPage23 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 91 | listAddress2.add(bannerPage23); 92 | BannerPage bannerPage24 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 93 | listAddress2.add(bannerPage24); 94 | bannerModel2.list = listAddress2; 95 | listbm.add(bannerModel2); 96 | 97 | bannermul.setDataList(listbm); 98 | 99 | 100 | Banner banner = (Banner) findViewById(R.id.banner); 101 | List listAddress3 = new ArrayList<>(); 102 | BannerPage bannerPage31 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_0df6e94a-73b9-4b4c-8b44-89bd74755943.jpg",1000); 103 | listAddress3.add(bannerPage31); 104 | BannerPage bannerPage32 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448009301.jpg",3000); 105 | listAddress3.add(bannerPage32); 106 | BannerPage bannerPage33 = new BannerPage("http://yyt.lexin580.com:8080/app_config/ztj08.mp4"); 107 | listAddress3.add(bannerPage33); 108 | BannerPage bannerPage34 = new BannerPage("http://static.lexin580.com/files/ProductPicture/150448004601_20180629_ad31512d-67c0-49a2-917e-71ff8d31b353.jpg",2000); 109 | listAddress3.add(bannerPage34); 110 | 111 | int index = 0;//插播地址,主要是插播时使用,可不传 默认是 0 112 | // banner.setDataList(listAddress3); 113 | // banner.setDataPlay(listAddress3); 114 | banner.setDataPlay(listAddress3,index); 115 | /*banner.setDataList(listAddress3,index); 116 | banner.startBanner(); 117 | banner.startAutoPlay();*/ 118 | } 119 | 120 | } 121 | 122 | ``` 123 | 124 | ### 欢迎交流 125 | 欢迎提问交流;若有bug,请添加bug截图或代码片段,以便更快更好的解决问题。
126 | 欢迎大家一起交流 127 | 128 | ### [我的博客](http://blog.sina.com.cn/s/articlelist_6078695441_0_1.html) 129 | 130 | -------------------------------------------------------------------------------- /BannerProj/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /BannerProj/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/BannerMul.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Color; 6 | import android.media.MediaPlayer; 7 | import android.net.Uri; 8 | import android.os.Build; 9 | import android.support.annotation.NonNull; 10 | import android.support.annotation.Nullable; 11 | import android.support.annotation.RequiresApi; 12 | import android.util.AttributeSet; 13 | import android.view.Gravity; 14 | import android.view.ViewGroup; 15 | import android.webkit.MimeTypeMap; 16 | import android.widget.ImageView; 17 | import android.widget.LinearLayout; 18 | import android.widget.Toast; 19 | 20 | import com.bumptech.glide.Glide; 21 | import com.bumptech.glide.request.RequestOptions; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class BannerMul extends LinearLayout { 27 | 28 | // private int mode = BannerModel.mode;//当前UI模式,默认是1 29 | private List dataList; 30 | 31 | public BannerMul(@NonNull Context context) 32 | { 33 | super(context); 34 | init(context,null,0); 35 | } 36 | 37 | public BannerMul(@NonNull Context context, @Nullable AttributeSet attrs) 38 | { 39 | super(context, attrs); 40 | init(context,attrs,0); 41 | 42 | } 43 | 44 | public BannerMul(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) 45 | { 46 | super(context, attrs, defStyleAttr); 47 | init(context,attrs,defStyleAttr); 48 | } 49 | 50 | /** 51 | * //@RequiresApi 52 | * **/ 53 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 54 | public BannerMul(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) 55 | { 56 | super(context, attrs, defStyleAttr, defStyleRes); 57 | init(context,attrs,defStyleAttr); 58 | } 59 | 60 | private void init(Context context,AttributeSet attrs,int defStyle){ 61 | if(true){ 62 | TypedArray a = context.getTheme().obtainStyledAttributes( 63 | attrs, R.styleable.BannerMul, defStyle, 0); 64 | 65 | BannerModel.mode = a.getInt(R.styleable.BannerMul_mode,BannerModel.mode); 66 | 67 | /*for (int i = 0; i < a.getIndexCount(); i++){ 68 | int attr = a.getIndex(i); 69 | switch (attr){ 70 | case R.styleable.BannerMul_mode: 71 | { 72 | mode = a.getInt(attr,1); 73 | } 74 | } 75 | }*/ 76 | 77 | a.recycle(); 78 | } 79 | } 80 | 81 | public void setDataList(List dataList){ 82 | setDataList(dataList,BannerModel.mode); 83 | } 84 | 85 | public void setDataList(List dataList,int mode){ 86 | this.removeAllViews(); 87 | 88 | BannerModel.mode = mode; 89 | if (dataList == null || dataList.size() == 0){ 90 | return; 91 | } 92 | 93 | LinearLayout.LayoutParams vp_param = new LinearLayout.LayoutParams( 94 | LayoutParams.MATCH_PARENT, 95 | LayoutParams.MATCH_PARENT,BannerModel.screenPercent1); 96 | vp_param.gravity = Gravity.CENTER; 97 | LinearLayout linearLayout1 = new LinearLayout(getContext()); 98 | linearLayout1.setLayoutParams(vp_param); 99 | linearLayout1.setOrientation(LinearLayout.HORIZONTAL); 100 | 101 | LinearLayout.LayoutParams vp_param0 = new LinearLayout.LayoutParams( 102 | LayoutParams.MATCH_PARENT, 103 | LayoutParams.MATCH_PARENT,BannerModel.screenPercent1); 104 | vp_param0.gravity = Gravity.CENTER; 105 | Banner banner1 = new Banner(getContext()); 106 | banner1.setLayoutParams(vp_param0); 107 | 108 | BannerModel bannerModel1 = dataList.get(0); 109 | bannerModel1.banner = banner1; 110 | 111 | linearLayout1.addView(banner1); 112 | 113 | this.addView(linearLayout1); 114 | 115 | if(BannerModel.mode > BannerModel.MONE_ONE){ 116 | 117 | vp_param.bottomMargin = 5; 118 | 119 | LinearLayout.LayoutParams vp_param2 = new LinearLayout.LayoutParams( 120 | LayoutParams.MATCH_PARENT, 121 | LayoutParams.MATCH_PARENT,BannerModel.SCREEN_PERCENT - BannerModel.screenPercent1); 122 | vp_param2.gravity = Gravity.CENTER; 123 | vp_param2.topMargin = 5; 124 | LinearLayout linearLayout2 = new LinearLayout(getContext()); 125 | linearLayout2.setLayoutParams(vp_param2); 126 | linearLayout2.setOrientation(LinearLayout.HORIZONTAL); 127 | 128 | LinearLayout.LayoutParams vp_param3 = new LinearLayout.LayoutParams( 129 | LayoutParams.MATCH_PARENT, 130 | LayoutParams.MATCH_PARENT,BannerModel.screenPercent2); 131 | Banner banner2 = new Banner(getContext()); 132 | banner2.setLayoutParams(vp_param3); 133 | 134 | BannerModel bannerModel2 = dataList.get(1); 135 | bannerModel2.banner = banner2; 136 | 137 | linearLayout2.addView(banner2); 138 | 139 | if(BannerModel.mode == BannerModel.MONE_THREE){ 140 | LinearLayout.LayoutParams vp_param4 = new LinearLayout.LayoutParams( 141 | LayoutParams.MATCH_PARENT, 142 | LayoutParams.MATCH_PARENT,BannerModel.SCREEN_PERCENT - BannerModel.screenPercent2); 143 | vp_param4.leftMargin = 10; 144 | Banner banner3 = new Banner(getContext()); 145 | banner3.setLayoutParams(vp_param4); 146 | 147 | BannerModel bannerModel3 = dataList.get(2); 148 | bannerModel3.banner = banner3; 149 | 150 | linearLayout2.addView(banner3); 151 | } 152 | 153 | this.addView(linearLayout2); 154 | } 155 | 156 | this.dataList = dataList; 157 | startBanner(); 158 | } 159 | 160 | private void startBanner(){ 161 | for(int i = 0; i < this.dataList.size() 162 | && i < BannerModel.mode; i++){ 163 | BannerModel bannerModel = this.dataList.get(i); 164 | if(bannerModel.banner != null){ 165 | bannerModel.banner.setDataList(bannerModel.list,bannerModel.index); 166 | //bannerModel.banner.setImgDelyed(bannerModel.imgDelyed); 167 | bannerModel.banner.setSlide(bannerModel.isSlide); 168 | bannerModel.banner.startBanner(); 169 | bannerModel.banner.startAutoPlay(); 170 | } 171 | } 172 | } 173 | 174 | public void destroy(){ 175 | for(int i = 0; i < this.dataList.size() && i < BannerModel.mode; i++){ 176 | BannerModel bannerModel = this.dataList.get(i); 177 | if(bannerModel.banner != null){ 178 | bannerModel.banner.destroy(); 179 | } 180 | } 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /BannerProj/bannermul/src/main/java/com/zy/bannermul/Banner.java: -------------------------------------------------------------------------------- 1 | package com.zy.bannermul; 2 | 3 | import android.content.Context; 4 | import android.media.MediaPlayer; 5 | import android.net.Uri; 6 | import android.os.Build; 7 | import android.os.Handler; 8 | import android.os.Message; 9 | import android.support.annotation.RequiresApi; 10 | import android.util.AttributeSet; 11 | import android.util.Log; 12 | import android.view.Gravity; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.webkit.MimeTypeMap; 16 | import android.widget.ImageView; 17 | import android.widget.LinearLayout; 18 | import android.widget.VideoView; 19 | 20 | import com.bumptech.glide.Glide; 21 | import com.bumptech.glide.request.RequestOptions; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * Created by steven on 2018/5/14. 28 | */ 29 | //public class Banner extends RelativeLayout 30 | public class Banner extends LinearLayout 31 | { 32 | private ViewPagerBanner viewPager; 33 | private final int UPTATE_VIEWPAGER = 100; 34 | //图片默认时间间隔 35 | private int imgDelyed = 2000; 36 | //每个位置默认时间间隔,因为有视频的原因 37 | private int delyedTime = 2000; 38 | //默认显示位置 39 | private int autoCurrIndex = 0; 40 | //是否自动播放 41 | private boolean isAutoPlay = false; 42 | private Time time; 43 | private List bannerModels; 44 | private List list; 45 | private List views; 46 | private BannerViewAdapter mAdapter; 47 | 48 | private List listBanner; 49 | 50 | public Banner(Context context) 51 | { 52 | super(context); 53 | init(context); 54 | } 55 | 56 | public Banner(Context context, AttributeSet attrs) 57 | { 58 | super(context, attrs); 59 | init(context); 60 | } 61 | 62 | public Banner(Context context, AttributeSet attrs, int defStyleAttr) 63 | { 64 | super(context, attrs, defStyleAttr); 65 | init(context); 66 | } 67 | 68 | /** 69 | * //@RequiresApi 70 | * **/ 71 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 72 | public Banner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) 73 | { 74 | super(context, attrs, defStyleAttr, defStyleRes); 75 | init(context); 76 | } 77 | 78 | private void init(Context context){ 79 | BannerModel.newProxy(context.getApplicationContext()); 80 | 81 | time = new Time(); 82 | LinearLayout.LayoutParams vp_param = new LinearLayout.LayoutParams( 83 | LayoutParams.MATCH_PARENT, 84 | LayoutParams.MATCH_PARENT); 85 | // vp_param.gravity = Gravity.CENTER; 86 | // vp_param.gravity = Gravity.BOTTOM | Gravity.START; 87 | 88 | // setLayoutParams(vp_param); 89 | 90 | viewPager = new ViewPagerBanner(getContext()); 91 | viewPager.setLayoutParams(vp_param); 92 | 93 | //viewPager.setBackgroundColor(Color.RED); 94 | this.addView(viewPager); 95 | } 96 | 97 | /** 98 | * 设置图片延迟时间 99 | * @param imgDelyed int;//时间(ms:单位毫秒) 100 | * **/ 101 | public void setImgDelyed(int imgDelyed){ 102 | this.imgDelyed = imgDelyed; 103 | } 104 | 105 | /** 106 | * 设置ViewPager是否可以滑动,默认false不可滑动 107 | * @param isSlide boolean;// 108 | * **/ 109 | public void setSlide(boolean isSlide){ 110 | viewPager.setSlide(isSlide); 111 | } 112 | 113 | /** 114 | * 获取delyedTime 115 | * @param position 当前位置 116 | */ 117 | private void getDelayedTime(int position){ 118 | View view1 = views.get(position); 119 | if (view1 instanceof VideoView){ 120 | VideoView videoView = (VideoView) view1; 121 | videoView.start(); 122 | videoView.seekTo(0); 123 | //videoView.suspend();//挂起视频文件的播放 124 | //videoView.resume ();//恢复挂起的播放器 125 | delyedTime = videoView.getDuration();//单位毫秒(ms) 126 | //delyedTime = videoView.getDuration() - videoView.getCurrentPosition();//单位毫秒(ms) 127 | time.getDelyedTime(videoView,runnable); 128 | } 129 | else 130 | { 131 | //delyedTime = imgDelyed; 132 | delyedTime = listBanner.get(position).imgDelyed;; 133 | } 134 | } 135 | 136 | /** 137 | * 设置滚动广告,图片,视频 138 | * **/ 139 | public void startBanner() { 140 | mAdapter = new BannerViewAdapter(views,getContext()); 141 | viewPager.setAdapter(mAdapter); 142 | viewPager.setOffscreenPageLimit(1);//参数1的含义就是,除去当前显示页面以外需要被预加载的页面数 143 | viewPager.setCurrentItem(autoCurrIndex,false);//跳转到指定页面 144 | viewPager.addOnPageChangeListener(new ViewPagerBanner.OnPageChangeListener() 145 | { 146 | @Override 147 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) 148 | { 149 | 150 | } 151 | 152 | @Override 153 | public void onPageSelected(int position) 154 | { 155 | Log.d("TAG","position:"+position); 156 | //当前位置 157 | autoCurrIndex = position; 158 | getDelayedTime(position); 159 | } 160 | 161 | @Override 162 | public void onPageScrollStateChanged(int state) 163 | { 164 | Log.d("TAG",""+state); 165 | 166 | //移除自动计时 167 | mHandler.removeCallbacks(runnable); 168 | 169 | //ViewPager跳转 170 | int pageIndex = autoCurrIndex; 171 | if(autoCurrIndex == 0){ 172 | pageIndex = views.size()-2; 173 | }else if(autoCurrIndex == views.size() - 1){ 174 | pageIndex = 1; 175 | } 176 | if (pageIndex != autoCurrIndex) { 177 | //无滑动动画,直接跳转 178 | viewPager.setCurrentItem(pageIndex, false); 179 | } 180 | 181 | //停止滑动时,重新自动倒计时 182 | if (state == 0 && isAutoPlay && views.size() > 1) 183 | { 184 | View view1 = views.get(pageIndex); 185 | 186 | if (view1 instanceof VideoView){ 187 | final VideoView videoView = (VideoView) view1; 188 | int current = videoView.getCurrentPosition();//获取到当前播放的时间位置 189 | int duration = videoView.getDuration(); 190 | delyedTime = duration - current; 191 | 192 | //某些时候,某些视频,获取的时间无效,就延时10秒,重新获取 193 | if (delyedTime <= 0) 194 | { 195 | time.getDelyedTime(videoView,runnable); 196 | mHandler.postDelayed(time,imgDelyed); 197 | } 198 | else 199 | { 200 | mHandler.postDelayed(runnable,delyedTime); 201 | } 202 | } 203 | else 204 | { 205 | //delyedTime = imgDelyed; 206 | delyedTime = listBanner.get(pageIndex).imgDelyed; 207 | mHandler.postDelayed(runnable,delyedTime); 208 | } 209 | Log.d("TAG","" + pageIndex + "--" + autoCurrIndex); 210 | } 211 | 212 | } 213 | }); 214 | } 215 | 216 | //开启自动循环 217 | public void startAutoPlay(){ 218 | isAutoPlay = true; 219 | if (views.size() > 1){ 220 | getDelayedTime(autoCurrIndex); 221 | if (delyedTime <= 0){ 222 | mHandler.postDelayed(time,imgDelyed); 223 | } 224 | else 225 | { 226 | mHandler.postDelayed(runnable,delyedTime); 227 | } 228 | } 229 | } 230 | 231 | /** 232 | * 发消息,进行循环 233 | */ 234 | private Runnable runnable = new Runnable() 235 | { 236 | @Override 237 | public void run() 238 | { 239 | mHandler.sendEmptyMessage(UPTATE_VIEWPAGER); 240 | } 241 | }; 242 | 243 | /** 244 | * 这个类,恩,获取视频长度,以及已经播放的时间 245 | */ 246 | private class Time implements Runnable{ 247 | 248 | private VideoView videoView; 249 | private Runnable runnable; 250 | 251 | public void getDelyedTime(VideoView videoView,Runnable runnable){ 252 | this.videoView = videoView; 253 | this.runnable = runnable; 254 | } 255 | @Override 256 | public void run() 257 | { 258 | int current = videoView.getCurrentPosition(); 259 | int duration = videoView.getDuration(); 260 | int delyedTime = duration - current; 261 | mHandler.postDelayed(runnable,delyedTime); 262 | } 263 | } 264 | 265 | //接受消息实现轮播 266 | private Handler mHandler = new Handler() { 267 | public void handleMessage(Message msg) { 268 | switch (msg.what) { 269 | case UPTATE_VIEWPAGER: 270 | viewPager.setCurrentItem(autoCurrIndex + 1,true); 271 | break; 272 | } 273 | } 274 | }; 275 | 276 | /* private class BannerModel{ 277 | public String url; 278 | public int playTime; 279 | public int type = 0; 280 | }*/ 281 | 282 | /** 283 | * @param dataList,//轮播数组 284 | * **/ 285 | //public void setDataList(List dataList){ 286 | public void setDataList(List dataList){ 287 | setDataList(dataList,-1); 288 | } 289 | 290 | /** 291 | * 设置数据 292 | * @param dataList,//轮播数组 293 | * @param index,//插播地址, -1时采用默认 294 | * **/ 295 | //public void setDataList(List dataList,int index){ 296 | public void setDataList(List dataList,int index){ 297 | listBanner = new ArrayList<>(); 298 | 299 | if(index != -1){ 300 | autoCurrIndex = index; 301 | } 302 | 303 | if (dataList == null){ 304 | dataList = new ArrayList<>(); 305 | } 306 | //用于显示的数组 307 | if (views == null) 308 | { 309 | views = new ArrayList<>(); 310 | }else { 311 | views.clear(); 312 | } 313 | 314 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( 315 | ViewGroup.LayoutParams.WRAP_CONTENT,//ViewGroup.LayoutParams.MATCH_PARENT, 316 | ViewGroup.LayoutParams.WRAP_CONTENT); 317 | lp.gravity = Gravity.CENTER; 318 | RequestOptions options = new RequestOptions(); 319 | options.centerCrop(); 320 | //数据大于一条,才可以循环 321 | if (dataList.size() > 1) 322 | { 323 | autoCurrIndex = 1; 324 | //循环数组,将首尾各加一条数据 325 | for (int i = 0; i < dataList.size() + 2; i++) 326 | //for (int i = 0; i < dataList.size(); i++) 327 | { 328 | 329 | //String url; 330 | BannerPage bannerPage; 331 | if (i == 0) 332 | { 333 | //url = dataList.get(dataList.size() - 1); 334 | bannerPage = dataList.get(dataList.size() - 1); 335 | } 336 | else if (i == dataList.size() + 1) 337 | { 338 | // url = dataList.get(0); 339 | bannerPage = dataList.get(0); 340 | } 341 | else 342 | { 343 | //url = dataList.get(i - 1); 344 | bannerPage = dataList.get(i - 1); 345 | } 346 | 347 | listBanner.add(bannerPage); 348 | 349 | if (MimeTypeMap.getFileExtensionFromUrl(bannerPage.url).equals("mp4")) 350 | { 351 | MVideoView videoView = new MVideoView(getContext()); 352 | 353 | /* videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 354 | { 355 | @Override 356 | public void onPrepared(MediaPlayer mp) 357 | { 358 | mp.pause(); 359 | //TODO 360 | } 361 | });*/ 362 | //监听视频播放完的代码 363 | /* videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 364 | 365 | @Override 366 | public void onCompletion(MediaPlayer mPlayer) { 367 | *//* mPlayer.start(); 368 | mPlayer.setLooping(true);*//* 369 | mPlayer.pause(); 370 | } 371 | });*/ 372 | 373 | videoView.setLayoutParams(lp); 374 | String s = BannerModel.getProxyUrl(bannerPage.url); 375 | videoView.setVideoURI(Uri.parse(BannerModel.getProxyUrl(bannerPage.url))); 376 | //videoView.start(); 377 | 378 | views.add(videoView); 379 | } 380 | else 381 | { 382 | ImageView imageView = new ImageView(getContext()); 383 | imageView.setLayoutParams(lp); 384 | // imageView.setScaleType(ImageView.ScaleType.FIT_XY); 385 | imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 386 | Glide.with(getContext()).load(bannerPage.url).apply(options).into(imageView); 387 | views.add(imageView); 388 | } 389 | } 390 | } 391 | else if (dataList.size() == 1){ 392 | autoCurrIndex = 0; 393 | //String url = dataList.get(0); 394 | BannerPage bannerPage = dataList.get(0); 395 | listBanner.add(bannerPage); 396 | 397 | if (MimeTypeMap.getFileExtensionFromUrl(bannerPage.url).equals("mp4")) 398 | { 399 | MVideoView videoView = new MVideoView(getContext()); 400 | videoView.setLayoutParams(lp); 401 | videoView.setVideoURI(Uri.parse(BannerModel.getProxyUrl(bannerPage.url))); 402 | // videoView.start(); 403 | //监听视频播放完的代码 404 | videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 405 | 406 | @Override 407 | public void onCompletion(MediaPlayer mPlayer) { 408 | mPlayer.start(); 409 | mPlayer.setLooping(true); 410 | } 411 | }); 412 | views.add(videoView); 413 | } 414 | else 415 | { 416 | ImageView imageView = new ImageView(getContext()); 417 | imageView.setLayoutParams(lp); 418 | // imageView.setScaleType(ImageView.ScaleType.FIT_XY); 419 | //imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 420 | imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); 421 | Glide.with(getContext()).load(bannerPage.url).apply(options).into(imageView); 422 | views.add(imageView); 423 | } 424 | } 425 | else 426 | { 427 | views.add(new LinearLayout(getContext())); 428 | } 429 | 430 | //List l = listBanner; 431 | } 432 | 433 | 434 | /** 435 | * 设置数据并播放 436 | * @param dataList,//轮播数组 437 | * **/ 438 | public void setDataPlay(List dataList){ 439 | setDataPlay(dataList,-1); 440 | } 441 | 442 | /** 443 | * 设置数据并播放 444 | * @param dataList,//轮播数组 445 | * @param index,//插播地址, -1时采用默认 446 | * **/ 447 | public void setDataPlay(List dataList,int index){ 448 | setDataList(dataList,index); 449 | startBanner(); 450 | startAutoPlay(); 451 | } 452 | 453 | /** 454 | * @param list,//轮播数组 455 | * @param index,//插播地址, -1时采用默认 456 | * **/ 457 | //public void dataChange(List list,int index){ 458 | public void dataChange(List list,int index){ 459 | if (list != null && list.size()>0) 460 | { 461 | if(index != -1){ 462 | autoCurrIndex = index; 463 | } 464 | //改变资源时要重新开启循环,否则会把视频的时长赋给图片,或者相反 465 | //因为delyedTime也要改变,所以要重新获取delyedTime 466 | mHandler.removeCallbacks(runnable); 467 | setDataList(list); 468 | mAdapter.setDataList(views,getContext()); 469 | mAdapter.notifyDataSetChanged(); 470 | viewPager.setCurrentItem(autoCurrIndex,false); 471 | //开启循环 472 | if (isAutoPlay && views.size() > 1){ 473 | getDelayedTime(autoCurrIndex); 474 | if (delyedTime <= 0){ 475 | mHandler.postDelayed(time,imgDelyed); 476 | }else { 477 | mHandler.postDelayed(runnable,delyedTime); 478 | } 479 | } 480 | } 481 | } 482 | 483 | public void destroy(){ 484 | //说当参数为null时,删除所有回调函数和message 485 | // 这样做的好处是在Acticity退出的时候,可以避免内存泄露 486 | mHandler.removeCallbacksAndMessages(null); 487 | mHandler = null; 488 | time = null; 489 | runnable = null; 490 | views.clear(); 491 | views = null; 492 | viewPager = null; 493 | mAdapter = null; 494 | } 495 | 496 | } 497 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 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 | banner 62 | 63 | 64 | 65 | 67 | 68 | 73 | 74 | 75 | 76 | 77 | true 78 | DEFINITION_ORDER 79 | 80 | 81 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 |