├── .gitignore ├── README.md ├── build.gradle ├── demo ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── bingoogolapple │ │ └── bgabanner │ │ └── demo │ │ ├── App.java │ │ ├── engine │ │ └── Engine.java │ │ ├── model │ │ ├── BannerModel.java │ │ └── RefreshModel.java │ │ └── ui │ │ └── activity │ │ ├── FrescoDemoActivity.java │ │ ├── GuideActivity.java │ │ ├── ListViewDemoActivity.java │ │ ├── MainActivity.java │ │ └── RecyclerViewDemoActivity.java │ └── res │ ├── drawable-hdpi │ ├── holder.png │ ├── ic_launcher.png │ ├── point_focused.png │ ├── point_focused_big.png │ ├── point_unfocused.png │ └── point_unfocused_small.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ ├── ic_launcher.png │ ├── uoko_guide_background_1.png │ ├── uoko_guide_background_2.png │ ├── uoko_guide_background_3.png │ ├── uoko_guide_foreground_1.png │ ├── uoko_guide_foreground_2.png │ └── uoko_guide_foreground_3.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── drawable │ ├── selector_banner_point.xml │ ├── selector_banner_unequal.xml │ ├── selector_btn_test.xml │ └── shape_number_indicator_background.xml │ ├── layout │ ├── activity_fresco_demo.xml │ ├── activity_guide.xml │ ├── activity_listview_demo.xml │ ├── activity_main.xml │ ├── activity_recyclerview_demo.xml │ ├── item_fresco.xml │ ├── item_normal.xml │ └── layout_header.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── styles_base.xml │ └── xml │ └── network_security_config.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── build.gradle ├── consumer-proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── bingoogolapple │ │ └── bgabanner │ │ ├── BGABanner.java │ │ ├── BGABannerScroller.java │ │ ├── BGABannerUtil.java │ │ ├── BGAGuideLinkageLayout.java │ │ ├── BGALocalImageSize.java │ │ ├── BGAOnNoDoubleClickListener.java │ │ ├── BGAViewPager.java │ │ └── transformer │ │ ├── AccordionPageTransformer.java │ │ ├── AlphaPageTransformer.java │ │ ├── BGAPageTransformer.java │ │ ├── CubePageTransformer.java │ │ ├── DefaultPageTransformer.java │ │ ├── DepthPageTransformer.java │ │ ├── FadePageTransformer.java │ │ ├── FlipPageTransformer.java │ │ ├── RotatePageTransformer.java │ │ ├── StackPageTransformer.java │ │ ├── TransitionEffect.java │ │ ├── ZoomCenterPageTransformer.java │ │ ├── ZoomFadePageTransformer.java │ │ ├── ZoomPageTransformer.java │ │ └── ZoomStackPageTransformer.java │ └── res │ ├── drawable-xhdpi │ ├── bga_banner_point_disabled.png │ └── bga_banner_point_enabled.png │ ├── drawable │ ├── bga_banner_selector_point_hollow.xml │ └── bga_banner_selector_point_solid.xml │ ├── layout │ └── bga_banner_item_image.xml │ └── values │ ├── attrs.xml │ └── ids.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Eclipse project files 30 | .classpath 31 | .project 32 | .settings/ 33 | 34 | # Intellij project files 35 | *.iml 36 | *.ipr 37 | *.iws 38 | .idea/ 39 | 40 | # Mac system files 41 | .DS_Store 42 | 43 | *.keystore 44 | 45 | captures -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :running:BGABanner-Android:running: 2 | ============ 3 | 4 | ## 目录 5 | 6 | * [功能介绍](#功能介绍) 7 | * [效果图与示例 apk](#效果图与示例-apk) 8 | * [常见问题](#常见问题) 9 | * [使用](#使用) 10 | * [自定义属性说明](#自定义属性说明) 11 | * [关于我](#关于我) 12 | * [打赏支持](#打赏支持) 13 | * [License](#license) 14 | 15 | ## 功能介绍 16 | 17 | - [x] 引导界面导航效果 18 | - [x] 支持根据服务端返回的数据动态设置广告条的总页数 19 | - [x] 支持大于等于1页时的无限循环自动轮播、手指按下暂停轮播、抬起手指开始轮播 20 | - [x] 支持自定义指示器位置和广告文案位置 21 | - [x] 支持图片指示器和数字指示器 22 | - [x] 支持 ViewPager 各种切换动画 23 | - [x] 支持选中特定页面 24 | - [x] 支持监听 item 点击事件 25 | - [x] 加载网络数据时支持占位图设置,避免出现整个广告条空白的情况 26 | - [x] 多个 ViewPager 跟随滚动 27 | 28 | ## 效果图与示例 apk 29 | 30 | ![banner](https://cloud.githubusercontent.com/assets/8949716/17557718/dc235ec4-5f4a-11e6-92b7-144a2a1a1e3f.gif) 31 | 32 | [点击下载 BGABannerDemo.apk](http://fir.im/BGABannerDemo) 或扫描下面的二维码安装 33 | 34 | ![BGABannerDemo apk文件二维](http://bgashare.bingoogolapple.cn/banner/BGABannerDemo.png) 35 | 36 | ## 常见问题 37 | 38 | 1. 结合 Fresco 加载图片请参考 [FrescoDemoActivity](https://github.com/bingoogolapple/BGABanner-Android/blob/master/demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/FrescoDemoActivity.java) 39 | 2. 自定义 item 布局文件请参考 [FrescoDemoActivity](https://github.com/bingoogolapple/BGABanner-Android/blob/master/demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/FrescoDemoActivity.java) 40 | 41 | ## 使用 42 | 43 | ### 1.添加 Gradle 依赖 44 | 45 | * 把 `maven { url 'https://jitpack.io' }` 添加到 root build.gradle 的 repositories 中 46 | * 在 app build.gradle 中添加如下依赖,末尾的「latestVersion」指的是徽章 [![](https://jitpack.io/v/bingoogolapple/BGABanner-Android.svg)](https://jitpack.io/#bingoogolapple/BGABanner-Android) 里的版本名称,请自行替换 47 | 48 | ```groovy 49 | implementation 'androidx.legacy:legacy-support-v4:latestVersion' 50 | implementation 'com.github.bingoogolapple:BGABanner-Android:latestVersion' 51 | ``` 52 | 53 | ### 2.在布局文件中添加 BGABanner 54 | 55 | ```xml 56 | 65 | ``` 66 | 67 | ### 3.在 Activity 或者 Fragment 中配置 BGABanner 的数据源 68 | 69 | 有多种配置数据源的方式,这里仅列出三种方式。更多初始化方式请查看 [demo](https://github.com/bingoogolapple/BGABanner-Android/tree/master/demo) 70 | 71 | >配置数据源的方式1:通过传入数据模型并结合 Adapter 的方式配置数据源。这种方式主要用于加载网络图片,以及实现少于3页时的无限轮播 72 | 73 | ```java 74 | mContentBanner.setAdapter(new BGABanner.Adapter() { 75 | @Override 76 | public void fillBannerItem(BGABanner banner, ImageView itemView, String model, int position) { 77 | Glide.with(MainActivity.this) 78 | .load(model) 79 | .placeholder(R.drawable.holder) 80 | .error(R.drawable.holder) 81 | .centerCrop() 82 | .dontAnimate() 83 | .into(itemView); 84 | } 85 | }); 86 | 87 | mContentBanner.setData(Arrays.asList("网络图片路径1", "网络图片路径2", "网络图片路径3"), Arrays.asList("提示文字1", "提示文字2", "提示文字3")); 88 | ``` 89 | 90 | > 配置数据源的方式2:通过直接传入视图集合的方式配置数据源,主要用于自定义引导页每个页面布局的情况 91 | 92 | ```java 93 | List views = new ArrayList<>(); 94 | views.add(View.inflate(context, R.layout.layout_guide_one, null)); 95 | views.add(View.inflate(context, R.layout.layout_guide_two, null)); 96 | views.add(View.inflate(context, R.layout.layout_guide_three, null)); 97 | mContentBanner.setData(views); 98 | ``` 99 | 100 | > 配置数据源的方式3:通过传入图片资源 id 的方式配置数据源,主要用于引导页每一页都是只显示图片的情况 101 | 102 | ``` 103 | // Bitmap 的宽高在 maxWidth maxHeight 和 minWidth minHeight 之间 104 | BGALocalImageSize localImageSize = new BGALocalImageSize(720, 1280, 320, 640); 105 | // 设置数据源 106 | mContentBanner.setData(localImageSize, ImageView.ScaleType.CENTER_CROP, 107 | R.drawable.uoko_guide_background_1, 108 | R.drawable.uoko_guide_background_2, 109 | R.drawable.uoko_guide_background_3); 110 | ``` 111 | 112 | ### 4.监听广告 item 的单击事件,在 BGABanner 里已经帮开发者处理了防止重复点击事件 113 | 114 | ```java 115 | mContentBanner.setDelegate(new BGABanner.Delegate() { 116 | @Override 117 | public void onBannerItemClick(BGABanner banner, ImageView itemView, String model, int position) { 118 | Toast.makeText(banner.getContext(), "点击了" + position, Toast.LENGTH_SHORT).show(); 119 | } 120 | }); 121 | ``` 122 | 123 | ### 5.设置「进入按钮」和「跳过按钮」控件资源 id 及其点击事件,如果进入按钮和跳过按钮有一个不存在的话就传 0,在 BGABanner 里已经帮开发者处理了防止重复点击事件,在 BGABanner 里已经帮开发者处理了「跳过按钮」和「进入按钮」的显示与隐藏 124 | 125 | ```java 126 | mContentBanner.setEnterSkipViewIdAndDelegate(R.id.btn_guide_enter, R.id.tv_guide_skip, new BGABanner.GuideDelegate() { 127 | @Override 128 | public void onClickEnterOrSkip() { 129 | startActivity(new Intent(GuideActivity.this, MainActivity.class)); 130 | finish(); 131 | } 132 | }); 133 | ``` 134 | 135 | ## 自定义属性说明 136 | ```xml 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | ``` 202 | 203 | ## 代码是最好的老师,更多详细用法请查看 [demo](https://github.com/bingoogolapple/BGABanner-Android/tree/master/demo):feet: 204 | 205 | ## 作者联系方式 206 | 207 | | 个人主页 | 邮箱 | 208 | | ------------- | ------------ | 209 | | bingoogolapple.cn | bingoogolapple@gmail.com | 210 | 211 | | 个人微信号 | 微信群 | 公众号 | 212 | | ------------ | ------------ | ------------ | 213 | | 个人微信号 | 微信群 | 公众号 | 214 | 215 | | 个人 QQ 号 | QQ 群 | 216 | | ------------ | ------------ | 217 | | 个人 QQ 号 | QQ 群 | 218 | 219 | ## 打赏支持作者 220 | 221 | 如果您觉得 BGA 系列开源库或工具软件帮您节省了大量的开发时间,可以扫描下方的二维码打赏支持。您的支持将鼓励我继续创作,打赏后还可以加我微信免费开通一年 [上帝小助手浏览器扩展/插件开发平台](https://github.com/bingoogolapple/bga-god-assistant-config) 的会员服务 222 | 223 | | 微信 | QQ | 支付宝 | 224 | | ------------- | ------------- | ------------- | 225 | | 微信 | QQ | 支付宝 | 226 | 227 | ## 作者项目推荐 228 | 229 | * 欢迎您使用我开发的第一个独立开发软件产品 [上帝小助手浏览器扩展/插件开发平台](https://github.com/bingoogolapple/bga-god-assistant-config) 230 | 231 | ## License 232 | 233 | Copyright 2015 bingoogolapple 234 | 235 | Licensed under the Apache License, Version 2.0 (the "License"); 236 | you may not use this file except in compliance with the License. 237 | You may obtain a copy of the License at 238 | 239 | http://www.apache.org/licenses/LICENSE-2.0 240 | 241 | Unless required by applicable law or agreed to in writing, software 242 | distributed under the License is distributed on an "AS IS" BASIS, 243 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 244 | See the License for the specific language governing permissions and 245 | limitations under the License. 246 | -------------------------------------------------------------------------------- /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 | google() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.4' 10 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | maven { url 'https://jitpack.io' } 17 | jcenter() 18 | google() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion ANDROID_BUILD_SDK_VERSION as int 5 | 6 | defaultConfig { 7 | minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION as int 8 | targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION as int 9 | versionCode VERSION_CODE as int 10 | versionName VERSION_NAME 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled true 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | dataBinding { 21 | enabled = true 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation project(':library') 27 | 28 | // -------------------- 以下两个库是必须依赖的 ---------------------------- 29 | // implementation 'com.github.bingoogolapple:BGABanner-Android:3.0.1' 30 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 31 | // -------------------- 以上两个库是必须依赖的 ---------------------------- 32 | 33 | // 以下几个库是演示案例所使用到的 34 | implementation 'androidx.appcompat:appcompat:1.1.0' 35 | implementation 'androidx.recyclerview:recyclerview:1.0.0' 36 | implementation 'androidx.cardview:cardview:1.0.0' 37 | implementation 'com.github.bumptech.glide:glide:4.7.1' 38 | implementation 'com.squareup.retrofit2:retrofit:2.4.0' 39 | implementation 'com.squareup.retrofit2:converter-gson:2.4.0' 40 | implementation 'com.github.bingoogolapple:BGABaseAdapter-Android:2.0.1' 41 | 42 | implementation 'com.facebook.fresco:fresco:2.0.0' 43 | } -------------------------------------------------------------------------------- /demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | ## ---------------------------------- 2 | ## Okio 相关 3 | ## ---------------------------------- 4 | -keep class sun.misc.Unsafe { *; } 5 | -dontwarn java.nio.file.* 6 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 7 | -dontwarn okio.** 8 | 9 | ## ---------------------------------- 10 | ## Retrofit 2.X 相关 11 | ## ---------------------------------- 12 | -dontwarn retrofit2.** 13 | -keep class retrofit2.** { *; } 14 | -keepattributes Signature 15 | -keepattributes Exceptions 16 | 17 | -keepclasseswithmembers class * { 18 | @retrofit2.http.* ; 19 | } 20 | 21 | ## ---------------------------------- 22 | ## RxJava 1.X 相关 23 | ## ---------------------------------- 24 | -dontwarn sun.misc.** 25 | 26 | -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { 27 | long producerIndex; 28 | long consumerIndex; 29 | } 30 | 31 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { 32 | rx.internal.util.atomic.LinkedQueueNode producerNode; 33 | } 34 | 35 | -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { 36 | rx.internal.util.atomic.LinkedQueueNode consumerNode; 37 | } 38 | 39 | ## ---------------------------------- 40 | ## Glide 相关 41 | ## ---------------------------------- 42 | -keep class com.bumptech.glide.Glide { *; } 43 | -keep public class * implements com.bumptech.glide.module.GlideModule 44 | -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { 45 | **[] $VALUES; 46 | public *; 47 | } 48 | -dontwarn com.bumptech.glide.** 49 | 50 | ## ---------------------------------- 51 | ## Fresco 相关 52 | ## ---------------------------------- 53 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 54 | 55 | # Do not strip any method/class that is annotated with @DoNotStrip 56 | -keep @com.facebook.common.internal.DoNotStrip class * 57 | -keepclassmembers class * { 58 | @com.facebook.common.internal.DoNotStrip *; 59 | } 60 | 61 | # Keep native methods 62 | -keepclassmembers class * { 63 | native ; 64 | } 65 | 66 | -dontwarn okio.** 67 | -dontwarn javax.annotation.** 68 | -dontwarn com.android.volley.toolbox.** 69 | 70 | ## ---------------------------------- 71 | ## DataBinding 相关 72 | ## ---------------------------------- 73 | -keepclasseswithmembers class * extends android.databinding.ViewDataBinding{ 74 | ; 75 | } 76 | 77 | ## ---------------------------------- 78 | ## 配置不混淆 Demo 里的 Model 79 | ## ---------------------------------- 80 | -keep class cn.bingoogolapple.bgabanner.demo.model.**{*;} -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/App.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | 7 | import cn.bingoogolapple.bgabanner.demo.engine.Engine; 8 | import retrofit2.Retrofit; 9 | import retrofit2.converter.gson.GsonConverterFactory; 10 | 11 | /** 12 | * 作者:王浩 邮件:bingoogolapple@gmail.com 13 | * 创建时间:15/6/21 下午10:13 14 | * 描述: 15 | */ 16 | public class App extends Application { 17 | private static App sInstance; 18 | private Engine mEngine; 19 | 20 | @Override 21 | public void onCreate() { 22 | super.onCreate(); 23 | 24 | sInstance = this; 25 | mEngine = new Retrofit.Builder() 26 | .baseUrl("http://bgashare.bingoogolapple.cn/banner/api/") 27 | .addConverterFactory(GsonConverterFactory.create()) 28 | .build().create(Engine.class); 29 | 30 | Fresco.initialize(this); 31 | } 32 | 33 | 34 | public static App getInstance() { 35 | return sInstance; 36 | } 37 | 38 | public Engine getEngine() { 39 | return mEngine; 40 | } 41 | } -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/engine/Engine.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.engine; 2 | 3 | import java.util.List; 4 | 5 | import cn.bingoogolapple.bgabanner.demo.model.BannerModel; 6 | import cn.bingoogolapple.bgabanner.demo.model.RefreshModel; 7 | import retrofit2.Call; 8 | import retrofit2.http.GET; 9 | import retrofit2.http.Path; 10 | import retrofit2.http.Url; 11 | 12 | 13 | /** 14 | * 作者:王浩 邮件:bingoogolapple@gmail.com 15 | * 创建时间:15/9/17 下午12:44 16 | * 描述: 17 | */ 18 | public interface Engine { 19 | 20 | @GET("{itemCount}item.json") 21 | Call fetchItemsWithItemCount(@Path("itemCount") int itemCount); 22 | 23 | @GET 24 | Call> loadContentData(@Url String url); 25 | } -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/model/BannerModel.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 作者:王浩 邮件:bingoogolapple@gmail.com 7 | * 创建时间:15/6/21 下午11:16 8 | * 描述: 9 | */ 10 | public class BannerModel { 11 | public List imgs; 12 | public List tips; 13 | } -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/model/RefreshModel.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.model; 2 | 3 | /** 4 | * 作者:王浩 邮件:bingoogolapple@gmail.com 5 | * 创建时间:15/5/21 14:53 6 | * 描述: 7 | */ 8 | public class RefreshModel { 9 | public String title; 10 | public String detail; 11 | 12 | public RefreshModel() { 13 | } 14 | 15 | public RefreshModel(String title, String detail) { 16 | this.title = title; 17 | this.detail = detail; 18 | } 19 | } -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/FrescoDemoActivity.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.ui.activity; 2 | 3 | import android.net.Uri; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import androidx.cardview.widget.CardView; 8 | import android.widget.Toast; 9 | 10 | import com.facebook.drawee.view.SimpleDraweeView; 11 | 12 | import cn.bingoogolapple.bgabanner.BGABanner; 13 | import cn.bingoogolapple.bgabanner.demo.App; 14 | import cn.bingoogolapple.bgabanner.demo.R; 15 | import cn.bingoogolapple.bgabanner.demo.model.BannerModel; 16 | import retrofit2.Call; 17 | import retrofit2.Callback; 18 | import retrofit2.Response; 19 | 20 | /** 21 | * 作者:王浩 邮件:bingoogolapple@gmail.com 22 | * 创建时间:16/12/12 下午10:37 23 | * 描述: 24 | */ 25 | public class FrescoDemoActivity extends AppCompatActivity { 26 | private BGABanner mContentBanner; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_fresco_demo); 32 | setTitle("FrescoDemo"); 33 | 34 | mContentBanner = findViewById(R.id.banner_fresco_demo_content); 35 | mContentBanner.setDelegate(new BGABanner.Delegate() { 36 | @Override 37 | public void onBannerItemClick(BGABanner banner, CardView itemView, String model, int position) { 38 | Toast.makeText(banner.getContext(), "点击了第" + (position + 1) + "页", Toast.LENGTH_SHORT).show(); 39 | } 40 | }); 41 | mContentBanner.setAdapter(new BGABanner.Adapter() { 42 | @Override 43 | public void fillBannerItem(BGABanner banner, CardView itemView, String model, int position) { 44 | SimpleDraweeView simpleDraweeView = itemView.findViewById(R.id.sdv_item_fresco_content); 45 | simpleDraweeView.setImageURI(Uri.parse(model)); 46 | } 47 | }); 48 | 49 | App.getInstance().getEngine().fetchItemsWithItemCount(5).enqueue(new Callback() { 50 | @Override 51 | public void onResponse(Call call, Response response) { 52 | BannerModel bannerModel = response.body(); 53 | // mContentBanner.setData(R.layout.item_fresco, bannerModel.imgs, bannerModel.tips); 54 | mContentBanner.setData(R.layout.item_fresco, bannerModel.imgs, null); 55 | } 56 | 57 | @Override 58 | public void onFailure(Call call, Throwable t) { 59 | Toast.makeText(App.getInstance(), "网络数据加载失败", Toast.LENGTH_SHORT).show(); 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/GuideActivity.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.ui.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.widget.ImageView; 7 | 8 | import cn.bingoogolapple.bgabanner.BGABanner; 9 | import cn.bingoogolapple.bgabanner.BGALocalImageSize; 10 | import cn.bingoogolapple.bgabanner.demo.R; 11 | 12 | public class GuideActivity extends Activity { 13 | private static final String TAG = GuideActivity.class.getSimpleName(); 14 | private BGABanner mBackgroundBanner; 15 | private BGABanner mForegroundBanner; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | 21 | initView(); 22 | setListener(); 23 | processLogic(); 24 | } 25 | 26 | private void initView() { 27 | setContentView(R.layout.activity_guide); 28 | mBackgroundBanner = findViewById(R.id.banner_guide_background); 29 | mForegroundBanner = findViewById(R.id.banner_guide_foreground); 30 | } 31 | 32 | private void setListener() { 33 | /** 34 | * 设置进入按钮和跳过按钮控件资源 id 及其点击事件 35 | * 如果进入按钮和跳过按钮有一个不存在的话就传 0 36 | * 在 BGABanner 里已经帮开发者处理了防止重复点击事件 37 | * 在 BGABanner 里已经帮开发者处理了「跳过按钮」和「进入按钮」的显示与隐藏 38 | */ 39 | mForegroundBanner.setEnterSkipViewIdAndDelegate(R.id.btn_guide_enter, R.id.tv_guide_skip, new BGABanner.GuideDelegate() { 40 | @Override 41 | public void onClickEnterOrSkip() { 42 | startActivity(new Intent(GuideActivity.this, MainActivity.class)); 43 | finish(); 44 | } 45 | }); 46 | } 47 | 48 | private void processLogic() { 49 | // Bitmap 的宽高在 maxWidth maxHeight 和 minWidth minHeight 之间 50 | BGALocalImageSize localImageSize = new BGALocalImageSize(720, 1280, 320, 640); 51 | // 设置数据源 52 | mBackgroundBanner.setData(localImageSize, ImageView.ScaleType.CENTER_CROP, 53 | R.drawable.uoko_guide_background_1, 54 | R.drawable.uoko_guide_background_2, 55 | R.drawable.uoko_guide_background_3); 56 | 57 | mForegroundBanner.setData(localImageSize, ImageView.ScaleType.CENTER_CROP, 58 | R.drawable.uoko_guide_foreground_1, 59 | R.drawable.uoko_guide_foreground_2, 60 | R.drawable.uoko_guide_foreground_3); 61 | } 62 | 63 | @Override 64 | protected void onResume() { 65 | super.onResume(); 66 | 67 | // 如果开发者的引导页主题是透明的,需要在界面可见时给背景 Banner 设置一个白色背景,避免滑动过程中两个 Banner 都设置透明度后能看到 Launcher 68 | mBackgroundBanner.setBackgroundResource(android.R.color.white); 69 | } 70 | } -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/ListViewDemoActivity.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.ui.activity; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.ImageView; 7 | import android.widget.ListView; 8 | import android.widget.Toast; 9 | 10 | import com.bumptech.glide.Glide; 11 | import com.bumptech.glide.request.RequestOptions; 12 | 13 | import java.util.List; 14 | 15 | import androidx.appcompat.app.AppCompatActivity; 16 | import cn.bingoogolapple.baseadapter.BGAAdapterViewAdapter; 17 | import cn.bingoogolapple.baseadapter.BGAViewHolderHelper; 18 | import cn.bingoogolapple.bgabanner.BGABanner; 19 | import cn.bingoogolapple.bgabanner.demo.App; 20 | import cn.bingoogolapple.bgabanner.demo.R; 21 | import cn.bingoogolapple.bgabanner.demo.engine.Engine; 22 | import cn.bingoogolapple.bgabanner.demo.model.BannerModel; 23 | import cn.bingoogolapple.bgabanner.demo.model.RefreshModel; 24 | import retrofit2.Call; 25 | import retrofit2.Callback; 26 | import retrofit2.Response; 27 | 28 | /** 29 | * 作者:王浩 邮件:bingoogolapple@gmail.com 30 | * 创建时间:16/7/21 下午8:26 31 | * 描述: 32 | */ 33 | public class ListViewDemoActivity extends AppCompatActivity implements BGABanner.Adapter, BGABanner.Delegate { 34 | private ListView mContentLv; 35 | private BGABanner mBanner; 36 | private ContentAdapter mContentAdapter; 37 | 38 | private Engine mEngine; 39 | 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.activity_listview_demo); 44 | mContentLv = findViewById(R.id.lv_content); 45 | 46 | setTitle("ListViewDemo"); 47 | mEngine = App.getInstance().getEngine(); 48 | 49 | initListView(); 50 | 51 | 52 | loadBannerData(); 53 | loadContentData(); 54 | } 55 | 56 | /** 57 | * 初始化ListView 58 | */ 59 | private void initListView() { 60 | // 初始化HeaderView 61 | View headerView = View.inflate(this, R.layout.layout_header, null); 62 | mBanner = headerView.findViewById(R.id.banner); 63 | mBanner.setAdapter(this); 64 | mBanner.setDelegate(this); 65 | 66 | // 初始化ListView 67 | mContentLv.addHeaderView(headerView); 68 | mContentAdapter = new ContentAdapter(this); 69 | mContentLv.setAdapter(mContentAdapter); 70 | } 71 | 72 | @Override 73 | public void fillBannerItem(BGABanner banner, ImageView itemView, String model, int position) { 74 | Glide.with(this) 75 | .load(model) 76 | .apply(new RequestOptions().placeholder(R.drawable.holder).error(R.drawable.holder).dontAnimate().centerCrop()) 77 | .into(itemView); 78 | } 79 | 80 | @Override 81 | public void onBannerItemClick(BGABanner banner, ImageView imageView, String model, int position) { 82 | Toast.makeText(this, "点击了第" + (position + 1) + "页", Toast.LENGTH_SHORT).show(); 83 | } 84 | 85 | /** 86 | * 加载头部广告条的数据 87 | */ 88 | private void loadBannerData() { 89 | mEngine.fetchItemsWithItemCount(5).enqueue(new Callback() { 90 | @Override 91 | public void onResponse(Call call, Response response) { 92 | BannerModel bannerModel = response.body(); 93 | mBanner.setData(bannerModel.imgs, bannerModel.tips); 94 | } 95 | 96 | @Override 97 | public void onFailure(Call call, Throwable t) { 98 | Toast.makeText(App.getInstance(), "加载广告条数据失败", Toast.LENGTH_SHORT).show(); 99 | } 100 | }); 101 | } 102 | 103 | /** 104 | * 加载内容列表数据 105 | */ 106 | private void loadContentData() { 107 | mEngine.loadContentData("http://bgashare.bingoogolapple.cn/refreshlayout/api/defaultdata.json").enqueue(new Callback>() { 108 | @Override 109 | public void onResponse(Call> call, Response> response) { 110 | mContentAdapter.setData(response.body()); 111 | } 112 | 113 | @Override 114 | public void onFailure(Call> call, Throwable t) { 115 | Toast.makeText(App.getInstance(), "加载内容数据失败", Toast.LENGTH_SHORT).show(); 116 | } 117 | }); 118 | } 119 | 120 | private class ContentAdapter extends BGAAdapterViewAdapter { 121 | 122 | public ContentAdapter(Context context) { 123 | super(context, R.layout.item_normal); 124 | } 125 | 126 | @Override 127 | protected void fillData(BGAViewHolderHelper helper, int position, RefreshModel model) { 128 | helper.setText(R.id.tv_item_normal_title, model.title).setText(R.id.tv_item_normal_detail, model.detail); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.ui.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | import android.widget.Toast; 9 | 10 | import com.bumptech.glide.Glide; 11 | import com.bumptech.glide.request.RequestOptions; 12 | 13 | import cn.bingoogolapple.bgabanner.BGABanner; 14 | import cn.bingoogolapple.bgabanner.demo.App; 15 | import cn.bingoogolapple.bgabanner.demo.R; 16 | import cn.bingoogolapple.bgabanner.demo.engine.Engine; 17 | import cn.bingoogolapple.bgabanner.demo.model.BannerModel; 18 | import cn.bingoogolapple.bgabanner.transformer.TransitionEffect; 19 | import retrofit2.Call; 20 | import retrofit2.Callback; 21 | import retrofit2.Response; 22 | 23 | public class MainActivity extends AppCompatActivity implements BGABanner.Delegate, BGABanner.Adapter { 24 | private BGABanner mDefaultBanner; 25 | private BGABanner mCubeBanner; 26 | private BGABanner mAccordionBanner; 27 | private BGABanner mFlipBanner; 28 | private BGABanner mRotateBanner; 29 | private BGABanner mAlphaBanner; 30 | private BGABanner mZoomFadeBanner; 31 | private BGABanner mFadeBanner; 32 | private BGABanner mZoomCenterBanner; 33 | private BGABanner mZoomBanner; 34 | private BGABanner mStackBanner; 35 | private BGABanner mZoomStackBanner; 36 | private BGABanner mDepthBanner; 37 | 38 | private Engine mEngine; 39 | 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.activity_main); 44 | 45 | setTitle("BGABannerDemo"); 46 | mEngine = App.getInstance().getEngine(); 47 | 48 | initView(); 49 | setListener(); 50 | loadData(); 51 | } 52 | 53 | private void initView() { 54 | mDefaultBanner = findViewById(R.id.banner_main_default); 55 | mCubeBanner = findViewById(R.id.banner_main_cube); 56 | mAccordionBanner = findViewById(R.id.banner_main_accordion); 57 | mFlipBanner = findViewById(R.id.banner_main_flip); 58 | mRotateBanner = findViewById(R.id.banner_main_rotate); 59 | mAlphaBanner = findViewById(R.id.banner_main_alpha); 60 | mZoomFadeBanner = findViewById(R.id.banner_main_zoomFade); 61 | mFadeBanner = findViewById(R.id.banner_main_fade); 62 | mZoomCenterBanner = findViewById(R.id.banner_main_zoomCenter); 63 | mZoomBanner = findViewById(R.id.banner_main_zoom); 64 | mStackBanner = findViewById(R.id.banner_main_stack); 65 | mZoomStackBanner = findViewById(R.id.banner_main_zoomStack); 66 | mDepthBanner = findViewById(R.id.banner_main_depth); 67 | } 68 | 69 | private void setListener() { 70 | mDefaultBanner.setDelegate(this); 71 | mCubeBanner.setDelegate(this); 72 | } 73 | 74 | private void loadData() { 75 | loadData(mDefaultBanner, 1); 76 | loadData(mCubeBanner, 2); 77 | loadData(mAccordionBanner, 3); 78 | loadData(mFlipBanner, 4); 79 | loadData(mRotateBanner, 5); 80 | loadData(mAlphaBanner, 6); 81 | loadData(mZoomFadeBanner, 3); 82 | loadData(mFadeBanner, 4); 83 | loadData(mZoomCenterBanner, 5); 84 | loadData(mZoomBanner, 6); 85 | loadData(mStackBanner, 3); 86 | loadData(mZoomStackBanner, 4); 87 | loadData(mDepthBanner, 5); 88 | } 89 | 90 | private void loadData(final BGABanner banner, final int count) { 91 | mEngine.fetchItemsWithItemCount(count).enqueue(new Callback() { 92 | @Override 93 | public void onResponse(Call call, Response response) { 94 | BannerModel bannerModel = response.body(); 95 | 96 | /** 97 | * 设置是否开启自动轮播,需要在 setData 方法之前调用,并且调了该方法后必须再调用一次 setData 方法 98 | * 例如根据图片当图片数量大于 1 时开启自动轮播,等于 1 时不开启自动轮播 99 | */ 100 | banner.setAutoPlayAble(bannerModel.imgs.size() > 1); 101 | 102 | banner.setAdapter(MainActivity.this); 103 | banner.setData(bannerModel.imgs, bannerModel.tips); 104 | } 105 | 106 | @Override 107 | public void onFailure(Call call, Throwable t) { 108 | Toast.makeText(App.getInstance(), "网络数据加载失败", Toast.LENGTH_SHORT).show(); 109 | } 110 | }); 111 | } 112 | 113 | @Override 114 | public void onBannerItemClick(BGABanner banner, ImageView itemView, String model, int position) { 115 | Toast.makeText(banner.getContext(), "点击了第" + (position + 1) + "页", Toast.LENGTH_SHORT).show(); 116 | } 117 | 118 | @Override 119 | public void fillBannerItem(BGABanner banner, ImageView itemView, String model, int position) { 120 | Glide.with(itemView.getContext()) 121 | .load(model) 122 | .apply(new RequestOptions().placeholder(R.drawable.holder).error(R.drawable.holder).dontAnimate().centerCrop()) 123 | .into(itemView); 124 | } 125 | 126 | public void onClick(View v) { 127 | switch (v.getId()) { 128 | case R.id.tv_main_visible: 129 | mDefaultBanner.setVisibility(View.VISIBLE); 130 | break; 131 | case R.id.tv_main_invisible: 132 | mDefaultBanner.setVisibility(View.INVISIBLE); 133 | break; 134 | case R.id.tv_main_gone: 135 | mDefaultBanner.setVisibility(View.GONE); 136 | break; 137 | case R.id.tv_main_change_height: 138 | // 设置宽高比例,如果大于 0,则会根据宽度来计算高度,否则使用 android:layout_height 指定的高度 139 | mDefaultBanner.setAspectRatio(2.1f); 140 | break; 141 | case R.id.tv_main_enable_auto_play: 142 | /** 143 | * 设置是否开启自动轮播,需要在 setData 方法之前调用,并且调了该方法后必须再调用一次 setData 方法 144 | * 例如根据图片当图片数量大于 1 时开启自动轮播,等于 1 时不开启自动轮播 145 | */ 146 | mDefaultBanner.setAutoPlayAble(true); 147 | break; 148 | case R.id.tv_main_disable_auto_play: 149 | /** 150 | * 设置是否开启自动轮播,需要在 setData 方法之前调用,并且调了该方法后必须再调用一次 setData 方法 151 | * 例如根据图片当图片数量大于 1 时开启自动轮播,等于 1 时不开启自动轮播 152 | */ 153 | mDefaultBanner.setAutoPlayAble(false); 154 | break; 155 | case R.id.tv_main_start_auto_play: 156 | // 仅在 autoPlayAble 为 true 时才会生效「开发者使用该库时不用调用该方法,这里只是为了演示而已,界面可见时在 BGABanner 内部已经帮开发者调用了该方方法」 157 | mDefaultBanner.startAutoPlay(); 158 | break; 159 | case R.id.tv_main_stop_auto_play: 160 | // 仅在 autoPlayAble 为 true 时才会生效「开发者使用该库时不用调用该方法,这里只是为了演示而已,界面不可见时在 BGABanner 内部已经帮开发者调用了该方方法」 161 | mDefaultBanner.stopAutoPlay(); 162 | break; 163 | case R.id.tv_main_select_page_one: 164 | mDefaultBanner.setCurrentItem(0); 165 | break; 166 | case R.id.tv_main_select_page_two: 167 | mDefaultBanner.setCurrentItem(1); 168 | break; 169 | case R.id.tv_main_select_page_three: 170 | mDefaultBanner.setCurrentItem(2); 171 | break; 172 | case R.id.tv_main_select_page_four: 173 | mDefaultBanner.setCurrentItem(3); 174 | break; 175 | case R.id.tv_main_select_page_five: 176 | mDefaultBanner.setCurrentItem(4); 177 | break; 178 | case R.id.tv_main_get_item_count: 179 | Toast.makeText(App.getInstance(), "广告条总页数为 " + mDefaultBanner.getItemCount(), Toast.LENGTH_SHORT).show(); 180 | break; 181 | case R.id.tv_main_get_current_item: 182 | Toast.makeText(App.getInstance(), "广告当前索引位置为 " + mDefaultBanner.getCurrentItem(), Toast.LENGTH_SHORT).show(); 183 | break; 184 | case R.id.tv_main_load_zero_item: 185 | mDefaultBanner.setAdapter(this); 186 | mDefaultBanner.setAutoPlayAble(false); 187 | mDefaultBanner.setData(null, null); 188 | mDefaultBanner.showPlaceholder(); 189 | break; 190 | case R.id.tv_main_load_one_item: 191 | loadData(mDefaultBanner, 1); 192 | break; 193 | case R.id.tv_main_load_two_item: 194 | loadData(mDefaultBanner, 2); 195 | break; 196 | case R.id.tv_main_load_three_item: 197 | loadData(mDefaultBanner, 3); 198 | break; 199 | case R.id.tv_main_load_five_item: 200 | loadData(mDefaultBanner, 5); 201 | break; 202 | case R.id.tv_main_cube: 203 | mDefaultBanner.setTransitionEffect(TransitionEffect.Cube); 204 | break; 205 | case R.id.tv_main_depth: 206 | mDefaultBanner.setTransitionEffect(TransitionEffect.Depth); 207 | break; 208 | case R.id.tv_main_flip: 209 | mDefaultBanner.setTransitionEffect(TransitionEffect.Flip); 210 | break; 211 | case R.id.tv_main_rotate: 212 | mDefaultBanner.setTransitionEffect(TransitionEffect.Rotate); 213 | break; 214 | case R.id.tv_main_alpha: 215 | mDefaultBanner.setTransitionEffect(TransitionEffect.Alpha); 216 | break; 217 | case R.id.tv_main_listview_demo: 218 | startActivity(new Intent(this, ListViewDemoActivity.class)); 219 | break; 220 | case R.id.tv_main_recyclerview_demo: 221 | startActivity(new Intent(this, RecyclerViewDemoActivity.class)); 222 | break; 223 | case R.id.tv_main_fresco: 224 | startActivity(new Intent(this, FrescoDemoActivity.class)); 225 | break; 226 | 227 | default: 228 | break; 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /demo/src/main/java/cn/bingoogolapple/bgabanner/demo/ui/activity/RecyclerViewDemoActivity.java: -------------------------------------------------------------------------------- 1 | package cn.bingoogolapple.bgabanner.demo.ui.activity; 2 | 3 | import android.graphics.Rect; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ImageView; 8 | import android.widget.Toast; 9 | 10 | import com.bumptech.glide.Glide; 11 | import com.bumptech.glide.request.RequestOptions; 12 | 13 | import java.util.List; 14 | 15 | import androidx.appcompat.app.AppCompatActivity; 16 | import androidx.recyclerview.widget.GridLayoutManager; 17 | import androidx.recyclerview.widget.RecyclerView; 18 | import cn.bingoogolapple.baseadapter.BGAOnRVItemClickListener; 19 | import cn.bingoogolapple.baseadapter.BGARecyclerViewAdapter; 20 | import cn.bingoogolapple.baseadapter.BGAViewHolderHelper; 21 | import cn.bingoogolapple.bgabanner.BGABanner; 22 | import cn.bingoogolapple.bgabanner.BGABannerUtil; 23 | import cn.bingoogolapple.bgabanner.demo.App; 24 | import cn.bingoogolapple.bgabanner.demo.R; 25 | import cn.bingoogolapple.bgabanner.demo.engine.Engine; 26 | import cn.bingoogolapple.bgabanner.demo.model.BannerModel; 27 | import cn.bingoogolapple.bgabanner.demo.model.RefreshModel; 28 | import retrofit2.Call; 29 | import retrofit2.Callback; 30 | import retrofit2.Response; 31 | 32 | /** 33 | * 作者:王浩 邮件:bingoogolapple@gmail.com 34 | * 创建时间:16/7/21 下午8:26 35 | * 描述: 36 | */ 37 | public class RecyclerViewDemoActivity extends AppCompatActivity implements BGABanner.Adapter, BGABanner.Delegate { 38 | private RecyclerView mContentRv; 39 | private BGABanner mBanner; 40 | private ContentAdapter mContentAdapter; 41 | 42 | private Engine mEngine; 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | setContentView(R.layout.activity_recyclerview_demo); 48 | mContentRv = findViewById(R.id.rv_content); 49 | 50 | setTitle("RecyclerViewDemo"); 51 | mEngine = App.getInstance().getEngine(); 52 | 53 | initRecyclerView(); 54 | 55 | 56 | loadBannerData(); 57 | loadContentData(); 58 | } 59 | 60 | /** 61 | * 初始化RecyclerView 62 | */ 63 | private void initRecyclerView() { 64 | // 初始化适配器 65 | mContentAdapter = new ContentAdapter(mContentRv); 66 | // 测试 item 点击事件 67 | mContentAdapter.setOnRVItemClickListener(new BGAOnRVItemClickListener() { 68 | @Override 69 | public void onRVItemClick(ViewGroup parent, View itemView, int position) { 70 | // 注意:即使加了 HeaderView,这里返回的 position 也是从 0 开始的,在 BGARecyclerViewAdapter 的内部已经帮开发者减去了 HeaderView 71 | Toast.makeText(itemView.getContext(), "position = " + position + " " + mContentAdapter.getItem(position).title, Toast.LENGTH_SHORT).show(); 72 | } 73 | }); 74 | // 添加 HeaderView 75 | mContentAdapter.addHeaderView(getHeaderView()); 76 | 77 | RecyclerView.LayoutManager layoutManager; 78 | 79 | // 测试 LinearLayoutManager 的情况 80 | // layoutManager = new LinearLayoutManager(this); 81 | 82 | // 测试 GridLayoutManager 的情况 83 | layoutManager = new GridLayoutManager(this, 2); 84 | 85 | mContentRv.setLayoutManager(layoutManager); 86 | 87 | // 测试添加分割间隙 88 | mContentRv.addItemDecoration(new RecyclerView.ItemDecoration() { 89 | @Override 90 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 91 | int position = parent.getChildAdapterPosition(view); 92 | // 注意:由于加了一个 HeaderView,所以是大于 0 时才加分隔间隙。onCanvas 就不演示了 93 | if (position > 0) { 94 | int halfPadding = BGABannerUtil.dp2px(view.getContext(), 4); 95 | outRect.set(halfPadding, halfPadding, halfPadding, halfPadding); 96 | } 97 | } 98 | }); 99 | 100 | // 注意:这里调用了 getHeaderAndFooterAdapter 方法 101 | mContentRv.setAdapter(mContentAdapter.getHeaderAndFooterAdapter()); 102 | } 103 | 104 | /** 105 | * 初始化 HeaderView 106 | * 107 | * @return 108 | */ 109 | private View getHeaderView() { 110 | View headerView = View.inflate(this, R.layout.layout_header, null); 111 | mBanner = headerView.findViewById(R.id.banner); 112 | mBanner.setAdapter(this); 113 | mBanner.setDelegate(this); 114 | return headerView; 115 | } 116 | 117 | @Override 118 | public void fillBannerItem(BGABanner banner, ImageView itemView, String model, int position) { 119 | Glide.with(this) 120 | .load(model) 121 | .apply(new RequestOptions().placeholder(R.drawable.holder).error(R.drawable.holder).dontAnimate().centerCrop()) 122 | .into(itemView); 123 | } 124 | 125 | @Override 126 | public void onBannerItemClick(BGABanner banner, ImageView imageView, String model, int position) { 127 | Toast.makeText(this, "点击了第" + (position + 1) + "页", Toast.LENGTH_SHORT).show(); 128 | } 129 | 130 | /** 131 | * 加载头部广告条的数据 132 | */ 133 | private void loadBannerData() { 134 | mEngine.fetchItemsWithItemCount(5).enqueue(new Callback() { 135 | @Override 136 | public void onResponse(Call call, Response response) { 137 | BannerModel bannerModel = response.body(); 138 | mBanner.setData(bannerModel.imgs, bannerModel.tips); 139 | } 140 | 141 | @Override 142 | public void onFailure(Call call, Throwable t) { 143 | Toast.makeText(App.getInstance(), "加载广告条数据失败", Toast.LENGTH_SHORT).show(); 144 | } 145 | }); 146 | } 147 | 148 | /** 149 | * 加载内容列表数据 150 | */ 151 | private void loadContentData() { 152 | mEngine.loadContentData("http://bgashare.bingoogolapple.cn/refreshlayout/api/defaultdata.json").enqueue(new Callback>() { 153 | @Override 154 | public void onResponse(Call> call, Response> response) { 155 | mContentAdapter.setData(response.body()); 156 | } 157 | 158 | @Override 159 | public void onFailure(Call> call, Throwable t) { 160 | Toast.makeText(App.getInstance(), "加载内容数据失败", Toast.LENGTH_SHORT).show(); 161 | } 162 | }); 163 | } 164 | 165 | private class ContentAdapter extends BGARecyclerViewAdapter { 166 | 167 | public ContentAdapter(RecyclerView recyclerView) { 168 | super(recyclerView, R.layout.item_normal); 169 | } 170 | 171 | @Override 172 | protected void fillData(BGAViewHolderHelper helper, int position, RefreshModel model) { 173 | helper.setText(R.id.tv_item_normal_title, model.title).setText(R.id.tv_item_normal_detail, model.detail); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/holder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/holder.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/point_focused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/point_focused.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/point_focused_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/point_focused_big.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/point_unfocused.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/point_unfocused.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-hdpi/point_unfocused_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-hdpi/point_unfocused_small.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_background_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_background_1.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_background_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_background_2.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_background_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_background_3.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_1.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_2.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xhdpi/uoko_guide_foreground_3.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingoogolapple/BGABanner-Android/a328a9eb2e49bda75db0003b76be74524da66708/demo/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/src/main/res/drawable/selector_banner_point.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/src/main/res/drawable/selector_banner_unequal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/src/main/res/drawable/selector_btn_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /demo/src/main/res/drawable/shape_number_indicator_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_fresco_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 24 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_guide.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 18 | 19 | 28 | 29 | 30 | 41 | 42 |