├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jarRepositories.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── AppGradle
└── appBuild.gradle
├── GalleryBannerLib
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── yc
│ │ └── gallerybannerlib
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── yc
│ │ └── gallerybannerlib
│ │ ├── GalleryLayoutManager.java
│ │ ├── GalleryLinearSnapHelper.java
│ │ ├── GalleryRecyclerView.java
│ │ ├── GalleryScaleTransformer.java
│ │ └── GallerySmoothScroller.java
│ └── test
│ └── java
│ └── com
│ └── yc
│ └── gallerybannerlib
│ └── ExampleUnitTest.java
├── LICENSE
├── README.md
├── SnapBannerLib
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── yc
│ └── snapbannerlib
│ ├── ScrollLinearHelper.java
│ ├── ScrollPageHelper.java
│ └── ScrollSnapHelper.java
├── YCBannerLib
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── yc
│ │ └── cn
│ │ └── ycbannerlib
│ │ ├── LibUtils.java
│ │ ├── banner
│ │ ├── adapter
│ │ │ ├── AbsDynamicPagerAdapter.java
│ │ │ ├── AbsLoopPagerAdapter.java
│ │ │ └── AbsStaticPagerAdapter.java
│ │ ├── hintview
│ │ │ ├── ColorPointHintView.java
│ │ │ ├── IconHintView.java
│ │ │ ├── ShapeHintView.java
│ │ │ └── TextHintView.java
│ │ ├── inter
│ │ │ ├── BaseHintView.java
│ │ │ └── HintViewDelegate.java
│ │ └── view
│ │ │ ├── BannerConstant.java
│ │ │ ├── BannerView.java
│ │ │ └── BannerViewPager.java
│ │ └── marquee
│ │ └── MarqueeView.java
│ └── res
│ ├── anim
│ ├── anim_marquee_in.xml
│ └── anim_marquee_out.xml
│ └── values
│ ├── attrs.xml
│ ├── ids.xml
│ └── strings.xml
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── yc
│ │ └── cn
│ │ └── ycbanner
│ │ ├── EightActivity.java
│ │ ├── FirstActivity.java
│ │ ├── FourActivity.java
│ │ ├── ImageBitmapUtils.java
│ │ ├── MainActivity.java
│ │ ├── NightActivity.java
│ │ ├── SecondActivity.java
│ │ ├── SevenActivity.java
│ │ ├── SixActivity.java
│ │ ├── Snap2Adapter.java
│ │ ├── Snap3Adapter.java
│ │ ├── SnapAdapter.java
│ │ ├── SplashActivity.java
│ │ └── ThirdActivity.java
│ └── res
│ ├── drawable-xhdpi
│ ├── bg_autumn_tree_min.jpg
│ ├── bg_kites_min.png
│ ├── bg_lake_min.jpg
│ ├── bg_leaves_min.jpg
│ ├── bg_magnolia_trees_min.jpg
│ ├── point_focus.png
│ └── point_normal.png
│ ├── drawable-xxhdpi
│ ├── beauty1.jpg
│ ├── beauty10.jpg
│ ├── beauty11.jpg
│ ├── beauty12.jpg
│ ├── beauty13.jpg
│ ├── beauty2.jpg
│ ├── beauty3.jpg
│ ├── beauty4.jpg
│ ├── beauty5.jpg
│ ├── beauty6.jpg
│ ├── beauty7.jpg
│ ├── beauty8.jpg
│ └── beauty9.jpg
│ ├── layout
│ ├── activity_eight.xml
│ ├── activity_first.xml
│ ├── activity_five.xml
│ ├── activity_four.xml
│ ├── activity_main.xml
│ ├── activity_night.xml
│ ├── activity_second.xml
│ ├── activity_seven.xml
│ ├── activity_third.xml
│ ├── item_snap.xml
│ └── item_snap2.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── array.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── image
├── 1.png
├── 2.png
├── 4.jpg
├── 4.mp4
├── 5.jpg
└── 6.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
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 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/dictionaries
41 | .idea/libraries
42 |
43 | # Keystore files
44 | *.jks
45 |
46 | # External native build folder generated in Android Studio 2.2 and later
47 | .externalNativeBuild
48 |
49 | # Google Services (e.g. APIs or Firebase)
50 | google-services.json
51 |
52 | # Freeline
53 | freeline.py
54 | freeline/
55 | freeline_project_description.json
56 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 1.8
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AppGradle/appBuild.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 |
3 | androidBuildToolsVersion = "29.0.0"
4 | androidMinSdkVersion = 17
5 | androidTargetSdkVersion = 29
6 | androidCompileSdkVersion = 29
7 |
8 |
9 | constraintLayoutVersion = '1.1.3'
10 | appcompatVersion = '1.2.0'
11 | annotationVersion = '1.1.0'
12 | cardviewVersion = '1.0.0'
13 | mediaVersion = '1.0.1'
14 | recyclerviewVersion = '1.0.0'
15 |
16 | /**主app-start*/
17 | AppDependencies = [
18 | constraintLayout : "androidx.constraintlayout:constraintlayout:${constraintLayoutVersion}",
19 | appcompat : "androidx.appcompat:appcompat:${appcompatVersion}",
20 | annotation : "androidx.annotation:annotation:${annotationVersion}",
21 | cardview : "androidx.cardview:cardview:${cardviewVersion}",
22 | media : "androidx.media:media:${mediaVersion}",
23 | recyclerview : "androidx.recyclerview:recyclerview:${recyclerviewVersion}",
24 | ]
25 |
26 | }
--------------------------------------------------------------------------------
/GalleryBannerLib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/GalleryBannerLib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 | apply from: rootProject.projectDir.absolutePath + "/AppGradle/appBuild.gradle"
5 | apply plugin: 'com.github.dcendents.android-maven'
6 |
7 | android {
8 | compileSdkVersion project.ext.androidCompileSdkVersion
9 | //buildToolsVersion project.ext.androidBuildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion project.ext.androidMinSdkVersion
13 | targetSdkVersion project.ext.androidTargetSdkVersion
14 | versionCode 2
15 | versionName "1.0.2"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: "libs", include: ["*.jar"])
28 | implementation project.ext.AppDependencies['appcompat']
29 | implementation project.ext.AppDependencies['recyclerview']
30 | }
--------------------------------------------------------------------------------
/GalleryBannerLib/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/GalleryBannerLib/consumer-rules.pro
--------------------------------------------------------------------------------
/GalleryBannerLib/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
--------------------------------------------------------------------------------
/GalleryBannerLib/src/androidTest/java/com/yc/gallerybannerlib/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerybannerlib;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 | assertEquals("com.yc.gallerybannerlib.test", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/GalleryBannerLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/GalleryBannerLib/src/main/java/com/yc/gallerybannerlib/GalleryLinearSnapHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerybannerlib;
2 |
3 | import android.graphics.PointF;
4 | import android.util.DisplayMetrics;
5 | import android.util.Log;
6 | import android.view.View;
7 |
8 | import androidx.annotation.Nullable;
9 | import androidx.recyclerview.widget.LinearSmoothScroller;
10 | import androidx.recyclerview.widget.LinearSnapHelper;
11 | import androidx.recyclerview.widget.OrientationHelper;
12 | import androidx.recyclerview.widget.RecyclerView;
13 |
14 | /**
15 | *
16 | * @author yangchong
17 | * blog : https://github.com/yangchong211
18 | * time : 2018/3/18
19 | * desc : 自定义SnapHelper
20 | * revise: 关于SnapHelper源码分析可以看我博客:https://blog.csdn.net/m0_37700275/article/details/83901677
21 | *
22 | */
23 | public class GalleryLinearSnapHelper extends LinearSnapHelper {
24 |
25 | private static final float INVALID_DISTANCE = 1f;
26 | private static final float MILLISECONDS_PER_INCH = 100.0f;
27 | private static final int MAX_SCROLL_ON_FLING_DURATION = 100; // ms
28 | private RecyclerView mRecyclerView;
29 | private OrientationHelper mHorizontalHelper;
30 |
31 | public GalleryLinearSnapHelper(@Nullable RecyclerView recyclerView){
32 | mRecyclerView = recyclerView;
33 | }
34 |
35 | @Nullable
36 | protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layoutManager) {
37 | if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
38 | return null;
39 | }
40 | return new LinearSmoothScroller(mRecyclerView.getContext()) {
41 | @Override
42 | protected void onTargetFound(View targetView, RecyclerView.State state, RecyclerView.SmoothScroller.Action action) {
43 | int[] snapDistances = calculateDistanceToFinalSnap(mRecyclerView.getLayoutManager(), targetView);
44 | final int dx;
45 | final int dy;
46 | if (snapDistances != null) {
47 | dx = snapDistances[0];
48 | dy = snapDistances[1];
49 | final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
50 | if (time > 0) {
51 | action.update(dx, dy, time, mDecelerateInterpolator);
52 | }
53 | }
54 | }
55 |
56 | @Override
57 | protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
58 | //这个地方可以自己设置
59 | return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
60 | }
61 |
62 | @Override
63 | protected int calculateTimeForScrolling(int dx) {
64 | return Math.min(MAX_SCROLL_ON_FLING_DURATION, super.calculateTimeForScrolling(dx));
65 | }
66 | };
67 | }
68 |
69 | /**
70 | * 提供一个用于对齐的Adapter 目标position,抽象方法,需要子类自己实现
71 | * 发现滚动时候,会滑动多个item,如果相对item个数做限制,可以在findTargetSnapPosition()方法中处理。
72 | * @param layoutManager layoutManager
73 | * @param velocityX velocityX
74 | * @param velocityY velocityY
75 | * @return
76 | */
77 | @Override
78 | public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
79 | if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
80 | return RecyclerView.NO_POSITION;
81 | }
82 |
83 | final int itemCount = layoutManager.getItemCount();
84 | if (itemCount == 0) {
85 | return RecyclerView.NO_POSITION;
86 | }
87 |
88 | final View currentView = findSnapView(layoutManager);
89 | if (currentView == null) {
90 | return RecyclerView.NO_POSITION;
91 | }
92 |
93 | final int currentPosition = layoutManager.getPosition(currentView);
94 | if (currentPosition == RecyclerView.NO_POSITION) {
95 | return RecyclerView.NO_POSITION;
96 | }
97 |
98 | RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider =
99 | (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
100 | PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
101 | if (vectorForEnd == null) {
102 | return RecyclerView.NO_POSITION;
103 | }
104 |
105 | //在松手之后,列表最多只能滚多一屏的item数
106 | int deltaThreshold = layoutManager.getWidth() / getHorizontalHelper(layoutManager).getDecoratedMeasurement(currentView);
107 | Log.d("GalleryLinearSnapHelper", "---deltaThreshold---"+deltaThreshold+"");
108 | int hDeltaJump;
109 | if (layoutManager.canScrollHorizontally()) {
110 | hDeltaJump = estimateNextPositionDiffForFling(layoutManager, getHorizontalHelper(layoutManager), velocityX, 0);
111 | if (hDeltaJump > deltaThreshold) {
112 | hDeltaJump = deltaThreshold;
113 | }
114 | if (hDeltaJump < -deltaThreshold) {
115 | hDeltaJump = -deltaThreshold;
116 | }
117 |
118 | if (vectorForEnd.x < 0) {
119 | hDeltaJump = -hDeltaJump;
120 | }
121 | Log.d("GalleryLinearSnapHelper", "+++-hDeltaJump-+++"+hDeltaJump+"");
122 | } else {
123 | hDeltaJump = 0;
124 | }
125 |
126 | if (hDeltaJump == 0) {
127 | return RecyclerView.NO_POSITION;
128 | }
129 | Log.d("GalleryLinearSnapHelper", "---hDeltaJump---"+hDeltaJump+"");
130 | int targetPos = currentPosition + hDeltaJump;
131 | if (targetPos < 0) {
132 | targetPos = 0;
133 | }
134 | Log.d("GalleryLinearSnapHelper", "+++targetPos+++"+targetPos+"");
135 | if (targetPos >= itemCount) {
136 | targetPos = itemCount - 1;
137 | }
138 | Log.d("GalleryLinearSnapHelper", "---targetPos---"+targetPos+"");
139 | return targetPos;
140 | }
141 |
142 |
143 | private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager,
144 | OrientationHelper helper, int velocityX, int velocityY) {
145 | int[] distances = calculateScrollDistance(velocityX, velocityY);
146 | float distancePerChild = computeDistancePerChild(layoutManager, helper);
147 | if (distancePerChild <= 0) {
148 | return 0;
149 | }
150 | int distance = distances[0];
151 | if (distance > 0) {
152 | return (int) Math.floor(distance / distancePerChild);
153 | } else {
154 | return (int) Math.ceil(distance / distancePerChild);
155 | }
156 | }
157 |
158 |
159 | private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
160 | View minPosView = null;
161 | View maxPosView = null;
162 | int minPos = Integer.MAX_VALUE;
163 | int maxPos = Integer.MIN_VALUE;
164 | int childCount = layoutManager.getChildCount();
165 | if (childCount == 0) {
166 | return INVALID_DISTANCE;
167 | }
168 | for (int i = 0; i < childCount; i++) {
169 | View child = layoutManager.getChildAt(i);
170 | final int pos = layoutManager.getPosition(child);
171 | if (pos == RecyclerView.NO_POSITION) {
172 | continue;
173 | }
174 | if (pos < minPos) {
175 | minPos = pos;
176 | minPosView = child;
177 | }
178 | if (pos > maxPos) {
179 | maxPos = pos;
180 | maxPosView = child;
181 | }
182 | }
183 | if (minPosView == null || maxPosView == null) {
184 | return INVALID_DISTANCE;
185 | }
186 | int start = Math.min(helper.getDecoratedStart(minPosView), helper.getDecoratedStart(maxPosView));
187 | int end = Math.max(helper.getDecoratedEnd(minPosView), helper.getDecoratedEnd(maxPosView));
188 | int distance = end - start;
189 | if (distance == 0) {return INVALID_DISTANCE;}
190 | return 1f * distance / ((maxPos - minPos) + 1);
191 | }
192 |
193 | private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
194 | if (mHorizontalHelper == null) {
195 | mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
196 | }
197 | return mHorizontalHelper;
198 | }
199 |
200 | }
201 |
--------------------------------------------------------------------------------
/GalleryBannerLib/src/main/java/com/yc/gallerybannerlib/GalleryScaleTransformer.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerybannerlib;
2 |
3 |
4 | import android.view.View;
5 |
6 | import androidx.annotation.FloatRange;
7 |
8 | /**
9 | *
10 | * @author yangchong
11 | * blog : https://github.com/yangchong211
12 | * time : 2018/4/17
13 | * desc : 自定义ItemTransformer,用于动画缩放比例,可以灵活设置
14 | * revise:
15 | *
16 | */
17 | public class GalleryScaleTransformer implements GalleryLayoutManager.ItemTransformer {
18 |
19 | //设置缩放比例因子
20 | private float scaleDivisor = 0.2f;
21 | private int padding = 30;
22 | public GalleryScaleTransformer(@FloatRange(from = 0.0f, to = 1.0f) float scaleSize , int padding) {
23 | this.scaleDivisor = scaleSize;
24 | this.padding = padding;
25 | }
26 |
27 | @Override
28 | public void transformItem(GalleryLayoutManager layoutManager, View item, float fraction) {
29 | item.setPivotX(item.getWidth() / 2.0f);
30 | item.setPivotY(item.getHeight()/ 2.0f);
31 | if (scaleDivisor==0.0f){
32 | int measuredWidth = item.getMeasuredWidth();
33 | //Log.d("GalleryScaleTransformer",measuredWidth+"");
34 | if (padding<0 || padding>measuredWidth){
35 | padding = 30;
36 | }
37 | item.setPadding(padding,0,padding,0);
38 | }else {
39 | float scale = 1 - scaleDivisor * Math.abs(fraction);
40 | //可以在这里对view设置动画效果
41 | item.setScaleX(scale);
42 | item.setScaleY(scale);
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/GalleryBannerLib/src/main/java/com/yc/gallerybannerlib/GallerySmoothScroller.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerybannerlib;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.view.View;
6 |
7 | import androidx.recyclerview.widget.LinearSmoothScroller;
8 | import androidx.recyclerview.widget.RecyclerView;
9 |
10 | /**
11 | *
12 | * @author yangchong
13 | * blog : https://github.com/yangchong211
14 | * time : 2018/4/17
15 | * desc : 自定义LinearSmoothScroller
16 | * revise:
17 | *
18 | */
19 | public class GallerySmoothScroller extends LinearSmoothScroller {
20 |
21 | private static final float MILLISECONDS_PER_INCH = 100f;
22 |
23 | GallerySmoothScroller(Context context) {
24 | super(context);
25 | }
26 |
27 | //This returns the milliseconds it takes to
28 | //scroll one pixel.
29 | @Override
30 | protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
31 | // 返回:滑过1px时经历的时间(ms)。
32 | //return MILLISECONDS_PER_INCH / displayMetrics.density;
33 | return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
34 | //返回滑动一个pixel需要多少毫秒
35 | }
36 |
37 |
38 | @Override
39 | protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
40 | final int dx = calculateDxToMakeCentral(targetView);
41 | final int dy = calculateDyToMakeCentral(targetView);
42 | final int distance = (int) Math.sqrt(dx * dx + dy * dy);
43 | final int time = calculateTimeForDeceleration(distance);
44 | if (time > 0) {
45 | action.update(-dx, -dy, time, mDecelerateInterpolator);
46 | }
47 | }
48 |
49 |
50 | private int calculateDxToMakeCentral(View view) {
51 | final RecyclerView.LayoutManager layoutManager = getLayoutManager();
52 | if (layoutManager == null || !layoutManager.canScrollHorizontally()) {
53 | return 0;
54 | }
55 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
56 | final int left = layoutManager.getDecoratedLeft(view) - params.leftMargin;
57 | final int right = layoutManager.getDecoratedRight(view) + params.rightMargin;
58 | final int start = layoutManager.getPaddingLeft();
59 | final int end = layoutManager.getWidth() - layoutManager.getPaddingRight();
60 | final int childCenter = left + (int) ((right - left) / 2.0f);
61 | final int containerCenter = (int) ((end - start) / 2.f);
62 | return containerCenter - childCenter;
63 | }
64 |
65 | private int calculateDyToMakeCentral(View view) {
66 | final RecyclerView.LayoutManager layoutManager = getLayoutManager();
67 | if (layoutManager == null || !layoutManager.canScrollVertically()) {
68 | return 0;
69 | }
70 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
71 | final int top = layoutManager.getDecoratedTop(view) - params.topMargin;
72 | final int bottom = layoutManager.getDecoratedBottom(view) + params.bottomMargin;
73 | final int start = layoutManager.getPaddingTop();
74 | final int end = layoutManager.getHeight() - layoutManager.getPaddingBottom();
75 | final int childCenter = top + (int) ((bottom - top) / 2.0f);
76 | final int containerCenter = (int) ((end - start) / 2.f);
77 | return containerCenter - childCenter;
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/GalleryBannerLib/src/test/java/com/yc/gallerybannerlib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.yc.gallerybannerlib;
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 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## YCBanner轮播图
2 | - 主要引导界面滑动导航 + 大于1页时无限轮播 + 自定义指示器
3 | - 项目地址:https://github.com/yangchong211/YCBanner
4 |
5 |
6 |
7 | ### 目录介绍
8 | - 1.功能说明
9 | - 2.ViewPager轮播图使用说明
10 | - 3.跑马灯使用说明
11 | - 4.RecyclerView轮播图
12 | - 5.图片展示
13 | - 6.其他介绍
14 |
15 |
16 | ### 1.功能说明
17 | #### 1.1 基础功能介绍
18 | - 1.1 自定义轮播图,可以设置轮播红点或者轮播数字,多种指示器,并且灵活设置位置
19 | - 1.2 支持多种轮播图适配器,无限轮播adapter,静态管理adapter,和动态管理adapter。支持多种场合使用。
20 | - 1.3 支持自定义hintView,十分灵活,拓展性强
21 | - 1.4 无限循环自动轮播、手指按下暂停轮播、抬起手指开始轮播
22 | - 1.5 优化:在页面onPause中调用停止轮播,在页面onResume中调用开始轮播
23 | - 1.6 支持监听item点击事件,支持轮播图中ViewPager的滑动监听事件
24 | - 1.7 不仅支持轮播图,还支持引导页面,十分方便
25 | - 1.8 后期增加使用recyclerView设置轮播图。已经封装到GalleryRecyclerView中,链式调用十分方便
26 | - 1.9 GalleryRecyclerView轮播图支持设置轮播间隔时间,设置滑动速度,设置缩放比例因子
27 | - 如何引用:直接在项目build文件中添加库即可:compile 'cn.yc:YCBannerLib:1.3.9'
28 |
29 |
30 | #### 1.2 该库的优势
31 |
32 |
33 | ### 2.ViewPager轮播图使用说明
34 | - 2.1 关于具体的使用方法,可以直接参考代码
35 | - 2.2 在布局中写,可以设置选择的属性值
36 |
37 | ```
38 |
47 | ```
48 |
49 |
50 | - 2.3 在代码中,自定义adapter适配器,继承自己合适的adapter。目前支持继承动态管理adapter,静态管理adapter,和无限轮播adapter
51 |
52 | ```
53 | private void initBanner() {
54 | banner = (BannerView) findViewById(R.id.banner);
55 | //设置轮播时间
56 | banner.setPlayDelay(2000);
57 | //设置轮播图适配器,必须
58 | banner.setAdapter(new ImageNormalAdapter());
59 | //设置位置
60 | banner.setHintGravity(1);
61 | //设置指示器样式
62 | banner.setHintMode(BannerView.HintMode.TEXT_HINT);
63 | //判断轮播是否进行
64 | boolean playing = banner.isPlaying();
65 | //轮播图点击事件
66 | banner.setOnBannerClickListener(new OnBannerClickListener() {
67 | @Override
68 | public void onItemClick(int position) {
69 | Toast.makeText(FirstActivity.this,position+"被点击呢",Toast.LENGTH_SHORT).show();
70 | }
71 | });
72 | //轮播图滑动事件
73 | banner.setOnPageListener(new OnPageListener() {
74 | @Override
75 | public void onPageChange(int position) {
76 |
77 | }
78 | });
79 | }
80 |
81 |
82 | private class ImageNormalAdapter extends AbsStaticPagerAdapter {
83 |
84 | @Override
85 | public View getView(ViewGroup container, int position) {
86 | ImageView view = new ImageView(container.getContext());
87 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
88 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
89 | ViewGroup.LayoutParams.MATCH_PARENT));
90 | view.setImageResource(imgs[position]);
91 | return view;
92 | }
93 |
94 | @Override
95 | public int getCount() {
96 | return imgs.length;
97 | }
98 | }
99 | ```
100 |
101 |
102 | - **2.4 关于轮播图属性**
103 | - 关于暂停和开始轮播方法,建议加上
104 |
105 | ```
106 | @Override
107 | protected void onPause() {
108 | super.onPause();
109 | if(banner!=null){
110 | //停止轮播
111 | banner.pause();
112 | }
113 | }
114 |
115 | @Override
116 | protected void onResume() {
117 | super.onResume();
118 | if(banner!=null){
119 | //开始轮播
120 | banner.resume();
121 | }
122 | }
123 | ```
124 |
125 |
126 | - **2.5 如何显示红点,文字,自定义icon等**
127 | - **a.设置文本添加代码**:
128 | - banner.setHintView(new TextHintView(this));
129 | - **b.设置自定义icon添加代码:**
130 | - banner.setHintView(new IconHintView(this,R.drawable.point_focus,R.drawable.point_normal));
131 | - **c.默认不添加该方法则是显示圆点**
132 | - 请参考代码,已经做出了很详细的注释
133 |
134 |
135 | ### 3.跑马灯使用说明
136 | #### 3.1 在布局中添加代码
137 | ```
138 |
139 |
154 | ```
155 |
156 | #### 3.2 使用
157 | ```
158 | List list = getMarqueeTitle();
159 | //根据公告字符串列表启动轮播
160 | marqueeView.startWithList(list);
161 | //设置点击事件
162 | marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() {
163 | @Override
164 | public void onItemClick(int position, TextView textView) {
165 |
166 | }
167 | });
168 | ```
169 |
170 | ### 4.RecyclerView轮播图
171 | #### 4.1 RecyclerView轮播图简单使用
172 | - 在布局中
173 | ```
174 |
179 | ```
180 | - 代码设置
181 | ```
182 | private void initRecyclerView() {
183 | Snap3Adapter adapter = new Snap3Adapter(this);
184 | adapter.setData(getData());
185 | mGalleryRecyclerView.setDelayTime(3000)
186 | .setFlingSpeed(0)
187 | .setDataAdapter(adapter)
188 | .setSelectedPosition(100)
189 | .setCallbackInFling(false)
190 | .setOnItemSelectedListener(new GalleryRecyclerView.OnItemSelectedListener() {
191 | @Override
192 | public void onItemSelected(RecyclerView recyclerView, View item, int position) {
193 | Log.e("onItemSelected-----",position+"");
194 | //设置高斯模糊背景
195 | setBlurImage(true);
196 | }
197 | })
198 | .setSize(adapter.getData().size())
199 | .setUp();
200 | }
201 | ```
202 | - 注意要点:recyclerView轮播要是无限轮播,必须设置两点,很关键。
203 | - 第一处是getItemCount() 返回的是Integer.MAX_VALUE。这是因为广告轮播图是无限轮播,getItemCount()返回的是Adapter中的总项目数,这样才能使RecyclerView能一直滚动。
204 | - 第二处是onBindViewHolder()中的 position%list.size() ,表示position对图片列表list取余,这样list.get(position%list.size())才能按顺序循环展示图片。
205 | #### 4.2 RecyclerView实现平滑滚动,图片剧中效果
206 | - 如果不想设置轮播图,只想滚动。则可以直接套用GalleryLayoutManager
207 | - 类似猫眼的电影选择控件
208 | ```
209 | GalleryLayoutManager manager = new GalleryLayoutManager(LinearLayoutManager.HORIZONTAL);
210 | manager.attach(recyclerView,100);
211 | //如果想缩放,可以直接设置缩放比例因子即可
212 | manager.setItemTransformer(new GalleryScaleTransformer( 0.2f));
213 | recyclerView.setLayoutManager(manager);
214 | Snap3Adapter adapter = new Snap3Adapter(this);
215 | adapter.setData(getData());
216 | recyclerView.setAdapter(adapter);
217 | ```
218 |
219 | #### 4.3 关于自定义SnapHelper类
220 | - 有的时候原生LinearSnapHelper或者PagerSnapHelper无法满足我的需求,比如要设置滑动卡片左边对齐,或者右边对齐,或者居中模式;如果想要修改一下速率,或者一次滑动只能滑动一个item,那么就需要自定义呢
221 | - 具体实现可以看我的项目demo,看看下面的效果图
222 | - 关于SnapHelper类源码深度解析,可以看我的这篇博客:https://www.jianshu.com/p/9b8e0696802d
223 |
224 |
225 | ### 5.图片展示
226 | - 4.1 轮播图截图
227 | - 
228 | - 
229 | - 
230 | - 
231 | - 
232 | -
233 |
234 | -
235 |
236 | ### 6.其他介绍
237 | **5.1版本更新说明**
238 | - v1.0 16年3月23日,新芽轮播图,最简单的轮播图,无限轮播。
239 | - v1.1 5月2日 添加了动态管理adapter,和静态管理adapter,模拟多种场景轮播图
240 | - v1.2 6月12日 添加了触摸轮播图时暂停,松开手指开始轮播的功能;如果设置轮播图控件宽高都是wrap_content,那么则默认宽是match_parent,高是200dp。修改了handler内存泄漏
241 | - v1.3 17年8月22日 添加了ViewPager滑动监听接口,可以作用于引导页,十分简单
242 | - v1.3.2 17年10月21日 添加跑马灯轮播到该lib库中
243 | - v1.3.6 18年9月15日 同行提议更新API方法说明
244 | - v1.3.7 18年4月到6月17日 抽取项目中代码增加了recyclerView轮播图
245 | - v1.4.0 18年12月10日 修改了recyclerView轮播图滑动卡顿现象
246 |
247 |
248 | #### 关于其他内容介绍
249 | 
250 |
251 |
252 | #### 关于博客汇总链接
253 | - 1.[技术博客汇总](https://www.jianshu.com/p/614cb839182c)
254 | - 2.[开源项目汇总](https://blog.csdn.net/m0_37700275/article/details/80863574)
255 | - 3.[生活博客汇总](https://blog.csdn.net/m0_37700275/article/details/79832978)
256 | - 4.[喜马拉雅音频汇总](https://www.jianshu.com/p/f665de16d1eb)
257 | - 5.[其他汇总](https://www.jianshu.com/p/53017c3fc75d)
258 |
259 |
260 |
261 |
262 | #### 于LICENSE
263 | ```
264 | Licensed under the Apache License, Version 2.0 (the "License");
265 | you may not use this file except in compliance with the License.
266 | You may obtain a copy of the License at
267 |
268 | http://www.apache.org/licenses/LICENSE-2.0
269 |
270 | Unless required by applicable law or agreed to in writing, software
271 | distributed under the License is distributed on an "AS IS" BASIS,
272 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
273 | See the License for the specific language governing permissions and
274 | limitations under the License.
275 | ```
276 |
277 |
--------------------------------------------------------------------------------
/SnapBannerLib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/SnapBannerLib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 | apply from: rootProject.projectDir.absolutePath + "/AppGradle/appBuild.gradle"
5 | apply plugin: 'com.github.dcendents.android-maven'
6 |
7 | android {
8 | compileSdkVersion project.ext.androidCompileSdkVersion
9 | //buildToolsVersion project.ext.androidBuildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion project.ext.androidMinSdkVersion
13 | targetSdkVersion project.ext.androidTargetSdkVersion
14 | versionCode 2
15 | versionName "1.0.2"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: "libs", include: ["*.jar"])
28 | implementation project.ext.AppDependencies['appcompat']
29 | implementation project.ext.AppDependencies['recyclerview']
30 | }
--------------------------------------------------------------------------------
/SnapBannerLib/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/SnapBannerLib/consumer-rules.pro
--------------------------------------------------------------------------------
/SnapBannerLib/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
--------------------------------------------------------------------------------
/SnapBannerLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/SnapBannerLib/src/main/java/com/yc/snapbannerlib/ScrollLinearHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.snapbannerlib;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.annotation.Nullable;
5 | import androidx.recyclerview.widget.LinearLayoutManager;
6 | import androidx.recyclerview.widget.LinearSmoothScroller;
7 | import androidx.recyclerview.widget.LinearSnapHelper;
8 | import androidx.recyclerview.widget.OrientationHelper;
9 | import androidx.recyclerview.widget.RecyclerView;
10 | import android.util.DisplayMetrics;
11 | import android.view.View;
12 |
13 | /**
14 | *
15 | * @author yangchong
16 | * blog : https://github.com/yangchong211
17 | * time : 2018/3/18
18 | * desc : 自定义SnapHelper,设置左对齐,滑动时候会滑动多个item
19 | * revise: 关于SnapHelper源码分析可以看我博客:https://blog.csdn.net/m0_37700275/article/details/83901677
20 | *
21 | */
22 | public class ScrollLinearHelper extends LinearSnapHelper {
23 |
24 | private OrientationHelper mHorizontalHelper, mVerticalHelper;
25 | private RecyclerView mRecyclerView;
26 | private static final float MILLISECONDS_PER_INCH = 40f;
27 |
28 | @Override
29 | public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
30 | mRecyclerView = recyclerView;
31 | super.attachToRecyclerView(recyclerView);
32 | }
33 |
34 | @Nullable
35 | @Override
36 | public int[] calculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView) {
37 | int[] out = new int[2];
38 | if (layoutManager.canScrollHorizontally()) {
39 | out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
40 | } else {
41 | out[0] = 0;
42 | }
43 | if (layoutManager.canScrollVertically()) {
44 | out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
45 | } else {
46 | out[1] = 0;
47 | }
48 | return out;
49 | }
50 |
51 | private int distanceToStart(View targetView, OrientationHelper helper) {
52 | return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
53 | }
54 |
55 | @Nullable
56 | @Override
57 | public View findSnapView(RecyclerView.LayoutManager layoutManager) {
58 | if (layoutManager instanceof LinearLayoutManager) {
59 | if (layoutManager.canScrollHorizontally()) {
60 | return findStartView(layoutManager, getHorizontalHelper(layoutManager));
61 | } else {
62 | return findStartView(layoutManager, getVerticalHelper(layoutManager));
63 | }
64 | }
65 | return super.findSnapView(layoutManager);
66 | }
67 |
68 | private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
69 | if (layoutManager instanceof LinearLayoutManager) {
70 | int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
71 | //需要判断是否是最后一个Item,如果是最后一个则不让对齐,以免出现最后一个显示不完全。
72 | boolean isLastItem = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition()
73 | == layoutManager.getItemCount() - 1;
74 | if (firstChild == RecyclerView.NO_POSITION || isLastItem) {
75 | return null;
76 | }
77 | View child = layoutManager.findViewByPosition(firstChild);
78 | if (helper.getDecoratedEnd(child) >= helper.getDecoratedMeasurement(child) / 2
79 | && helper.getDecoratedEnd(child) > 0) {
80 | return child;
81 | } else {
82 | if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition()
83 | == layoutManager.getItemCount() - 1) {
84 | return null;
85 | } else {
86 | return layoutManager.findViewByPosition(firstChild + 1);
87 | }
88 | }
89 | }
90 | return super.findSnapView(layoutManager);
91 | }
92 |
93 | @Nullable
94 | protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layoutManager) {
95 | if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
96 | return null;
97 | }
98 | return new LinearSmoothScroller(mRecyclerView.getContext()) {
99 | @Override
100 | protected void onTargetFound(View targetView, RecyclerView.State state, RecyclerView.SmoothScroller.Action action) {
101 | int[] snapDistances = calculateDistanceToFinalSnap(mRecyclerView.getLayoutManager(), targetView);
102 | final int dx;
103 | final int dy;
104 | if (snapDistances != null) {
105 | dx = snapDistances[0];
106 | dy = snapDistances[1];
107 | final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
108 | if (time > 0) {
109 | action.update(dx, dy, time, mDecelerateInterpolator);
110 | }
111 | }
112 | }
113 |
114 | @Override
115 | protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
116 | //这个地方可以自己设置
117 | return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
118 | }
119 | };
120 | }
121 |
122 | @NonNull
123 | private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
124 | if (mVerticalHelper == null) {
125 | mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
126 | }
127 | return mVerticalHelper;
128 | }
129 |
130 | @NonNull
131 | private OrientationHelper getHorizontalHelper(
132 | @NonNull RecyclerView.LayoutManager layoutManager) {
133 | if (mHorizontalHelper == null) {
134 | mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
135 | }
136 | return mHorizontalHelper;
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/SnapBannerLib/src/main/java/com/yc/snapbannerlib/ScrollPageHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.snapbannerlib;
2 |
3 | import android.os.Build;
4 | import androidx.annotation.NonNull;
5 | import androidx.annotation.Nullable;
6 | import androidx.recyclerview.widget.GridLayoutManager;
7 | import androidx.recyclerview.widget.LinearLayoutManager;
8 | import androidx.recyclerview.widget.LinearSmoothScroller;
9 | import androidx.recyclerview.widget.OrientationHelper;
10 | import androidx.recyclerview.widget.PagerSnapHelper;
11 | import androidx.recyclerview.widget.RecyclerView;
12 | import androidx.recyclerview.widget.SnapHelper;
13 | import android.text.TextUtils;
14 | import android.view.Gravity;
15 | import android.view.View;
16 |
17 | import java.util.Locale;
18 |
19 | /**
20 | *
21 | * @author yangchong
22 | * blog : https://github.com/yangchong211
23 | * time : 2018/3/18
24 | * desc : 自定义SnapHelper,设置左对齐,滑动时候会限制item只滑动一个。可以设置gravity位置对齐
25 | * revise: 关于SnapHelper源码分析可以看我博客:https://blog.csdn.net/m0_37700275/article/details/83901677
26 | *
27 | */
28 | public class ScrollPageHelper extends PagerSnapHelper {
29 |
30 | private OrientationHelper mHorizontalHelper, mVerticalHelper;
31 | private int gravity;
32 | private boolean snapLastItem;
33 | private boolean isRtlHorizontal;
34 |
35 | public ScrollPageHelper(int gravity, boolean enableSnapLast){
36 | this.snapLastItem = enableSnapLast;
37 | this.gravity = gravity;
38 | }
39 |
40 | @Override
41 | public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
42 | throws IllegalStateException {
43 | if (recyclerView != null && (!(recyclerView.getLayoutManager() instanceof LinearLayoutManager)
44 | || recyclerView.getLayoutManager() instanceof GridLayoutManager)) {
45 | throw new IllegalStateException("ScrollPageHelper needs a RecyclerView with a LinearLayoutManager");
46 | }
47 | if (recyclerView != null) {
48 | recyclerView.setOnFlingListener(null);
49 | if ((gravity == Gravity.START || gravity == Gravity.END)) {
50 | isRtlHorizontal = isRtl();
51 | }
52 | }
53 | super.attachToRecyclerView(recyclerView);
54 | }
55 |
56 |
57 | @Nullable
58 | @Override
59 | public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
60 | int[] out = new int[2];
61 | if (layoutManager.canScrollHorizontally()) {
62 | if (gravity == Gravity.START) {
63 | out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager), false);
64 | } else { // END
65 | out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager), false);
66 | }
67 | } else {
68 | out[0] = 0;
69 | }
70 | if (layoutManager.canScrollVertically()) {
71 | if (gravity == Gravity.TOP) {
72 | out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager), false);
73 | } else { // BOTTOM
74 | out[1] = distanceToEnd(targetView, getVerticalHelper(layoutManager), false);
75 | }
76 | } else {
77 | out[1] = 0;
78 | }
79 | return out;
80 | }
81 |
82 | @Nullable
83 | @Override
84 | public View findSnapView(RecyclerView.LayoutManager layoutManager) {
85 | View snapView = null;
86 | if (layoutManager instanceof LinearLayoutManager) {
87 | switch (gravity) {
88 | case Gravity.START:
89 | snapView = findStartView(layoutManager, getHorizontalHelper(layoutManager));
90 | break;
91 | case Gravity.END:
92 | snapView = findEndView(layoutManager, getHorizontalHelper(layoutManager));
93 | break;
94 | case Gravity.TOP:
95 | snapView = findStartView(layoutManager, getVerticalHelper(layoutManager));
96 | break;
97 | case Gravity.BOTTOM:
98 | snapView = findEndView(layoutManager, getVerticalHelper(layoutManager));
99 | break;
100 | }
101 | }
102 | return snapView;
103 | }
104 |
105 |
106 | private boolean isRtl() {
107 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
108 | return false;
109 | }
110 | return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL;
111 | }
112 |
113 |
114 | @NonNull
115 | private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
116 | if (mVerticalHelper == null) {
117 | mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
118 | }
119 | return mVerticalHelper;
120 | }
121 |
122 | @NonNull
123 | private OrientationHelper getHorizontalHelper(
124 | @NonNull RecyclerView.LayoutManager layoutManager) {
125 | if (mHorizontalHelper == null) {
126 | mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
127 | }
128 | return mHorizontalHelper;
129 | }
130 |
131 |
132 | private int distanceToStart(View targetView, @NonNull OrientationHelper helper, boolean fromEnd) {
133 | if (isRtlHorizontal && !fromEnd) {
134 | return distanceToEnd(targetView, helper, true);
135 | }
136 |
137 | return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
138 | }
139 |
140 | private int distanceToEnd(View targetView, @NonNull OrientationHelper helper, boolean fromStart) {
141 | if (isRtlHorizontal && !fromStart) {
142 | return distanceToStart(targetView, helper, true);
143 | }
144 |
145 | return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
146 | }
147 |
148 |
149 | @Nullable
150 | private View findStartView(RecyclerView.LayoutManager layoutManager,
151 | @NonNull OrientationHelper helper) {
152 |
153 | if (layoutManager instanceof LinearLayoutManager) {
154 | LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
155 | boolean reverseLayout = linearLayoutManager.getReverseLayout();
156 | int firstChild = reverseLayout ? linearLayoutManager.findLastVisibleItemPosition()
157 | : linearLayoutManager.findFirstVisibleItemPosition();
158 | int offset = 1;
159 |
160 | if (layoutManager instanceof GridLayoutManager) {
161 | offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
162 | }
163 |
164 | if (firstChild == RecyclerView.NO_POSITION) {
165 | return null;
166 | }
167 |
168 | View child = layoutManager.findViewByPosition(firstChild);
169 |
170 | float visibleWidth;
171 | if (isRtlHorizontal) {
172 | visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
173 | / helper.getDecoratedMeasurement(child);
174 | } else {
175 | visibleWidth = (float) helper.getDecoratedEnd(child)
176 | / helper.getDecoratedMeasurement(child);
177 | }
178 | boolean endOfList;
179 | if (!reverseLayout) {
180 | endOfList = ((LinearLayoutManager) layoutManager)
181 | .findLastCompletelyVisibleItemPosition()
182 | == layoutManager.getItemCount() - 1;
183 | } else {
184 | endOfList = ((LinearLayoutManager) layoutManager)
185 | .findFirstCompletelyVisibleItemPosition()
186 | == 0;
187 | }
188 |
189 | if (visibleWidth > 0.5f && !endOfList) {
190 | return child;
191 | } else if (snapLastItem && endOfList) {
192 | return child;
193 | } else if (endOfList) {
194 | return null;
195 | } else {
196 | return reverseLayout ? layoutManager.findViewByPosition(firstChild - offset)
197 | : layoutManager.findViewByPosition(firstChild + offset);
198 | }
199 | }
200 |
201 | return null;
202 | }
203 |
204 | @Nullable
205 | private View findEndView(RecyclerView.LayoutManager layoutManager,
206 | @NonNull OrientationHelper helper) {
207 |
208 | if (layoutManager instanceof LinearLayoutManager) {
209 | LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
210 | boolean reverseLayout = linearLayoutManager.getReverseLayout();
211 | int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition()
212 | : linearLayoutManager.findLastVisibleItemPosition();
213 | int offset = 1;
214 |
215 | if (layoutManager instanceof GridLayoutManager) {
216 | offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
217 | }
218 |
219 | if (lastChild == RecyclerView.NO_POSITION) {
220 | return null;
221 | }
222 |
223 | View child = layoutManager.findViewByPosition(lastChild);
224 |
225 | float visibleWidth;
226 |
227 | if (isRtlHorizontal) {
228 | visibleWidth = (float) helper.getDecoratedEnd(child)
229 | / helper.getDecoratedMeasurement(child);
230 | } else {
231 | visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
232 | / helper.getDecoratedMeasurement(child);
233 | }
234 |
235 | boolean startOfList;
236 | if (!reverseLayout) {
237 | startOfList = ((LinearLayoutManager) layoutManager)
238 | .findFirstCompletelyVisibleItemPosition() == 0;
239 | } else {
240 | startOfList = ((LinearLayoutManager) layoutManager)
241 | .findLastCompletelyVisibleItemPosition()
242 | == layoutManager.getItemCount() - 1;
243 | }
244 |
245 | if (visibleWidth > 0.5f && !startOfList) {
246 | return child;
247 | } else if (snapLastItem && startOfList) {
248 | return child;
249 | } else if (startOfList) {
250 | return null;
251 | } else {
252 | return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset)
253 | : layoutManager.findViewByPosition(lastChild - offset);
254 | }
255 | }
256 | return null;
257 | }
258 |
259 |
260 | }
261 |
--------------------------------------------------------------------------------
/SnapBannerLib/src/main/java/com/yc/snapbannerlib/ScrollSnapHelper.java:
--------------------------------------------------------------------------------
1 | package com.yc.snapbannerlib;
2 |
3 | import android.graphics.PointF;
4 | import android.util.DisplayMetrics;
5 | import android.view.View;
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.annotation.Nullable;
9 | import androidx.recyclerview.widget.LinearLayoutManager;
10 | import androidx.recyclerview.widget.LinearSmoothScroller;
11 | import androidx.recyclerview.widget.OrientationHelper;
12 | import androidx.recyclerview.widget.RecyclerView;
13 | import androidx.recyclerview.widget.SnapHelper;
14 |
15 |
16 | /**
17 | *
18 | * @author yangchong
19 | * blog : https://github.com/yangchong211
20 | * time : 2018/3/18
21 | * desc : 自定义SnapHelper
22 | * revise: 关于SnapHelper源码分析可以看我博客:https://blog.csdn.net/m0_37700275/article/details/83901677
23 | *
24 | */
25 | public class ScrollSnapHelper extends SnapHelper {
26 |
27 | private static final float INVALID_DISTANCE = 1f;
28 | private static final float MILLISECONDS_PER_INCH = 40f;
29 | private OrientationHelper mHorizontalHelper;
30 | private RecyclerView mRecyclerView;
31 |
32 |
33 | @Override
34 | public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
35 | mRecyclerView = recyclerView;
36 | super.attachToRecyclerView(recyclerView);
37 | }
38 |
39 | @Override
40 | public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
41 | int[] out = new int[2];
42 | if (layoutManager.canScrollHorizontally()) {
43 | out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
44 | } else {
45 | out[0] = 0;
46 | }
47 | return out;
48 | }
49 |
50 | private int distanceToStart(View targetView, OrientationHelper helper) {
51 | return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
52 | }
53 |
54 | @Nullable
55 | protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layoutManager) {
56 | if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
57 | return null;
58 | }
59 | return new LinearSmoothScroller(mRecyclerView.getContext()) {
60 | @Override
61 | protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
62 | int[] snapDistances = calculateDistanceToFinalSnap(mRecyclerView.getLayoutManager(), targetView);
63 | final int dx;
64 | final int dy;
65 | if (snapDistances != null) {
66 | dx = snapDistances[0];
67 | dy = snapDistances[1];
68 | final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
69 | if (time > 0) {
70 | action.update(dx, dy, time, mDecelerateInterpolator);
71 | }
72 | }
73 | }
74 |
75 | @Override
76 | protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
77 | return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
78 | }
79 | };
80 | }
81 |
82 | @Override
83 | public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
84 | if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) {
85 | return RecyclerView.NO_POSITION;
86 | }
87 | final int itemCount = layoutManager.getItemCount();
88 | if (itemCount == 0) {
89 | return RecyclerView.NO_POSITION;
90 | }
91 | final View currentView = findSnapView(layoutManager);
92 | if (currentView == null) {
93 | return RecyclerView.NO_POSITION;
94 | }
95 | final int currentPosition = layoutManager.getPosition(currentView);
96 | if (currentPosition == RecyclerView.NO_POSITION) {
97 | return RecyclerView.NO_POSITION;
98 | }
99 | RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider =
100 | (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
101 | PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
102 | if (vectorForEnd == null) {
103 | // cannot get a vector for the given position.
104 | return RecyclerView.NO_POSITION;
105 | }
106 |
107 | //在松手之后,列表最多只能滚多一屏的item数
108 | int deltaThreshold = layoutManager.getWidth() / getHorizontalHelper(layoutManager).getDecoratedMeasurement(currentView);
109 |
110 | int hDeltaJump;
111 | if (layoutManager.canScrollHorizontally()) {
112 | hDeltaJump = estimateNextPositionDiffForFling(layoutManager, getHorizontalHelper(layoutManager), velocityX, 0);
113 | if (hDeltaJump > deltaThreshold) {
114 | hDeltaJump = deltaThreshold;
115 | }
116 | if (hDeltaJump < -deltaThreshold) {
117 | hDeltaJump = -deltaThreshold;
118 | }
119 | if (vectorForEnd.x < 0) {
120 | hDeltaJump = -hDeltaJump;
121 | }
122 | } else {
123 | hDeltaJump = 0;
124 | }
125 | if (hDeltaJump == 0) {
126 | return RecyclerView.NO_POSITION;
127 | }
128 |
129 | int targetPos = currentPosition + hDeltaJump;
130 | if (targetPos < 0) {
131 | targetPos = 0;
132 | }
133 | if (targetPos >= itemCount) {
134 | targetPos = itemCount - 1;
135 | }
136 | return targetPos;
137 | }
138 |
139 | @Override
140 | public View findSnapView(RecyclerView.LayoutManager layoutManager) {
141 | return findStartView(layoutManager, getHorizontalHelper(layoutManager));
142 | }
143 |
144 |
145 | private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
146 | if (layoutManager instanceof LinearLayoutManager) {
147 | int firstChildPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
148 | if (firstChildPosition == RecyclerView.NO_POSITION) {
149 | return null;
150 | }
151 | if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1) {
152 | return null;
153 | }
154 | View firstChildView = layoutManager.findViewByPosition(firstChildPosition);
155 | if (helper.getDecoratedEnd(firstChildView) >= helper.getDecoratedMeasurement(firstChildView) / 2 && helper.getDecoratedEnd(firstChildView) > 0) {
156 | return firstChildView;
157 | } else {
158 | return layoutManager.findViewByPosition(firstChildPosition + 1);
159 | }
160 | } else {
161 | return null;
162 | }
163 | }
164 |
165 |
166 | private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager, OrientationHelper helper, int velocityX, int velocityY) {
167 | int[] distances = calculateScrollDistance(velocityX, velocityY);
168 | float distancePerChild = computeDistancePerChild(layoutManager, helper);
169 | if (distancePerChild <= 0) {
170 | return 0;
171 | }
172 | int distance = distances[0];
173 | if (distance > 0) {
174 | return (int) Math.floor(distance / distancePerChild);
175 | } else {
176 | return (int) Math.ceil(distance / distancePerChild);
177 | }
178 | }
179 |
180 | private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
181 | View minPosView = null;
182 | View maxPosView = null;
183 | int minPos = Integer.MAX_VALUE;
184 | int maxPos = Integer.MIN_VALUE;
185 | int childCount = layoutManager.getChildCount();
186 | if (childCount == 0) {
187 | return INVALID_DISTANCE;
188 | }
189 | for (int i = 0; i < childCount; i++) {
190 | View child = layoutManager.getChildAt(i);
191 | final int pos = layoutManager.getPosition(child);
192 | if (pos == RecyclerView.NO_POSITION) {
193 | continue;
194 | }
195 | if (pos < minPos) {
196 | minPos = pos;
197 | minPosView = child;
198 | }
199 | if (pos > maxPos) {
200 | maxPos = pos;
201 | maxPosView = child;
202 | }
203 | }
204 | if (minPosView == null || maxPosView == null) {
205 | return INVALID_DISTANCE;
206 | }
207 | int start = Math.min(helper.getDecoratedStart(minPosView), helper.getDecoratedStart(maxPosView));
208 | int end = Math.max(helper.getDecoratedEnd(minPosView), helper.getDecoratedEnd(maxPosView));
209 | int distance = end - start;
210 | if (distance == 0) {
211 | return INVALID_DISTANCE;
212 | }
213 | return 1f * distance / ((maxPos - minPos) + 1);
214 | }
215 |
216 |
217 | private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
218 | if (mHorizontalHelper == null) {
219 | mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
220 | }
221 | return mHorizontalHelper;
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/YCBannerLib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/YCBannerLib/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | }
4 | apply from: rootProject.projectDir.absolutePath + "/AppGradle/appBuild.gradle"
5 | apply plugin: 'com.github.dcendents.android-maven'
6 |
7 | android {
8 | compileSdkVersion project.ext.androidCompileSdkVersion
9 | //buildToolsVersion project.ext.androidBuildToolsVersion
10 |
11 | defaultConfig {
12 | minSdkVersion project.ext.androidMinSdkVersion
13 | targetSdkVersion project.ext.androidTargetSdkVersion
14 | versionCode 2
15 | versionName "1.0.2"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: "libs", include: ["*.jar"])
28 | implementation project.ext.AppDependencies['appcompat']
29 | implementation project.ext.AppDependencies['recyclerview']
30 | }
--------------------------------------------------------------------------------
/YCBannerLib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\PC\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/LibUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib;
2 |
3 |
4 | import android.content.Context;
5 |
6 | /**
7 | *
8 | * @author yangchong
9 | * blog : https://github.com/yangchong211
10 | * time : 2018/4/17
11 | * desc : 工具类
12 | * revise:
13 | *
14 | */
15 | public class LibUtils {
16 |
17 | public static int dip2px(Context ctx, float dpValue) {
18 | final float scale = ctx.getResources().getDisplayMetrics().density;
19 | return (int) (dpValue * scale + 0.5f);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/adapter/AbsDynamicPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.adapter;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.fragment.app.FragmentPagerAdapter;
8 | import androidx.viewpager.widget.PagerAdapter;
9 |
10 |
11 | /**
12 | *
13 | * @author yangchong
14 | * blog : https://github.com/yangchong211
15 | * time : 2016/3/18
16 | * desc : 动态管理的Adapter。概念参照{@link FragmentPagerAdapter}
17 | * 每次都会创建新view,销毁旧View。节省内存消耗性能
18 | * revise: 比如使用场景是启动引导页
19 | *
20 | */
21 | public abstract class AbsDynamicPagerAdapter extends PagerAdapter {
22 |
23 | @Override
24 | public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
25 | return arg0==arg1;
26 | }
27 |
28 | @Override
29 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
30 | container.removeView((View) object);
31 | }
32 |
33 | @Override
34 | public int getItemPosition(@NonNull Object object) {
35 | return super.getItemPosition(object);
36 | }
37 |
38 | @NonNull
39 | @Override
40 | public Object instantiateItem(@NonNull ViewGroup container, int position) {
41 | View itemView = getView(container,position);
42 | container.addView(itemView);
43 | return itemView;
44 | }
45 |
46 | /**
47 | * 创建view
48 | * @param container container
49 | * @param position 索引
50 | * @return
51 | */
52 | public abstract View getView(ViewGroup container, int position);
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/adapter/AbsLoopPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.adapter;
2 |
3 | import android.annotation.TargetApi;
4 | import android.database.DataSetObserver;
5 | import android.os.Build;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.viewpager.widget.PagerAdapter;
12 | import androidx.viewpager.widget.ViewPager;
13 |
14 | import com.yc.cn.ycbannerlib.banner.inter.BaseHintView;
15 | import com.yc.cn.ycbannerlib.banner.inter.HintViewDelegate;
16 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
17 |
18 | import java.lang.reflect.Field;
19 | import java.util.ArrayList;
20 |
21 | /**
22 | *
23 | * @author yangchong
24 | * blog : https://github.com/yangchong211
25 | * time : 2016/3/18
26 | * desc : AbsLoopPagerAdapter
27 | * revise: 如果是自动轮播图的话就用这一个
28 | *
29 | */
30 | public abstract class AbsLoopPagerAdapter extends PagerAdapter {
31 |
32 |
33 | private BannerView mViewPager;
34 | /**
35 | * 用来存放View的集合
36 | */
37 | private ArrayList mViewList = new ArrayList<>();
38 |
39 | private class LoopHintViewDelegate implements HintViewDelegate {
40 | @Override
41 | public void setCurrentPosition(int position, BaseHintView hintView) {
42 | if (hintView!=null&&getRealCount()>0){
43 | hintView.setCurrent(position%getRealCount());
44 | }
45 | }
46 |
47 | @Override
48 | public void initView(int length, int gravity, BaseHintView hintView) {
49 | if (hintView!=null){
50 | hintView.initView(getRealCount(),gravity);
51 | }
52 | }
53 | }
54 |
55 | /**
56 | * 刷新全部
57 | */
58 | @Override
59 | public void notifyDataSetChanged() {
60 | mViewList.clear();
61 | initPosition();
62 | super.notifyDataSetChanged();
63 | }
64 |
65 | /**
66 | * 获取item索引
67 | *
68 | * POSITION_UNCHANGED表示位置没有变化,即在添加或移除一页或多页之后该位置的页面保持不变,
69 | * 可以用于一个ViewPager中最后几页的添加或移除时,保持前几页仍然不变;
70 | *
71 | * POSITION_NONE,表示当前页不再作为ViewPager的一页数据,将被销毁,可以用于无视View缓存的刷新;
72 | * 根据传过来的参数Object来判断这个key所指定的新的位置
73 | * @param object objcet
74 | * @return
75 | */
76 | @Override
77 | public int getItemPosition(@NonNull Object object) {
78 | return POSITION_NONE;
79 | }
80 |
81 | /**
82 | * 注册数据观察者监听
83 | * @param observer observer
84 | */
85 | @Override
86 | public void registerDataSetObserver(@NonNull DataSetObserver observer) {
87 | super.registerDataSetObserver(observer);
88 | initPosition();
89 | }
90 |
91 | private void initPosition(){
92 | if (getRealCount()>1){
93 | if (mViewPager.getViewPager().getCurrentItem() == 0&&getRealCount()>0){
94 | int half = Integer.MAX_VALUE/2;
95 | int start = half - half%getRealCount();
96 | setCurrent(start);
97 | }
98 | }
99 | }
100 |
101 | /**
102 | * 设置位置,利用反射实现
103 | * @param index 索引
104 | */
105 | @TargetApi(Build.VERSION_CODES.KITKAT)
106 | private void setCurrent(int index){
107 | try {
108 | Field field = ViewPager.class.getDeclaredField("mCurItem");
109 | field.setAccessible(true);
110 | field.set(mViewPager.getViewPager(),index);
111 | } catch (NoSuchFieldException | IllegalAccessException e) {
112 | e.printStackTrace();
113 | }
114 | }
115 |
116 | public AbsLoopPagerAdapter(BannerView viewPager){
117 | this.mViewPager = viewPager;
118 | viewPager.setHintViewDelegate(new LoopHintViewDelegate());
119 | }
120 |
121 | @Override
122 | public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
123 | return arg0==arg1;
124 | }
125 |
126 | /**
127 | * 如果页面不是当前显示的页面也不是要缓存的页面,会调用这个方法,将页面销毁。
128 | * @param container container
129 | * @param position 索引
130 | * @param object object
131 | */
132 | @Override
133 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
134 | container.removeView((View) object);
135 | Log.d("PagerAdapter","销毁的方法");
136 | }
137 |
138 | /**
139 | * 要显示的页面或需要缓存的页面,会调用这个方法进行布局的初始化。
140 | * @param container container
141 | * @param position 索引
142 | * @return
143 | */
144 | @NonNull
145 | @Override
146 | public Object instantiateItem(@NonNull ViewGroup container, int position) {
147 | int realPosition = position%getRealCount();
148 | View itemView = findViewByPosition(container,realPosition);
149 | container.addView(itemView);
150 | Log.d("PagerAdapter","创建的方法");
151 | return itemView;
152 | }
153 |
154 | /**
155 | * 这个是避免重复创建,如果集合中有,则取集合中的
156 | * @param container container
157 | * @param position 索引
158 | * @return
159 | */
160 | private View findViewByPosition(ViewGroup container, int position){
161 | for (View view : mViewList) {
162 | if (((int)view.getTag()) == position&&view.getParent()==null){
163 | return view;
164 | }
165 | }
166 | View view = getView(container,position);
167 | view.setTag(position);
168 | mViewList.add(view);
169 | return view;
170 | }
171 |
172 |
173 | @Deprecated
174 | @Override
175 | public final int getCount() {
176 | //设置最大轮播图数量 ,如果是1那么就是1,不轮播;如果大于1则设置一个最大值,可以轮播
177 | //return getRealCount();
178 | return getRealCount()<=1?getRealCount(): Integer.MAX_VALUE;
179 | }
180 |
181 | /**
182 | * 获取轮播图数量
183 | * @return 数量
184 | */
185 | public abstract int getRealCount();
186 |
187 | /**
188 | * 创建view
189 | * @param container viewGroup
190 | * @param position 索引
191 | * @return
192 | */
193 | public abstract View getView(ViewGroup container, int position);
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/adapter/AbsStaticPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.adapter;
2 |
3 |
4 | import android.util.Log;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.fragment.app.FragmentStatePagerAdapter;
10 | import androidx.viewpager.widget.PagerAdapter;
11 |
12 | import com.yc.cn.ycbannerlib.LibUtils;
13 |
14 | import java.util.ArrayList;
15 |
16 |
17 |
18 | /**
19 | *
20 | * @author yangchong
21 | * blog : https://github.com/yangchong211
22 | * time : 2016/3/18
23 | * desc : 静态存储的Adapter,概念参照{@link FragmentStatePagerAdapter}
24 | * view添加进去就不管了,View长在,内存不再
25 | * revise: 如果是静态轮播图就用这个
26 | *
27 | */
28 | public abstract class AbsStaticPagerAdapter extends PagerAdapter {
29 |
30 | private ArrayList mViewList = new ArrayList<>();
31 |
32 | @Override
33 | public boolean isViewFromObject(@NonNull View arg0, @NonNull Object arg1) {
34 | return arg0==arg1;
35 | }
36 |
37 | @Override
38 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
39 | container.removeView((View) object);
40 | Log.d("PagerAdapter","销毁的方法");
41 | }
42 |
43 | @Override
44 | public void notifyDataSetChanged() {
45 | mViewList.clear();
46 | super.notifyDataSetChanged();
47 | }
48 |
49 | @Override
50 | public int getItemPosition(@NonNull Object object) {
51 | return POSITION_NONE;
52 | }
53 |
54 | @NonNull
55 | @Override
56 | public Object instantiateItem(@NonNull ViewGroup container, int position) {
57 | View itemView = findViewByPosition(container,position);
58 | container.addView(itemView);
59 | onBind(itemView,position);
60 | Log.d("PagerAdapter","创建的方法");
61 | return itemView;
62 | }
63 |
64 | private View findViewByPosition(ViewGroup container, int position){
65 | for (View view : mViewList) {
66 | if (((int)view.getTag()) == position&&view.getParent()==null){
67 | return view;
68 | }
69 | }
70 | View view = getView(container,position);
71 | view.setTag(position);
72 | mViewList.add(view);
73 | return view;
74 | }
75 |
76 |
77 | public void onBind(View view, int position){}
78 |
79 | public abstract View getView(ViewGroup container, int position);
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/hintview/ColorPointHintView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.hintview;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.drawable.Drawable;
6 | import android.graphics.drawable.GradientDrawable;
7 |
8 | import com.yc.cn.ycbannerlib.LibUtils;
9 |
10 | /**
11 | *
12 | * @author yangchong
13 | * blog : https://github.com/yangchong211
14 | * time : 2016/3/18
15 | * desc : color
16 | * revise:
17 | *
18 | */
19 | @SuppressLint("ViewConstructor")
20 | public class ColorPointHintView extends ShapeHintView {
21 |
22 | private int focusColor;
23 | private int normalColor;
24 |
25 | public ColorPointHintView(Context context, int focusColor, int normalColor) {
26 | super(context);
27 | this.focusColor = focusColor;
28 | this.normalColor = normalColor;
29 | }
30 |
31 | @Override
32 | public Drawable makeFocusDrawable() {
33 | GradientDrawable dotFocus = new GradientDrawable();
34 | dotFocus.setColor(focusColor);
35 | dotFocus.setCornerRadius(LibUtils.dip2px(getContext(), 4));
36 | dotFocus.setSize(LibUtils.dip2px(getContext(), 8),
37 | LibUtils.dip2px(getContext(), 8));
38 | return dotFocus;
39 | }
40 |
41 | @Override
42 | public Drawable makeNormalDrawable() {
43 | GradientDrawable dotNormal = new GradientDrawable();
44 | dotNormal.setColor(normalColor);
45 | dotNormal.setCornerRadius(LibUtils.dip2px(getContext(), 4));
46 | dotNormal.setSize(LibUtils.dip2px(getContext(), 8),
47 | LibUtils.dip2px(getContext(), 8));
48 | return dotNormal;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/hintview/IconHintView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.hintview;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Matrix;
7 | import android.graphics.PixelFormat;
8 | import android.graphics.drawable.BitmapDrawable;
9 | import android.graphics.drawable.Drawable;
10 |
11 | import androidx.annotation.DrawableRes;
12 |
13 | import com.yc.cn.ycbannerlib.LibUtils;
14 |
15 | /**
16 | *
17 | * @author yangchong
18 | * blog : https://github.com/yangchong211
19 | * time : 2016/3/18
20 | * desc : icon
21 | * revise:
22 | *
23 | */
24 | public class IconHintView extends ShapeHintView {
25 |
26 | private int focusResId;
27 | private int normalResId;
28 | private int size;
29 |
30 |
31 | public IconHintView(Context context, @DrawableRes int focusResId, @DrawableRes int normalResId) {
32 | this(context, focusResId, normalResId, LibUtils.dip2px(context,32));
33 | }
34 |
35 | public IconHintView(Context context, @DrawableRes int focusResId,
36 | @DrawableRes int normalResId, int size) {
37 | super(context);
38 | this.focusResId = focusResId;
39 | this.normalResId = normalResId;
40 | this.size = size;
41 | }
42 |
43 | @Override
44 | public Drawable makeFocusDrawable() {
45 | Drawable drawable = getContext().getResources().getDrawable(focusResId);
46 | if (size>0){
47 | drawable = zoomDrawable(drawable,size,size);
48 | }
49 | return drawable;
50 | }
51 |
52 | @Override
53 | public Drawable makeNormalDrawable() {
54 | Drawable drawable = getContext().getResources().getDrawable(normalResId);
55 | if (size>0){
56 | drawable = zoomDrawable(drawable,size,size);
57 | }
58 | return drawable;
59 | }
60 |
61 | private Drawable zoomDrawable(Drawable drawable, int w, int h) {
62 | int width = drawable.getIntrinsicWidth();
63 | int height = drawable.getIntrinsicHeight();
64 | Bitmap oldBmp = drawableToBitmap(drawable);
65 | Matrix matrix = new Matrix();
66 | float scaleWidth = ((float) w / width);
67 | float scaleHeight = ((float) h / height);
68 | matrix.postScale(scaleWidth, scaleHeight);
69 | Bitmap newBmp = Bitmap.createBitmap(oldBmp, 0, 0, width, height, matrix, true);
70 | return new BitmapDrawable(null, newBmp);
71 | }
72 |
73 | private Bitmap drawableToBitmap(Drawable drawable) {
74 | int width = drawable.getIntrinsicWidth();
75 | int height = drawable.getIntrinsicHeight();
76 | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ?
77 | Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
78 | Bitmap bitmap = Bitmap.createBitmap(width, height, config);
79 | Canvas canvas = new Canvas(bitmap);
80 | drawable.setBounds(0, 0, width, height);
81 | drawable.draw(canvas);
82 | return bitmap;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/hintview/ShapeHintView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.hintview;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.Drawable;
5 | import android.util.AttributeSet;
6 | import android.view.Gravity;
7 | import android.widget.ImageView;
8 | import android.widget.LinearLayout;
9 |
10 | import com.yc.cn.ycbannerlib.banner.inter.BaseHintView;
11 |
12 | /**
13 | *
14 | * @author yangchong
15 | * blog : https://github.com/yangchong211
16 | * time : 2016/3/18
17 | * desc : shape图形
18 | * revise:
19 | *
20 | */
21 | public abstract class ShapeHintView extends LinearLayout implements BaseHintView {
22 |
23 | private ImageView[] mDots;
24 | private int length = 0;
25 | private int lastPosition = 0;
26 |
27 | private Drawable dotNormal;
28 | private Drawable dotFocus;
29 |
30 | public ShapeHintView(Context context){
31 | super(context);
32 | }
33 |
34 | public ShapeHintView(Context context, AttributeSet attrs) {
35 | super(context, attrs);
36 | }
37 |
38 |
39 | public abstract Drawable makeFocusDrawable();
40 |
41 | public abstract Drawable makeNormalDrawable();
42 |
43 | @Override
44 | public void initView(int length, int gravity) {
45 | removeAllViews();
46 | lastPosition = 0;
47 | setOrientation(HORIZONTAL);
48 | switch (gravity) {
49 | case 0:
50 | setGravity(Gravity.START| Gravity.CENTER_VERTICAL);
51 | break;
52 | case 1:
53 | setGravity(Gravity.CENTER);
54 | break;
55 | case 2:
56 | setGravity(Gravity.END| Gravity.CENTER_VERTICAL);
57 | break;
58 | default:
59 | break;
60 | }
61 |
62 | this.length = length;
63 | mDots = new ImageView[length];
64 |
65 | dotFocus = makeFocusDrawable();
66 | dotNormal = makeNormalDrawable();
67 |
68 | for (int i = 0; i < length; i++) {
69 | mDots[i]=new ImageView(getContext());
70 | LayoutParams dotLp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
71 | dotLp.setMargins(10, 0, 10, 0);
72 | mDots[i].setLayoutParams(dotLp);
73 | mDots[i].setBackgroundDrawable(dotNormal);
74 | addView(mDots[i]);
75 | }
76 | setCurrent(0);
77 | }
78 |
79 | @Override
80 | public void setCurrent(int current) {
81 | if (current < 0 || current > length - 1) {
82 | return;
83 | }
84 | mDots[lastPosition].setBackgroundDrawable(dotNormal);
85 | mDots[current].setBackgroundDrawable(dotFocus);
86 | lastPosition = current;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/hintview/TextHintView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.hintview;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.Color;
6 | import android.util.AttributeSet;
7 | import android.view.Gravity;
8 |
9 | import androidx.appcompat.widget.AppCompatTextView;
10 |
11 | import com.yc.cn.ycbannerlib.banner.inter.BaseHintView;
12 |
13 | /**
14 | *
15 | * @author yangchong
16 | * blog : https://github.com/yangchong211
17 | * time : 2016/3/18
18 | * desc : 文本
19 | * revise:
20 | *
21 | */
22 | public class TextHintView extends AppCompatTextView implements BaseHintView {
23 |
24 | private int length;
25 | public TextHintView(Context context){
26 | super(context);
27 | }
28 |
29 | public TextHintView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | }
32 |
33 | @Override
34 | public void initView(int length, int gravity) {
35 | this.length = length;
36 | setTextColor(Color.WHITE);
37 | switch (gravity) {
38 | case 0:
39 | setGravity(Gravity.START| Gravity.CENTER_VERTICAL);
40 | break;
41 | case 1:
42 | setGravity(Gravity.CENTER);
43 | break;
44 | case 2:
45 | setGravity(Gravity.END| Gravity.CENTER_VERTICAL);
46 | break;
47 | default:
48 | break;
49 | }
50 |
51 | setCurrent(0);
52 | }
53 |
54 | @SuppressLint("SetTextI18n")
55 | @Override
56 | public void setCurrent(int current) {
57 | setText(current+1+"/"+ length);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/inter/BaseHintView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.inter;
2 |
3 | /**
4 | *
5 | * @author yangchong
6 | * blog : https://github.com/yangchong211
7 | * time : 2016/3/18
8 | * desc : 所有指示器的接口
9 | * revise:
10 | *
11 | */
12 | public interface BaseHintView {
13 |
14 | void initView(int length, int gravity);
15 |
16 | void setCurrent(int current);
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/inter/HintViewDelegate.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.inter;
2 |
3 | /**
4 | *
5 | * @author yangchong
6 | * blog : https://github.com/yangchong211
7 | * time : 2016/3/18
8 | * desc :
9 | * revise:
10 | *
11 | */
12 | public interface HintViewDelegate {
13 |
14 | /**
15 | * 设置索引位置
16 | * @param position 索引
17 | * @param hintView HintView
18 | */
19 | void setCurrentPosition(int position, BaseHintView hintView);
20 |
21 | /**
22 | * 初始化view
23 | * @param length length
24 | * @param gravity 位置
25 | * @param hintView HintView
26 | */
27 | void initView(int length, int gravity, BaseHintView hintView);
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/view/BannerConstant.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.view;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.RetentionPolicy;
5 |
6 | public class BannerConstant {
7 |
8 |
9 | /**
10 | * 不建议用枚举,可以用注解替代
11 | * 轮播图红点是0,数字是1
12 | * 后期还可以加入其他的
13 | */
14 | @Retention(RetentionPolicy.SOURCE)
15 | public @interface HintMode {
16 | int COLOR_POINT_HINT = 0;
17 | int TEXT_HINT = 1;
18 | }
19 |
20 | @Retention(RetentionPolicy.SOURCE)
21 | public @interface HintGravity {
22 | int LEFT = 1;
23 | int CENTER = 2;
24 | int RIGHT = 3;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/banner/view/BannerViewPager.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.banner.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 |
7 | import androidx.viewpager.widget.ViewPager;
8 |
9 | public class BannerViewPager extends ViewPager {
10 |
11 | private boolean scrollable = true;
12 |
13 | public BannerViewPager(Context context) {
14 | super(context);
15 | }
16 |
17 | public BannerViewPager(Context context, AttributeSet attrs) {
18 | super(context, attrs);
19 | }
20 |
21 | @Override
22 | public boolean onTouchEvent(MotionEvent ev) {
23 | if(this.scrollable) {
24 | if (getCurrentItem() == 0 && getChildCount() == 0) {
25 | return false;
26 | }
27 | return super.onTouchEvent(ev);
28 | } else {
29 | return false;
30 | }
31 | }
32 |
33 | @Override
34 | public boolean onInterceptTouchEvent(MotionEvent ev) {
35 | if(this.scrollable) {
36 | if (getCurrentItem() == 0 && getChildCount() == 0) {
37 | return false;
38 | }
39 | return super.onInterceptTouchEvent(ev);
40 | } else {
41 | return false;
42 | }
43 | }
44 |
45 | public void setScrollable(boolean scrollable) {
46 | this.scrollable = scrollable;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/java/com/yc/cn/ycbannerlib/marquee/MarqueeView.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbannerlib.marquee;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.text.TextUtils;
7 | import android.util.AttributeSet;
8 | import android.view.Gravity;
9 | import android.view.View;
10 | import android.view.ViewTreeObserver;
11 | import android.view.animation.Animation;
12 | import android.view.animation.AnimationUtils;
13 | import android.widget.TextView;
14 | import android.widget.ViewFlipper;
15 | import com.yc.cn.ycbannerlib.R;
16 | import java.util.ArrayList;
17 |
18 | /**
19 | *
20 | * @author yangchong
21 | * blog : https://github.com/yangchong211
22 | * time : 2017/1/18
23 | * desc : v1.0 17年1月18日
24 | * v1.1 17年4月7日
25 | * revise:
26 | *
27 | */
28 | public class MarqueeView extends ViewFlipper {
29 |
30 | private Context mContext;
31 | private ArrayList notices;
32 | private boolean isSetAnimDuration = false;
33 | private OnItemClickListener onItemClickListener;
34 |
35 | private int interval = 2000;
36 | private int animDuration = 500;
37 | private int textSize = 14;
38 | private int textColor = 0xffffffff;
39 |
40 | private boolean singleLine = false;
41 | private int gravity = Gravity.START | Gravity.CENTER_VERTICAL;
42 | private static final int TEXT_GRAVITY_LEFT = 0, TEXT_GRAVITY_CENTER = 1, TEXT_GRAVITY_RIGHT = 2;
43 |
44 | public MarqueeView(Context context, AttributeSet attrs) {
45 | super(context, attrs);
46 | init(context, attrs, 0);
47 | }
48 |
49 | private void init(Context context, AttributeSet attrs, int defStyleAttr) {
50 | this.mContext = context;
51 | if (notices == null) {
52 | notices = new ArrayList<>();
53 | }
54 |
55 | @SuppressLint("CustomViewStyleable")
56 | TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MarqueeViewStyle, defStyleAttr, 0);
57 | interval = typedArray.getInteger(R.styleable.MarqueeViewStyle_mvInterval, interval);
58 | isSetAnimDuration = typedArray.hasValue(R.styleable.MarqueeViewStyle_mvAnimDuration);
59 | singleLine = typedArray.getBoolean(R.styleable.MarqueeViewStyle_mvSingleLine, false);
60 | animDuration = typedArray.getInteger(R.styleable.MarqueeViewStyle_mvAnimDuration, animDuration);
61 | if (typedArray.hasValue(R.styleable.MarqueeViewStyle_mvTextSize)) {
62 | textSize = (int) typedArray.getDimension(R.styleable.MarqueeViewStyle_mvTextSize, textSize);
63 | textSize = px2sp(mContext, textSize);
64 | }
65 | textColor = typedArray.getColor(R.styleable.MarqueeViewStyle_mvTextColor, textColor);
66 | int gravityType = typedArray.getInt(R.styleable.MarqueeViewStyle_mvGravity, TEXT_GRAVITY_LEFT);
67 | switch (gravityType) {
68 | case TEXT_GRAVITY_CENTER:
69 | gravity = Gravity.CENTER;
70 | break;
71 | case TEXT_GRAVITY_RIGHT:
72 | gravity = Gravity.START | Gravity.CENTER_VERTICAL;
73 | break;
74 | default:
75 | break;
76 | }
77 | typedArray.recycle();
78 |
79 | setFlipInterval(interval);
80 | }
81 |
82 | /**
83 | * 根据公告字符串启动轮播
84 | * @param notice 公告
85 | */
86 | public void startWithText(final String notice) {
87 | if (TextUtils.isEmpty(notice)) {
88 | return;
89 | }
90 | getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
91 | @Override
92 | public void onGlobalLayout() {
93 | getViewTreeObserver().removeGlobalOnLayoutListener(this);
94 | startWithFixedWidth(notice, getWidth());
95 | }
96 | });
97 | }
98 |
99 | /**
100 | * 根据公告字符串列表启动轮播
101 | * @param notices 公告集合
102 | */
103 | public void startWithList(ArrayList notices) {
104 | setNotices(notices);
105 | start();
106 | }
107 |
108 | /**
109 | * 根据宽度和公告字符串启动轮播
110 | * @param notice 公告
111 | * @param width width
112 | */
113 | private void startWithFixedWidth(String notice, int width) {
114 | int noticeLength = notice.length();
115 | int dpW = px2dip(mContext, width);
116 | int limit = dpW / textSize;
117 | if (dpW == 0) {
118 | throw new RuntimeException("Please set MarqueeView width !");
119 | }
120 | ArrayList list = new ArrayList<>();
121 | if (noticeLength <= limit) {
122 | list.add(notice);
123 | } else {
124 | int size = noticeLength / limit + (noticeLength % limit != 0 ? 1 : 0);
125 | for (int i = 0; i < size; i++) {
126 | int startIndex = i * limit;
127 | int endIndex = ((i + 1) * limit >= noticeLength ? noticeLength : (i + 1) * limit);
128 | list.add(notice.substring(startIndex, endIndex));
129 | }
130 | }
131 | notices.addAll(list);
132 | start();
133 | }
134 |
135 | /**
136 | * 启动轮播
137 | * @return 是否启动轮播
138 | */
139 | public boolean start() {
140 | if (notices == null || notices.size() == 0) {
141 | return false;
142 | }
143 | //先移除所有view
144 | removeAllViews();
145 | //然后重置动画
146 | resetAnimation();
147 |
148 | //根据设置的数据集合数量创建TextView
149 | for (int i = 0; i < notices.size(); i++) {
150 | final TextView textView = createTextView(notices.get(i), i);
151 | final int finalI = i;
152 | textView.setOnClickListener(new OnClickListener() {
153 | @Override
154 | public void onClick(View v) {
155 | if (onItemClickListener != null) {
156 | onItemClickListener.onItemClick(finalI, textView);
157 | }
158 | }
159 | });
160 | addView(textView);
161 | }
162 |
163 | //如果集合数目大于1,则开始;否则停止
164 | if (notices.size() > 1) {
165 | startFlipping();
166 | } else {
167 | stopFlipping();
168 | }
169 | return true;
170 | }
171 |
172 |
173 | /**
174 | * 重置动画
175 | */
176 | private void resetAnimation(){
177 | clearAnimation();
178 | //设置进入的动画
179 | Animation animIn = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_in);
180 | if (isSetAnimDuration) {
181 | animIn.setDuration(animDuration);
182 | }
183 | setInAnimation(animIn);
184 |
185 | //设置结束的动画
186 | Animation animOut = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_out);
187 | if (isSetAnimDuration) {
188 | animOut.setDuration(animDuration);
189 | }
190 | setOutAnimation(animOut);
191 | }
192 |
193 | /**
194 | * 创建ViewFlipper下的TextView
195 | * @param text text
196 | * @param position position
197 | * @return TextView
198 | */
199 | private TextView createTextView(CharSequence text, int position) {
200 | TextView tv = new TextView(mContext);
201 | tv.setGravity(gravity);
202 | tv.setText(text);
203 | tv.setTextColor(textColor);
204 | tv.setTextSize(textSize);
205 | tv.setSingleLine(singleLine);
206 | tv.setTag(position);
207 | return tv;
208 | }
209 |
210 | /**
211 | * 获取当前索引位置
212 | * @return 索引
213 | */
214 | public int getPosition() {
215 | return (int) getCurrentView().getTag();
216 | }
217 |
218 | public ArrayList getNotices() {
219 | return notices;
220 | }
221 |
222 | /**
223 | * 设置数据集合
224 | * @param notices 数据
225 | */
226 | public void setNotices(ArrayList notices) {
227 | this.notices = notices;
228 | }
229 |
230 | /**
231 | * 设置点击事件
232 | * @param onItemClickListener 点击事件listener
233 | */
234 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
235 | this.onItemClickListener = onItemClickListener;
236 | }
237 | public interface OnItemClickListener {
238 | void onItemClick(int position, TextView textView);
239 | }
240 |
241 |
242 | public static int px2sp(Context context, float pxValue) {
243 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
244 | return (int) (pxValue / fontScale + 0.5f);
245 | }
246 |
247 | public static int px2dip(Context ctx, float pxValue) {
248 | final float scale = ctx.getResources().getDisplayMetrics().density;
249 | return (int) (pxValue / scale + 0.5f);
250 | }
251 |
252 | }
253 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/res/anim/anim_marquee_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/res/anim/anim_marquee_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/YCBannerLib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | YCBannerLib
3 |
4 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply from: rootProject.projectDir.absolutePath + "/AppGradle/appBuild.gradle"
3 |
4 | android {
5 | compileSdkVersion project.ext.androidCompileSdkVersion
6 | //buildToolsVersion project.ext.androidBuildToolsVersion
7 | defaultConfig {
8 | applicationId "com.yc.cn.ycbanner"
9 | minSdkVersion project.ext.androidMinSdkVersion
10 | targetSdkVersion project.ext.androidTargetSdkVersion
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | implementation project.ext.AppDependencies['appcompat']
25 | implementation project.ext.AppDependencies['recyclerview']
26 | implementation project.ext.AppDependencies['media']
27 | compile project(':YCBannerLib')
28 | compile project(':GalleryBannerLib')
29 | compile project(':SnapBannerLib')
30 | // compile 'cn.yc:YCBannerLib:1.4.0' //轮播图
31 | compile 'cn.yc:YCStatusBarLib:1.4.0'
32 | compile 'cn.yc:YCBaseAdapterLib:1.3.4'
33 | compile 'cn.yc:YCUtilsLib:1.6.2'
34 | compile 'cn.yc:YCStatusBarLib:1.4.0'
35 | }
36 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\PC\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/EightActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.content.res.TypedArray;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.graphics.drawable.Drawable;
8 | import android.graphics.drawable.TransitionDrawable;
9 | import android.os.Bundle;
10 | import android.util.Log;
11 | import android.view.View;
12 | import android.widget.FrameLayout;
13 |
14 |
15 | import androidx.annotation.Nullable;
16 | import androidx.appcompat.app.AppCompatActivity;
17 | import androidx.recyclerview.widget.LinearLayoutManager;
18 | import androidx.recyclerview.widget.RecyclerView;
19 |
20 | import com.ns.yc.ycutilslib.blurView.blur.CustomBlur;
21 | import com.yc.gallerybannerlib.GalleryLayoutManager;
22 | import com.yc.gallerybannerlib.GalleryRecyclerView;
23 | import com.yc.gallerybannerlib.GalleryScaleTransformer;
24 |
25 | import java.util.ArrayList;
26 | import java.util.HashMap;
27 | import java.util.Map;
28 |
29 | import cn.ycbjie.ycstatusbarlib.bar.StateAppBar;
30 |
31 | public class EightActivity extends AppCompatActivity {
32 |
33 | private GalleryRecyclerView mRecyclerView;
34 | private RecyclerView recyclerView2;
35 | private ArrayList data = new ArrayList<>();
36 | private FrameLayout fl_container;
37 |
38 | @Override
39 | protected void onDestroy() {
40 | super.onDestroy();
41 | if (mRecyclerView!=null){
42 | mRecyclerView.release();
43 | }
44 | }
45 |
46 | @Override
47 | protected void onStart() {
48 | super.onStart();
49 | if (mRecyclerView!=null){
50 | mRecyclerView.onStart();
51 | }
52 | }
53 |
54 | @Override
55 | protected void onStop() {
56 | super.onStop();
57 | if (mRecyclerView!=null){
58 | mRecyclerView.onStop();
59 | }
60 | }
61 |
62 | @Override
63 | protected void onCreate(@Nullable Bundle savedInstanceState) {
64 | super.onCreate(savedInstanceState);
65 | setContentView(R.layout.activity_eight);
66 | StateAppBar.translucentStatusBar(this,true);
67 | mRecyclerView = findViewById(R.id.recyclerView);
68 | recyclerView2 = findViewById(R.id.recyclerView2);
69 | fl_container = findViewById(R.id.fl_container);
70 | initRecyclerView();
71 | initRecyclerView2();
72 | }
73 |
74 | private void initRecyclerView() {
75 | Snap3Adapter adapter = new Snap3Adapter(this);
76 | adapter.setData(getData());
77 | mRecyclerView.setDelayTime(3000)
78 | .setFlingSpeed(10000)
79 | .setDataAdapter(adapter)
80 | .setSelectedPosition(100)
81 | .setCallbackInFling(false)
82 | .setOnItemSelectedListener(new GalleryRecyclerView.OnItemSelectedListener() {
83 | @Override
84 | public void onItemSelected(RecyclerView recyclerView, View item, int position) {
85 | Log.e("onItemSelected-----",position+"");
86 | //设置高斯模糊背景
87 | setBlurImage(true);
88 | }
89 | })
90 | .setSize(adapter.getData().size())
91 | .setUp();
92 | }
93 |
94 |
95 | private void initRecyclerView2() {
96 | GalleryLayoutManager manager = new GalleryLayoutManager(this, LinearLayoutManager.HORIZONTAL);
97 | manager.attach(recyclerView2,100);
98 | manager.setItemTransformer(new GalleryScaleTransformer( 0.2f,30));
99 | recyclerView2.setLayoutManager(manager);
100 | Snap3Adapter adapter = new Snap3Adapter(this);
101 | adapter.setData(getData());
102 | recyclerView2.setAdapter(adapter);
103 | }
104 |
105 |
106 | private ArrayList getData(){
107 | TypedArray bannerImage = getResources().obtainTypedArray(R.array.banner_image);
108 | for (int i = 0; i < 12 ; i++) {
109 | int image = bannerImage.getResourceId(i, R.drawable.beauty1);
110 | data.add(image);
111 | }
112 | bannerImage.recycle();
113 | return data;
114 | }
115 |
116 |
117 | /**
118 | * 获取虚化背景的位置
119 | */
120 | private int mLastDraPosition = -1;
121 | private Map mTSDraCacheMap = new HashMap<>();
122 | private static final String KEY_PRE_DRAW = "key_pre_draw";
123 | /**
124 | * 设置背景高斯模糊
125 | */
126 | public void setBlurImage(boolean forceUpdate) {
127 | final Snap3Adapter adapter = (Snap3Adapter) mRecyclerView.getAdapter();
128 | final int mCurViewPosition = mRecyclerView.getCurrentItem();
129 |
130 | boolean isSamePosAndNotUpdate = (mCurViewPosition == mLastDraPosition) && !forceUpdate;
131 |
132 | if (adapter == null || mRecyclerView == null || isSamePosAndNotUpdate) {
133 | return;
134 | }
135 | mRecyclerView.post(new Runnable() {
136 | @Override
137 | public void run() {
138 | // 获取当前位置的图片资源ID
139 | int resourceId = adapter.getData().get(mCurViewPosition%adapter.getData().size());
140 | // 将该资源图片转为Bitmap
141 | Bitmap resBmp = BitmapFactory.decodeResource(getResources(), resourceId);
142 | // 将该Bitmap高斯模糊后返回到resBlurBmp
143 | Bitmap resBlurBmp = CustomBlur.apply(mRecyclerView.getContext(), resBmp, 10);
144 | // 再将resBlurBmp转为Drawable
145 | Drawable resBlurDrawable = new BitmapDrawable(resBlurBmp);
146 | // 获取前一页的Drawable
147 | Drawable preBlurDrawable = mTSDraCacheMap.get(KEY_PRE_DRAW) == null ? resBlurDrawable : mTSDraCacheMap.get(KEY_PRE_DRAW);
148 |
149 | /* 以下为淡入淡出效果 */
150 | Drawable[] drawableArr = {preBlurDrawable, resBlurDrawable};
151 | TransitionDrawable transitionDrawable = new TransitionDrawable(drawableArr);
152 | fl_container.setBackgroundDrawable(transitionDrawable);
153 | transitionDrawable.startTransition(500);
154 |
155 | // 存入到cache中
156 | mTSDraCacheMap.put(KEY_PRE_DRAW, resBlurDrawable);
157 | // 记录上一次高斯模糊的位置
158 | mLastDraPosition = mCurViewPosition;
159 | }
160 | });
161 | }
162 |
163 |
164 |
165 | }
166 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/FirstActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.Toast;
10 |
11 | import androidx.annotation.Nullable;
12 | import androidx.appcompat.app.AppCompatActivity;
13 |
14 | import com.yc.cn.ycbannerlib.banner.view.BannerConstant;
15 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
16 | import com.yc.cn.ycbannerlib.banner.adapter.AbsLoopPagerAdapter;
17 |
18 |
19 | /**
20 | * Created by PC on 2017/11/21.
21 | * 作者:PC
22 | */
23 |
24 | public class FirstActivity extends AppCompatActivity {
25 |
26 |
27 | private int[] imgs = {
28 | R.drawable.bg_kites_min,
29 | R.drawable.bg_autumn_tree_min,
30 | R.drawable.bg_lake_min,
31 | R.drawable.bg_leaves_min,
32 | R.drawable.bg_magnolia_trees_min,
33 | };
34 | private BannerView banner;
35 |
36 | @Override
37 | protected void onDestroy() {
38 | super.onDestroy();
39 | }
40 |
41 | @Override
42 | protected void onPause() {
43 | super.onPause();
44 | if(banner!=null){
45 | //停止轮播
46 | banner.pause();
47 | }
48 | }
49 |
50 | @Override
51 | protected void onResume() {
52 | super.onResume();
53 | if(banner!=null){
54 | //开始轮播
55 | banner.resume();
56 | }
57 | }
58 |
59 | @Override
60 | protected void onCreate(@Nullable Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | setContentView(R.layout.activity_first);
63 |
64 | initBanner();
65 | }
66 |
67 | private void initBanner() {
68 | banner = (BannerView) findViewById(R.id.banner);
69 | //设置轮播时间
70 | banner.setPlayDelay(2000);
71 | //设置轮播图适配器,必须
72 | banner.setAdapter(new ImageNormalAdapter(banner));
73 | //设置位置
74 | banner.setHintGravity(1);
75 | banner.setHintPadding(20,0, 20,20);
76 | //判断轮播是否进行
77 | boolean playing = banner.isPlaying();
78 | //轮播图点击事件
79 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
80 | @Override
81 | public void onItemClick(int position) {
82 | Toast.makeText(FirstActivity.this,position+"被点击呢",Toast.LENGTH_SHORT).show();
83 | }
84 | });
85 | //轮播图滑动事件
86 | banner.setOnPageListener(new BannerView.OnPageListener() {
87 | @Override
88 | public void onPageChange(int position) {
89 |
90 | }
91 | });
92 | }
93 |
94 |
95 | private class ImageNormalAdapter extends AbsLoopPagerAdapter {
96 |
97 | public ImageNormalAdapter(BannerView viewPager) {
98 | super(viewPager);
99 | }
100 |
101 | @Override
102 | public View getView(ViewGroup container, int position) {
103 | ImageView view = new ImageView(container.getContext());
104 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
105 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
106 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs[position]);
107 | Bitmap bitmap1 = ImageBitmapUtils.compressByQuality(bitmap, 50, false);
108 | view.setImageBitmap(bitmap1);
109 | return view;
110 | }
111 |
112 | @Override
113 | public int getRealCount() {
114 | return imgs.length;
115 | }
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/FourActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.Toast;
10 |
11 | import androidx.annotation.Nullable;
12 | import androidx.appcompat.app.AppCompatActivity;
13 |
14 | import com.yc.cn.ycbannerlib.banner.adapter.AbsStaticPagerAdapter;
15 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
16 | import com.yc.cn.ycbannerlib.banner.adapter.AbsLoopPagerAdapter;
17 | import com.yc.cn.ycbannerlib.banner.hintview.TextHintView;
18 |
19 | /**
20 | * Created by PC on 2017/11/21.
21 | * 作者:PC
22 | */
23 |
24 | public class FourActivity extends AppCompatActivity {
25 |
26 | private int[] imgs = {
27 | R.drawable.bg_kites_min,
28 | R.drawable.bg_autumn_tree_min,
29 | R.drawable.bg_lake_min,
30 | R.drawable.bg_leaves_min,
31 | R.drawable.bg_magnolia_trees_min,
32 | };
33 | private BannerView banner;
34 |
35 | @Override
36 | protected void onDestroy() {
37 | super.onDestroy();
38 | }
39 |
40 | @Override
41 | protected void onPause() {
42 | super.onPause();
43 | if(banner!=null){
44 | banner.pause();
45 | }
46 | }
47 |
48 | @Override
49 | protected void onResume() {
50 | super.onResume();
51 | if(banner!=null){
52 | banner.resume();
53 | }
54 | }
55 |
56 | @Override
57 | protected void onCreate(@Nullable Bundle savedInstanceState) {
58 | super.onCreate(savedInstanceState);
59 | setContentView(R.layout.activity_four);
60 |
61 | initBanner();
62 | }
63 |
64 | private void initBanner() {
65 | banner = (BannerView) findViewById(R.id.banner);
66 | banner.setHintPadding(0, 20, 20,20);
67 | banner.setHintView(new TextHintView(this));
68 | banner.setAdapter(new ImageNormalAdapter());
69 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
70 | @Override
71 | public void onItemClick(int position) {
72 | Toast.makeText(FourActivity.this,
73 | position+"被点击呢",Toast.LENGTH_SHORT).show();
74 | }
75 | });
76 | }
77 |
78 |
79 |
80 | private class ImageNormalAdapter extends AbsStaticPagerAdapter {
81 |
82 | @Override
83 | public View getView(ViewGroup container, int position) {
84 | ImageView view = new ImageView(container.getContext());
85 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
86 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
87 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs[position]);
88 | Bitmap bitmap1 = ImageBitmapUtils.compressByQuality(bitmap, 50, false);
89 | view.setImageBitmap(bitmap1);
90 | return view;
91 | }
92 |
93 | @Override
94 | public int getCount() {
95 | return imgs.length;
96 | }
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/ImageBitmapUtils.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 |
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Matrix;
8 | import android.util.Log;
9 |
10 | import androidx.annotation.IntRange;
11 |
12 | import java.io.ByteArrayOutputStream;
13 |
14 | /**
15 | *
16 | * @author 杨充
17 | * blog : https://github.com/yangchong211
18 | * time : 2017/11/26
19 | * desc : bitmap优化压缩工具类
20 | * revise: 针对每个工具类,方法以及参数必须标注清晰
21 | *
22 | */
23 | public class ImageBitmapUtils {
24 |
25 | /*
26 | 质量压缩方法:在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的:
27 | 1、bitmap图片的大小不会改变
28 | 2、bytes.length是随着quality变小而变小的。
29 | 这样适合去传递二进制的图片数据,比如分享图片,要传入二进制数据过去,限制500kb之内。
30 | */
31 | /**
32 | * 第一种:质量压缩法
33 | * @param image 目标原图
34 | * @param maxSize 最大的图片大小
35 | * @return bitmap,注意可以测试以下压缩前后bitmap的大小值
36 | */
37 | public static Bitmap compressImage(Bitmap image , long maxSize) {
38 | int byteCount = image.getByteCount();
39 | Log.i("yc压缩图片","压缩前大小"+byteCount);
40 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
41 | // 把ByteArrayInputStream数据生成图片
42 | Bitmap bitmap = null;
43 | // 质量压缩方法,options的值是0-100,这里100表示原来图片的质量,不压缩,把压缩后的数据存放到baos中
44 | image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
45 | int options = 90;
46 | // 循环判断如果压缩后图片是否大于maxSize,大于继续压缩
47 | while (baos.toByteArray().length > maxSize) {
48 | // 重置baos即清空baos
49 | baos.reset();
50 | // 这里压缩options%,把压缩后的数据存放到baos中
51 | image.compress(Bitmap.CompressFormat.JPEG, options, baos);
52 | // 每次都减少10,当为1的时候停止,options<10的时候,递减1
53 | if(options == 1){
54 | break;
55 | }else if (options <= 10) {
56 | options -= 1;
57 | } else {
58 | options -= 10;
59 | }
60 | }
61 | byte[] bytes = baos.toByteArray();
62 | if (bytes.length != 0) {
63 | // 把压缩后的数据baos存放到bytes中
64 | bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
65 | int byteCount1 = bitmap.getByteCount();
66 | Log.i("yc压缩图片","压缩后大小"+byteCount1);
67 | }
68 | return bitmap;
69 | }
70 |
71 |
72 | /**
73 | * 第一种:质量压缩法
74 | *
75 | * @param src 源图片
76 | * @param maxByteSize 允许最大值字节数
77 | * @param recycle 是否回收
78 | * @return 质量压缩压缩过的图片
79 | */
80 | public static Bitmap compressByQuality1(final Bitmap src, long maxByteSize, final boolean recycle) {
81 | if (src == null || src.getWidth() == 0 || src.getHeight() == 0 || maxByteSize <= 0) {
82 | return null;
83 | }
84 | Log.i("yc压缩图片","压缩前大小"+src.getByteCount());
85 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
86 | src.compress(Bitmap.CompressFormat.JPEG, 100, baos);
87 | byte[] bytes;
88 | if (baos.size() <= maxByteSize) {// 最好质量的不大于最大字节,则返回最佳质量
89 | bytes = baos.toByteArray();
90 | } else {
91 | baos.reset();
92 | src.compress(Bitmap.CompressFormat.JPEG, 0, baos);
93 | if (baos.size() >= maxByteSize) { // 最差质量不小于最大字节,则返回最差质量
94 | bytes = baos.toByteArray();
95 | } else {
96 | // 二分法寻找最佳质量
97 | int st = 0;
98 | int end = 100;
99 | int mid = 0;
100 | while (st < end) {
101 | mid = (st + end) / 2;
102 | baos.reset();
103 | src.compress(Bitmap.CompressFormat.JPEG, mid, baos);
104 | int len = baos.size();
105 | if (len == maxByteSize) {
106 | break;
107 | } else if (len > maxByteSize) {
108 | end = mid - 1;
109 | } else {
110 | st = mid + 1;
111 | }
112 | }
113 | if (end == mid - 1) {
114 | baos.reset();
115 | src.compress(Bitmap.CompressFormat.JPEG, st, baos);
116 | }
117 | bytes = baos.toByteArray();
118 | }
119 | }
120 | if (recycle && !src.isRecycled()){
121 | src.recycle();
122 | }
123 | Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
124 | Log.i("yc压缩图片","压缩后大小"+bitmap.getByteCount());
125 | return bitmap;
126 | }
127 |
128 |
129 | /**
130 | * 第一种:质量压缩法
131 | *
132 | * @param src 源图片
133 | * @param quality 质量
134 | * @param recycle 是否回收
135 | * @return 质量压缩后的图片
136 | */
137 | public static Bitmap compressByQuality(final Bitmap src, @IntRange(from = 0, to = 100) final int quality, final boolean recycle) {
138 | if (src == null || src.getWidth() == 0 || src.getHeight() == 0) {
139 | return null;
140 | }
141 | Log.i("yc压缩图片","压缩前大小"+src.getByteCount());
142 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
143 | src.compress(Bitmap.CompressFormat.JPEG, quality, baos);
144 | byte[] bytes = baos.toByteArray();
145 | if (recycle && !src.isRecycled()) {
146 | src.recycle();
147 | }
148 | Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
149 | Log.i("yc压缩图片","压缩后大小"+bitmap.getByteCount());
150 | return bitmap;
151 | }
152 |
153 |
154 |
155 | /**
156 | * 第二种:按采样大小压缩
157 | *
158 | * @param src 源图片
159 | * @param sampleSize 采样率大小
160 | * @param recycle 是否回收
161 | * @return 按采样率压缩后的图片
162 | */
163 | public static Bitmap compressBySampleSize(final Bitmap src, final int sampleSize, final boolean recycle) {
164 | if (src == null || src.getWidth() == 0 || src.getHeight() == 0) {
165 | return null;
166 | }
167 | Log.i("yc压缩图片","压缩前大小"+src.getByteCount());
168 | BitmapFactory.Options options = new BitmapFactory.Options();
169 | options.inSampleSize = sampleSize;
170 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
171 | src.compress(Bitmap.CompressFormat.JPEG, 100, baos);
172 | byte[] bytes = baos.toByteArray();
173 | if (recycle && !src.isRecycled()) {
174 | src.recycle();
175 | }
176 | Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
177 | Log.i("yc压缩图片","压缩后大小"+bitmap.getByteCount());
178 | return bitmap;
179 | }
180 |
181 |
182 | /**
183 | * 第二种:按采样大小压缩
184 | *
185 | * @param src 源图片
186 | * @param maxWidth 最大宽度
187 | * @param maxHeight 最大高度
188 | * @param recycle 是否回收
189 | * @return 按采样率压缩后的图片
190 | */
191 | public static Bitmap compressBySampleSize(final Bitmap src, final int maxWidth, final int maxHeight, final boolean recycle) {
192 | if (src == null || src.getWidth() == 0 || src.getHeight() == 0) {
193 | return null;
194 | }
195 | Log.i("yc压缩图片","压缩前大小"+src.getByteCount());
196 | BitmapFactory.Options options = new BitmapFactory.Options();
197 | options.inJustDecodeBounds = true;
198 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
199 | src.compress(Bitmap.CompressFormat.JPEG, 100, baos);
200 | byte[] bytes = baos.toByteArray();
201 | BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
202 | options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
203 | options.inJustDecodeBounds = false;
204 | if (recycle && !src.isRecycled()) {
205 | src.recycle();
206 | }
207 | Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
208 | Log.i("yc压缩图片","压缩后大小"+bitmap.getByteCount());
209 | return bitmap;
210 | }
211 |
212 | /**
213 | * 计算获取缩放比例inSampleSize
214 | */
215 | private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
216 | final int height = options.outHeight;
217 | final int width = options.outWidth;
218 | int inSampleSize = 1;
219 | if (height > reqHeight || width > reqWidth) {
220 | final int heightRatio = Math.round((float) height / (float) reqHeight);
221 | final int widthRatio = Math.round((float) width / (float) reqWidth);
222 | inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
223 | }
224 | final float totalPixels = width * height;
225 | final float totalReqPixelsCap = reqWidth * reqHeight * 2;
226 | while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
227 | inSampleSize++;
228 | }
229 | return inSampleSize;
230 | }
231 |
232 |
233 | /**
234 | * 第三种:按缩放压缩
235 | *
236 | * @param src 源图片
237 | * @param newWidth 新宽度
238 | * @param newHeight 新高度
239 | * @param recycle 是否回收
240 | * @return 缩放压缩后的图片
241 | */
242 | public static Bitmap compressByScale(final Bitmap src, final int newWidth, final int newHeight, final boolean recycle) {
243 | return scale(src, newWidth, newHeight, recycle);
244 | }
245 |
246 | /**
247 | * 第三种:按缩放压缩
248 | *
249 | * @param src 源图片
250 | * @param scaleWidth 缩放宽度倍数
251 | * @param scaleHeight 缩放高度倍数
252 | * @param recycle 是否回收
253 | * @return 缩放压缩后的图片
254 | */
255 | public static Bitmap compressByScale(final Bitmap src, final float scaleWidth, final float scaleHeight, final boolean recycle) {
256 | return scale(src, scaleWidth, scaleHeight, recycle);
257 | }
258 |
259 | /**
260 | * 缩放图片
261 | *
262 | * @param src 源图片
263 | * @param scaleWidth 缩放宽度倍数
264 | * @param scaleHeight 缩放高度倍数
265 | * @param recycle 是否回收
266 | * @return 缩放后的图片
267 | */
268 | private static Bitmap scale(final Bitmap src, final float scaleWidth, final float scaleHeight, final boolean recycle) {
269 | if (src == null || src.getWidth() == 0 || src.getHeight() == 0) {
270 | return null;
271 | }
272 | Matrix matrix = new Matrix();
273 | matrix.setScale(scaleWidth, scaleHeight);
274 | Bitmap ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
275 | if (recycle && !src.isRecycled()) {
276 | src.recycle();
277 | }
278 | return ret;
279 | }
280 |
281 |
282 | }
283 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.content.Intent;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Color;
7 | import android.os.Build;
8 | import android.os.Bundle;
9 | import android.text.SpannableString;
10 | import android.text.Spanned;
11 | import android.text.style.ForegroundColorSpan;
12 | import android.text.style.URLSpan;
13 | import android.util.Log;
14 | import android.view.View;
15 | import android.widget.TextView;
16 |
17 | import androidx.annotation.RequiresApi;
18 | import androidx.appcompat.app.AppCompatActivity;
19 |
20 | import com.yc.cn.ycbannerlib.marquee.MarqueeView;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 | import java.util.concurrent.atomic.AtomicInteger;
25 |
26 | public class MainActivity extends AppCompatActivity implements View.OnClickListener {
27 |
28 | private MarqueeView marqueeView;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_main);
34 |
35 | findViewById(R.id.tv_1).setOnClickListener(this);
36 | findViewById(R.id.tv_2).setOnClickListener(this);
37 | findViewById(R.id.tv_3).setOnClickListener(this);
38 | findViewById(R.id.tv_4).setOnClickListener(this);
39 | findViewById(R.id.tv_5).setOnClickListener(this);
40 | findViewById(R.id.tv_6).setOnClickListener(this);
41 | findViewById(R.id.tv_7).setOnClickListener(this);
42 | findViewById(R.id.tv_8).setOnClickListener(this);
43 | findViewById(R.id.tv_9).setOnClickListener(this);
44 | marqueeView = findViewById(R.id.marqueeView);
45 | initMarqueeView();
46 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
47 | initBitmap();
48 | }
49 | }
50 |
51 |
52 | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
53 | private void initBitmap() {
54 | BitmapFactory.Options options = new BitmapFactory.Options();
55 | // 图片复用,这个属性必须设置;
56 | options.inMutable = true;
57 | // 手动设置缩放比例,使其取整数,方便计算、观察数据;
58 | options.inDensity = 320;
59 | options.inTargetDensity = 320;
60 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_autumn_tree_min, options);
61 | // 对象内存地址;
62 | Log.i("ycBitmap", "bitmap = " + bitmap);
63 | Log.i("ycBitmap", "ByteCount = " + bitmap.getByteCount() + ":::bitmap:AllocationByteCount = " + bitmap.getAllocationByteCount());
64 | // 使用inBitmap属性,这个属性必须设置;
65 | options.inBitmap = bitmap; options.inDensity = 320;
66 | // 设置缩放宽高为原始宽高一半;
67 | options.inTargetDensity = 160;
68 | options.inMutable = true;
69 | Bitmap bitmapReuse = BitmapFactory.decodeResource(getResources(), R.drawable.bg_kites_min, options);
70 | // 复用对象的内存地址;
71 | Log.i("ycBitmap", "bitmapReuse = " + bitmapReuse);
72 | Log.i("ycBitmap", "bitmap:ByteCount = " + bitmap.getByteCount() + ":::bitmap:AllocationByteCount = " + bitmap.getAllocationByteCount());
73 | Log.i("ycBitmap", "bitmapReuse:ByteCount = " + bitmapReuse.getByteCount() + ":::bitmapReuse:AllocationByteCount = " + bitmapReuse.getAllocationByteCount());
74 |
75 | //11-26 18:24:07.971 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap = android.graphics.Bitmap@9739bff
76 | //11-26 18:24:07.972 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap:ByteCount = 4346880:::bitmap:AllocationByteCount = 4346880
77 | //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmapReuse = android.graphics.Bitmap@9739bff
78 | //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmap:ByteCount = 1228800:::bitmap:AllocationByteCount = 4346880
79 | //11-26 18:24:07.994 15470-15470/com.yc.cn.ycbanner I/ycBitmap: bitmapReuse:ByteCount = 1228800:::bitmapReuse:AllocationByteCount = 4346880
80 | }
81 |
82 | @Override
83 | public void onClick(View v) {
84 | switch (v.getId()){
85 | case R.id.tv_1:
86 | startActivity(new Intent(this, FirstActivity.class));
87 | break;
88 | case R.id.tv_2:
89 | startActivity(new Intent(this, SecondActivity.class));
90 | break;
91 | case R.id.tv_3:
92 | startActivity(new Intent(this, ThirdActivity.class));
93 | break;
94 | case R.id.tv_4:
95 | startActivity(new Intent(this, FourActivity.class));
96 | break;
97 | case R.id.tv_5:
98 | startActivity(new Intent(this, SplashActivity.class));
99 | break;
100 | case R.id.tv_6:
101 | startActivity(new Intent(this, SixActivity.class));
102 | break;
103 | case R.id.tv_7:
104 | startActivity(new Intent(this,SevenActivity.class));
105 | break;
106 | case R.id.tv_8:
107 | startActivity(new Intent(this,EightActivity.class));
108 | break;
109 | case R.id.tv_9:
110 | startActivity(new Intent(this,NightActivity.class));
111 | break;
112 | default:
113 | break;
114 | }
115 | }
116 |
117 |
118 | private void initMarqueeView() {
119 | if (marqueeView == null) {
120 | return;
121 | }
122 | ArrayList list = getMarqueeTitle();
123 | //根据公告字符串列表启动轮播
124 | marqueeView.startWithList(list);
125 | //设置点击事件
126 | marqueeView.setOnItemClickListener(new MarqueeView.OnItemClickListener() {
127 | @Override
128 | public void onItemClick(int position, TextView textView) {
129 |
130 | }
131 | });
132 | }
133 |
134 |
135 |
136 | public ArrayList getMarqueeTitle() {
137 | ArrayList list = new ArrayList<>();
138 | String[] title = getResources().getStringArray(R.array.main_marquee_title);
139 | SpannableString ss1 = new SpannableString(title[0]);
140 | ss1.setSpan(new ForegroundColorSpan(Color.BLACK), 2, title[0].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
141 | list.add(ss1.toString());
142 | SpannableString ss2 = new SpannableString(title[1]);
143 | ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 2, title[1].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
144 | list.add(ss2.toString());
145 | SpannableString ss3 = new SpannableString(title[2]);
146 | ss3.setSpan(new URLSpan("http://www.ximalaya.com/zhubo/71989305/"), 2, title[2].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
147 | list.add(ss3.toString());
148 | return list;
149 | }
150 |
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/NightActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.content.res.TypedArray;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.graphics.drawable.Drawable;
8 | import android.graphics.drawable.TransitionDrawable;
9 | import android.os.Bundle;
10 | import android.util.Log;
11 | import android.view.View;
12 | import android.widget.FrameLayout;
13 |
14 | import androidx.annotation.Nullable;
15 | import androidx.appcompat.app.AppCompatActivity;
16 | import androidx.recyclerview.widget.LinearLayoutManager;
17 | import androidx.recyclerview.widget.RecyclerView;
18 |
19 | import com.ns.yc.ycutilslib.blurView.blur.CustomBlur;
20 | import com.yc.gallerybannerlib.GalleryLayoutManager;
21 | import com.yc.gallerybannerlib.GalleryLinearSnapHelper;
22 | import com.yc.gallerybannerlib.GalleryRecyclerView;
23 | import com.yc.gallerybannerlib.GalleryScaleTransformer;
24 |
25 | import java.util.ArrayList;
26 | import java.util.HashMap;
27 | import java.util.Map;
28 |
29 | import cn.ycbjie.ycstatusbarlib.bar.StateAppBar;
30 |
31 | public class NightActivity extends AppCompatActivity {
32 |
33 | private GalleryRecyclerView mRecyclerView;
34 | private GalleryRecyclerView recyclerView2;
35 | private RecyclerView recyclerView3;
36 | private ArrayList data = new ArrayList<>();
37 | private FrameLayout fl_container;
38 |
39 | @Override
40 | protected void onDestroy() {
41 | super.onDestroy();
42 | mRecyclerView.release();
43 | }
44 |
45 | @Override
46 | protected void onCreate(@Nullable Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_night);
49 | StateAppBar.translucentStatusBar(this,true);
50 | mRecyclerView = findViewById(R.id.recyclerView);
51 | fl_container = findViewById(R.id.fl_container);
52 | recyclerView2 = findViewById(R.id.recyclerView2);
53 | recyclerView3 = findViewById(R.id.recyclerView3);
54 | initRecyclerView();
55 | initRecyclerView2();
56 | initRecyclerView3();
57 | }
58 |
59 | private void initRecyclerView() {
60 | Snap3Adapter adapter = new Snap3Adapter(this);
61 | adapter.setData(getData());
62 | mRecyclerView.setAdapter(adapter);
63 | mRecyclerView.setFlingSpeed(15000);
64 | mRecyclerView.setOnItemSelectedListener(new GalleryRecyclerView.OnItemSelectedListener() {
65 | @Override
66 | public void onItemSelected(RecyclerView recyclerView, View item, int position) {
67 | Log.e("onItemSelected-----", position + "");
68 | //设置高斯模糊背景
69 | setBlurImage(true);
70 | }
71 | });
72 | GalleryLayoutManager manager = new GalleryLayoutManager(this, LinearLayoutManager.HORIZONTAL);
73 | //attach,绑定recyclerView,并且设置默认选中索引的位置
74 | manager.attach(100);
75 | //设置缩放比例因子,在0到1.0之间即可
76 | manager.setItemTransformer(new GalleryScaleTransformer( 0.2f,30));
77 | mRecyclerView.setLayoutManager(manager);
78 | GalleryLinearSnapHelper mSnapHelper = new GalleryLinearSnapHelper(mRecyclerView);
79 | mSnapHelper.attachToRecyclerView(mRecyclerView);
80 | mRecyclerView.onStart();
81 | }
82 |
83 | private void initRecyclerView2() {
84 | Snap3Adapter adapter = new Snap3Adapter(this);
85 | adapter.setData(getData());
86 | recyclerView2.setAdapter(adapter);
87 | recyclerView2.setFlingSpeed(8000);
88 | GalleryLayoutManager manager = new GalleryLayoutManager(this, LinearLayoutManager.HORIZONTAL);
89 | //attach,绑定recyclerView,并且设置默认选中索引的位置
90 | manager.attach(100);
91 | //设置缩放比例因子,在0到1.0之间即可
92 | manager.setItemTransformer(new GalleryScaleTransformer( 0.0f,30));
93 | recyclerView2.setLayoutManager(manager);
94 | GalleryLinearSnapHelper mSnapHelper = new GalleryLinearSnapHelper(recyclerView2);
95 | mSnapHelper.attachToRecyclerView(recyclerView2);
96 | recyclerView2.onStart();
97 | }
98 |
99 |
100 | private void initRecyclerView3() {
101 | GalleryLayoutManager manager = new GalleryLayoutManager(this, LinearLayoutManager.HORIZONTAL);
102 | manager.attach(recyclerView3,100);
103 | manager.setItemTransformer(new GalleryScaleTransformer( 0.0f,30));
104 | recyclerView3.setLayoutManager(manager);
105 | Snap3Adapter adapter = new Snap3Adapter(this);
106 | adapter.setData(getData());
107 | recyclerView3.setAdapter(adapter);
108 | }
109 |
110 |
111 | private ArrayList getData(){
112 | data.clear();
113 | TypedArray bannerImage = getResources().obtainTypedArray(R.array.banner_image);
114 | for (int i = 0; i < 12 ; i++) {
115 | int image = bannerImage.getResourceId(i, R.drawable.beauty1);
116 | data.add(image);
117 | }
118 | bannerImage.recycle();
119 | return data;
120 | }
121 |
122 |
123 | /**
124 | * 获取虚化背景的位置
125 | */
126 | private int mLastDraPosition = -1;
127 | private Map mTSDraCacheMap = new HashMap<>();
128 | private static final String KEY_PRE_DRAW = "key_pre_draw";
129 | /**
130 | * 设置背景高斯模糊
131 | */
132 | public void setBlurImage(boolean forceUpdate) {
133 | final Snap3Adapter adapter = (Snap3Adapter) mRecyclerView.getAdapter();
134 | final int mCurViewPosition = mRecyclerView.getCurrentItem();
135 |
136 | boolean isSamePosAndNotUpdate = (mCurViewPosition == mLastDraPosition) && !forceUpdate;
137 |
138 | if (adapter == null || mRecyclerView == null || isSamePosAndNotUpdate) {
139 | return;
140 | }
141 | mRecyclerView.post(new Runnable() {
142 | @Override
143 | public void run() {
144 | // 获取当前位置的图片资源ID
145 | int resourceId = adapter.getData().get(mCurViewPosition%adapter.getData().size());
146 | // 将该资源图片转为Bitmap
147 | Bitmap resBmp = BitmapFactory.decodeResource(getResources(), resourceId);
148 | // 将该Bitmap高斯模糊后返回到resBlurBmp
149 | Bitmap resBlurBmp = CustomBlur.apply(mRecyclerView.getContext(), resBmp, 10);
150 | // 再将resBlurBmp转为Drawable
151 | Drawable resBlurDrawable = new BitmapDrawable(resBlurBmp);
152 | // 获取前一页的Drawable
153 | Drawable preBlurDrawable = mTSDraCacheMap.get(KEY_PRE_DRAW) == null ? resBlurDrawable : mTSDraCacheMap.get(KEY_PRE_DRAW);
154 |
155 | /* 以下为淡入淡出效果 */
156 | Drawable[] drawableArr = {preBlurDrawable, resBlurDrawable};
157 | TransitionDrawable transitionDrawable = new TransitionDrawable(drawableArr);
158 | fl_container.setBackgroundDrawable(transitionDrawable);
159 | transitionDrawable.startTransition(500);
160 |
161 | // 存入到cache中
162 | mTSDraCacheMap.put(KEY_PRE_DRAW, resBlurDrawable);
163 | // 记录上一次高斯模糊的位置
164 | mLastDraPosition = mCurViewPosition;
165 | }
166 | });
167 | }
168 |
169 |
170 |
171 | }
172 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/SecondActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 |
10 | import androidx.annotation.Nullable;
11 | import androidx.appcompat.app.AppCompatActivity;
12 |
13 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
14 | import com.yc.cn.ycbannerlib.banner.adapter.AbsLoopPagerAdapter;
15 |
16 | /**
17 | * Created by PC on 2017/11/21.
18 | * 作者:PC
19 | */
20 |
21 | public class SecondActivity extends AppCompatActivity {
22 |
23 | private int[] imgs = {
24 | R.drawable.bg_kites_min,
25 | R.drawable.bg_autumn_tree_min,
26 | R.drawable.bg_lake_min,
27 | R.drawable.bg_leaves_min,
28 | R.drawable.bg_magnolia_trees_min,
29 | };
30 | private BannerView banner;
31 |
32 | @Override
33 | protected void onDestroy() {
34 | super.onDestroy();
35 | }
36 |
37 | @Override
38 | protected void onPause() {
39 | super.onPause();
40 | if(banner!=null){
41 | banner.pause();
42 | }
43 | }
44 |
45 | @Override
46 | protected void onResume() {
47 | super.onResume();
48 | if(banner!=null){
49 | banner.resume();
50 | }
51 | }
52 |
53 | @Override
54 | protected void onCreate(@Nullable Bundle savedInstanceState) {
55 | super.onCreate(savedInstanceState);
56 | setContentView(R.layout.activity_second);
57 |
58 | initBanner();
59 | }
60 |
61 | private void initBanner() {
62 | banner = (BannerView) findViewById(R.id.banner);
63 | banner.setAdapter(new ImageNormalAdapter(banner));
64 | banner.setHintGravity(1);
65 | banner.setPlayDelay(2000);
66 | banner.setHintPadding(20,0, 20,20);
67 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
68 | @Override
69 | public void onItemClick(int position) {
70 |
71 | }
72 | });
73 | }
74 |
75 |
76 | private class ImageNormalAdapter extends AbsLoopPagerAdapter {
77 |
78 | public ImageNormalAdapter(BannerView viewPager) {
79 | super(viewPager);
80 | }
81 |
82 | @Override
83 | public View getView(ViewGroup container, int position) {
84 | ImageView view = new ImageView(container.getContext());
85 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
86 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
87 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs[position]);
88 | Bitmap bitmap1 = ImageBitmapUtils.compressByQuality(bitmap, 50, false);
89 | view.setImageBitmap(bitmap1);
90 | return view;
91 | }
92 |
93 | @Override
94 | public int getRealCount() {
95 | return imgs.length;
96 | }
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/SevenActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.os.Bundle;
4 | import android.view.Gravity;
5 |
6 | import androidx.annotation.Nullable;
7 | import androidx.appcompat.app.AppCompatActivity;
8 | import androidx.recyclerview.widget.LinearLayoutManager;
9 | import androidx.recyclerview.widget.LinearSnapHelper;
10 | import androidx.recyclerview.widget.RecyclerView;
11 |
12 | import com.yc.snapbannerlib.ScrollLinearHelper;
13 | import com.yc.snapbannerlib.ScrollPageHelper;
14 | import com.yc.snapbannerlib.ScrollSnapHelper;
15 |
16 | import java.util.ArrayList;
17 |
18 |
19 | public class SevenActivity extends AppCompatActivity {
20 |
21 | private RecyclerView mRecyclerView;
22 | private RecyclerView mRecyclerView2;
23 | private RecyclerView mRecyclerView3;
24 | private RecyclerView mRecyclerView4;
25 | private ArrayList data = new ArrayList<>();
26 |
27 | @Override
28 | protected void onCreate(@Nullable Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_seven);
31 | mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
32 | mRecyclerView2 = (RecyclerView) findViewById(R.id.recyclerView2);
33 | mRecyclerView3 = (RecyclerView) findViewById(R.id.recyclerView3);
34 | mRecyclerView4 = (RecyclerView) findViewById(R.id.recyclerView4);
35 | initRecyclerView();
36 | initRecyclerView2();
37 | initRecyclerView3();
38 | initRecyclerView4();
39 | }
40 |
41 | private void initRecyclerView() {
42 | LinearLayoutManager manager = new LinearLayoutManager(this);
43 | manager.setOrientation(LinearLayoutManager.HORIZONTAL);
44 | mRecyclerView.setLayoutManager(manager);
45 | ScrollLinearHelper snapHelper = new ScrollLinearHelper();
46 | snapHelper.attachToRecyclerView(mRecyclerView);
47 | SnapAdapter adapter = new SnapAdapter(this);
48 | mRecyclerView.setAdapter(adapter);
49 | adapter.addAll(getData());
50 | }
51 |
52 | private void initRecyclerView2() {
53 | LinearLayoutManager manager = new LinearLayoutManager(this);
54 | manager.setOrientation(LinearLayoutManager.HORIZONTAL);
55 | mRecyclerView2.setLayoutManager(manager);
56 | LinearSnapHelper snapHelper = new LinearSnapHelper();
57 | snapHelper.attachToRecyclerView(mRecyclerView2);
58 | SnapAdapter adapter = new SnapAdapter(this);
59 | mRecyclerView2.setAdapter(adapter);
60 | adapter.addAll(getData());
61 | }
62 |
63 |
64 | private void initRecyclerView3() {
65 | LinearLayoutManager manager = new LinearLayoutManager(this);
66 | manager.setOrientation(LinearLayoutManager.HORIZONTAL);
67 | mRecyclerView3.setLayoutManager(manager);
68 | ScrollPageHelper snapHelper = new ScrollPageHelper(Gravity.START,false);
69 | snapHelper.attachToRecyclerView(mRecyclerView3);
70 | SnapAdapter adapter = new SnapAdapter(this);
71 | mRecyclerView3.setAdapter(adapter);
72 | adapter.addAll(getData());
73 | }
74 |
75 |
76 | private void initRecyclerView4() {
77 | LinearLayoutManager manager = new LinearLayoutManager(this);
78 | manager.setOrientation(LinearLayoutManager.HORIZONTAL);
79 | mRecyclerView4.setLayoutManager(manager);
80 | ScrollSnapHelper snapHelper = new ScrollSnapHelper();
81 | snapHelper.attachToRecyclerView(mRecyclerView4);
82 | SnapAdapter adapter = new SnapAdapter(this);
83 | mRecyclerView4.setAdapter(adapter);
84 | adapter.addAll(getData());
85 | }
86 |
87 |
88 |
89 | private ArrayList getData(){
90 | for (int a=0 ; a<20 ; a++){
91 | data.add("测试数据"+a);
92 | }
93 | return data;
94 | }
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/SixActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.Toast;
10 |
11 | import androidx.annotation.Nullable;
12 | import androidx.appcompat.app.AppCompatActivity;
13 |
14 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
15 | import com.yc.cn.ycbannerlib.banner.adapter.AbsStaticPagerAdapter;
16 | import com.yc.cn.ycbannerlib.banner.hintview.IconHintView;
17 |
18 | /**
19 | * Created by PC on 2017/11/21.
20 | * 作者:PC
21 | */
22 |
23 | public class SixActivity extends AppCompatActivity {
24 |
25 | private int[] imgs = {
26 | R.drawable.bg_kites_min,
27 | R.drawable.bg_autumn_tree_min,
28 | R.drawable.bg_lake_min,
29 | R.drawable.bg_leaves_min,
30 | R.drawable.bg_magnolia_trees_min,
31 | };
32 | private BannerView banner;
33 |
34 | @Override
35 | protected void onDestroy() {
36 | super.onDestroy();
37 | }
38 |
39 | @Override
40 | protected void onPause() {
41 | super.onPause();
42 | if(banner!=null){
43 | banner.pause();
44 | }
45 | }
46 |
47 | @Override
48 | protected void onResume() {
49 | super.onResume();
50 | if(banner!=null){
51 | banner.resume();
52 | }
53 | }
54 |
55 | @Override
56 | protected void onCreate(@Nullable Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.activity_four);
59 |
60 | initBanner();
61 | }
62 |
63 | private void initBanner() {
64 | banner = (BannerView) findViewById(R.id.banner);
65 | banner.setAnimationDuration(1000);
66 | banner.setHintGravity(1);
67 | banner.setHintPadding(0, 20,0,20);
68 | banner.setPlayDelay(2000);
69 | banner.setHintView(new IconHintView(this,R.drawable.point_focus,R.drawable.point_normal));
70 | banner.setAdapter(new ImageNormalAdapter());
71 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
72 | @Override
73 | public void onItemClick(int position) {
74 | Toast.makeText(SixActivity.this,position+"被点击呢",Toast.LENGTH_SHORT).show();
75 | }
76 | });
77 | }
78 |
79 |
80 | private class ImageNormalAdapter extends AbsStaticPagerAdapter {
81 |
82 | @Override
83 | public View getView(ViewGroup container, int position) {
84 | ImageView view = new ImageView(container.getContext());
85 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
86 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
87 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs[position]);
88 | Bitmap bitmap1 = ImageBitmapUtils.compressByScale(bitmap,2.0f,2.0f,false);
89 | view.setImageBitmap(bitmap1);
90 | return view;
91 | }
92 |
93 | @Override
94 | public int getCount() {
95 | return imgs.length;
96 | }
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/Snap2Adapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 |
4 | import android.content.Context;
5 | import android.util.Log;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import com.yc.cn.ycbaseadapterlib.adapter.BaseAdapter;
11 | import com.yc.cn.ycbaseadapterlib.adapter.BaseViewHolder;
12 | import com.yc.cn.ycbaseadapterlib.itemType.BaseMViewHolder;
13 | import com.yc.cn.ycbaseadapterlib.itemType.RecyclerArrayAdapter;
14 |
15 | import java.util.List;
16 |
17 | public class Snap2Adapter extends BaseAdapter {
18 |
19 |
20 | Snap2Adapter(Context context) {
21 | super(context, R.layout.item_snap2);
22 | }
23 |
24 |
25 | @Override
26 | protected void bindData(BaseViewHolder holder, Integer data) {
27 | Integer integer = getData().get(getViewPosition() % getData().size());
28 | ImageView imageView = holder.getView(R.id.iv_image);
29 | imageView.setBackgroundResource(integer);
30 | }
31 |
32 | @Override
33 | public int getItemCount() {
34 | if (getData().size() != 1) {
35 | Log.e("getItemCount","getItemCount---------");
36 | return Integer.MAX_VALUE; // 无限轮播
37 | } else {
38 | Log.e("getItemCount","getItemCount++++----");
39 | return getData().size();
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/Snap3Adapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 |
4 | import android.content.Context;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 |
11 |
12 | import androidx.annotation.NonNull;
13 | import androidx.recyclerview.widget.RecyclerView;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | public class Snap3Adapter extends RecyclerView.Adapter {
19 |
20 |
21 | private Context mContext;
22 | Snap3Adapter(Context context){
23 | this.mContext =context;
24 | }
25 |
26 | private List urlList = new ArrayList<>();
27 | public void setData(List list) {
28 | urlList.clear();
29 | this.urlList = list;
30 | }
31 |
32 | public List getData() {
33 | return urlList;
34 | }
35 |
36 | @NonNull
37 | @Override
38 | public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
39 | View view = LayoutInflater.from(mContext).inflate(R.layout.item_snap2, parent, false);
40 | return new MyViewHolder(view);
41 | }
42 |
43 | @Override
44 | public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
45 | if (urlList == null || urlList.isEmpty())
46 | return;
47 | Integer url = urlList.get(position%urlList.size());
48 | // Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), url);
49 | // Bitmap bitmap1 = ImageBitmapUtils.compressByQuality(bitmap, 60,false);
50 | // holder.imageView.setImageBitmap(bitmap1);
51 |
52 | holder.imageView.setBackgroundResource(url);
53 | }
54 |
55 |
56 | class MyViewHolder extends RecyclerView.ViewHolder{
57 | ImageView imageView;
58 | MyViewHolder(View itemView) {
59 | super(itemView);
60 | imageView = itemView.findViewById(R.id.iv_image);
61 | }
62 |
63 | }
64 |
65 | @Override
66 | public int getItemCount() {
67 | if (urlList.size() != 1) {
68 | Log.e("getItemCount","getItemCount---------");
69 | return Integer.MAX_VALUE; // 无限轮播
70 | } else {
71 | Log.e("getItemCount","getItemCount++++----");
72 | return urlList.size();
73 | }
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/SnapAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 |
4 | import android.content.Context;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.yc.cn.ycbaseadapterlib.itemType.BaseMViewHolder;
10 | import com.yc.cn.ycbaseadapterlib.itemType.RecyclerArrayAdapter;
11 |
12 | public class SnapAdapter extends RecyclerArrayAdapter{
13 |
14 |
15 |
16 |
17 | public SnapAdapter(Context context) {
18 | super(context);
19 | }
20 |
21 | @Override
22 | public BaseMViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
23 | return new MyViewHolder(parent);
24 | }
25 |
26 | private class MyViewHolder extends BaseMViewHolder {
27 |
28 | private final ImageView imageView;
29 | private final TextView textView;
30 |
31 | MyViewHolder(ViewGroup parent) {
32 | super(parent, R.layout.item_snap);
33 | imageView = getView(R.id.iv_image);
34 | textView = getView(R.id.tv_title);
35 | }
36 |
37 | @Override
38 | public void setData(String data) {
39 | super.setData(data);
40 | imageView.setBackgroundResource(R.drawable.bg_kites_min);
41 | textView.setText(data);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.Button;
8 | import android.widget.ImageView;
9 |
10 | import androidx.annotation.Nullable;
11 | import androidx.appcompat.app.AppCompatActivity;
12 |
13 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
14 | import com.yc.cn.ycbannerlib.banner.adapter.AbsDynamicPagerAdapter;
15 |
16 |
17 |
18 | /**
19 | * Created by yc on 2018/4/10.
20 | */
21 |
22 | public class SplashActivity extends AppCompatActivity {
23 |
24 | private int[] imgs = {
25 | R.drawable.bg_kites_min,
26 | R.drawable.bg_autumn_tree_min,
27 | R.drawable.bg_lake_min,
28 | R.drawable.bg_leaves_min,
29 | R.drawable.bg_magnolia_trees_min,
30 | };
31 | private BannerView banner;
32 | private Button btn;
33 |
34 | @Override
35 | protected void onCreate(@Nullable Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_five);
38 | initBanner();
39 | initListener();
40 | }
41 |
42 | private void initListener() {
43 | btn = (Button) findViewById(R.id.btn);
44 | btn.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | startActivity(new Intent(SplashActivity.this, MainActivity.class));
48 | }
49 | });
50 | }
51 |
52 |
53 | private void initBanner() {
54 | banner = (BannerView) findViewById(R.id.banner);
55 | banner.setPlayDelay(0);
56 | banner.setAdapter(new ImageNormalAdapter());
57 | banner.setHintGravity(1);
58 | banner.setHintPadding(20,0, 20,20);
59 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
60 | @Override
61 | public void onItemClick(int position) {
62 |
63 | }
64 | });
65 | banner.setOnPageListener(new BannerView.OnPageListener() {
66 | @Override
67 | public void onPageChange(int position) {
68 | if(position==imgs.length-1){
69 | btn.setVisibility(View.VISIBLE);
70 | }else {
71 | btn.setVisibility(View.GONE);
72 | }
73 | }
74 | });
75 | }
76 |
77 |
78 |
79 | private class ImageNormalAdapter extends AbsDynamicPagerAdapter {
80 |
81 | @Override
82 | public View getView(ViewGroup container, int position) {
83 | ImageView view = new ImageView(container.getContext());
84 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
85 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
86 | ViewGroup.LayoutParams.MATCH_PARENT));
87 | view.setImageResource(imgs[position]);
88 | return view;
89 | }
90 |
91 | @Override
92 | public int getCount() {
93 | return imgs.length;
94 | }
95 | }
96 |
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yc/cn/ycbanner/ThirdActivity.java:
--------------------------------------------------------------------------------
1 | package com.yc.cn.ycbanner;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 | import android.graphics.Color;
6 | import android.os.Bundle;
7 | import android.view.Gravity;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.Toast;
12 |
13 | import androidx.annotation.Nullable;
14 | import androidx.appcompat.app.AppCompatActivity;
15 |
16 | import com.yc.cn.ycbannerlib.banner.view.BannerView;
17 | import com.yc.cn.ycbannerlib.banner.adapter.AbsLoopPagerAdapter;
18 |
19 | /**
20 | * Created by PC on 2017/11/21.
21 | * 作者:PC
22 | */
23 |
24 | public class ThirdActivity extends AppCompatActivity {
25 |
26 | private int[] imgs = {
27 | R.drawable.bg_kites_min,
28 | R.drawable.bg_autumn_tree_min,
29 | R.drawable.bg_lake_min,
30 | R.drawable.bg_leaves_min,
31 | R.drawable.bg_magnolia_trees_min,
32 | };
33 | private BannerView banner;
34 |
35 | @Override
36 | protected void onDestroy() {
37 | super.onDestroy();
38 | }
39 |
40 | @Override
41 | protected void onPause() {
42 | super.onPause();
43 | if(banner!=null){
44 | banner.pause();
45 | }
46 | }
47 |
48 | @Override
49 | protected void onResume() {
50 | super.onResume();
51 | if(banner!=null){
52 | banner.resume();
53 | }
54 | }
55 |
56 | @Override
57 | protected void onCreate(@Nullable Bundle savedInstanceState) {
58 | super.onCreate(savedInstanceState);
59 | setContentView(R.layout.activity_third);
60 |
61 | initBanner();
62 | }
63 |
64 | private void initBanner() {
65 | banner = (BannerView) findViewById(R.id.banner);
66 | banner.setHintColor(Color.GRAY);
67 | banner.setHintGravity(Gravity.RIGHT);
68 | banner.setAnimationDuration(1000);
69 | banner.setHintPadding(0, 20,0,20);
70 | banner.setPlayDelay(2000);
71 | banner.setAdapter(new ImageNormalAdapter(banner));
72 | banner.setOnBannerClickListener(new BannerView.OnBannerClickListener() {
73 | @Override
74 | public void onItemClick(int position) {
75 | Toast.makeText(ThirdActivity.this,position+"被点击呢",Toast.LENGTH_SHORT).show();
76 | }
77 | });
78 | }
79 |
80 |
81 | private class ImageNormalAdapter extends AbsLoopPagerAdapter {
82 |
83 | ImageNormalAdapter(BannerView viewPager) {
84 | super(viewPager);
85 | }
86 |
87 | @Override
88 | public View getView(ViewGroup container, int position) {
89 | ImageView view = new ImageView(container.getContext());
90 | view.setScaleType(ImageView.ScaleType.CENTER_CROP);
91 | view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
92 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs[position]);
93 | Bitmap bitmap1 = ImageBitmapUtils.compressByQuality1(bitmap, 10240,false);
94 | view.setImageBitmap(bitmap1);
95 | return view;
96 | }
97 |
98 |
99 | @Override
100 | public int getRealCount() {
101 | return imgs.length;
102 | }
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_autumn_tree_min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/bg_autumn_tree_min.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_kites_min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/bg_kites_min.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_lake_min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/bg_lake_min.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_leaves_min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/bg_leaves_min.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_magnolia_trees_min.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/bg_magnolia_trees_min.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/point_focus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/point_focus.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/point_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xhdpi/point_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty10.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty11.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty12.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty13.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty4.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty5.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty6.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty7.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty8.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/beauty9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/drawable-xxhdpi/beauty9.jpg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_eight.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_first.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_five.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
13 |
14 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_four.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
25 |
26 |
33 |
34 |
35 |
42 |
43 |
44 |
51 |
52 |
59 |
60 |
61 |
77 |
78 |
79 |
86 |
87 |
94 |
95 |
102 |
103 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_night.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
12 |
16 |
21 |
22 |
23 |
24 |
29 |
30 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_second.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_seven.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
14 |
15 |
16 |
21 |
22 |
23 |
28 |
29 |
30 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_third.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_snap.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_snap2.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - 1.坚持读书,写作,源于内心的动力
6 | - 2.展翅翱翔,青春我们一路前行
7 | - 3.欢迎订阅喜马拉雅听书
8 |
9 |
10 |
11 |
12 | - @drawable/beauty1
13 | - @drawable/beauty2
14 | - @drawable/beauty3
15 | - @drawable/beauty4
16 | - @drawable/beauty5
17 | - @drawable/beauty6
18 | - @drawable/beauty7
19 | - @drawable/beauty8
20 | - @drawable/beauty9
21 | - @drawable/beauty10
22 | - @drawable/beauty11
23 | - @drawable/beauty12
24 | - @drawable/beauty13
25 | - @drawable/beauty11
26 | - @drawable/beauty12
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #10000000
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | YCBanner
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/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 | google()
6 | jcenter()
7 | maven {
8 | url 'https://maven.google.com/'
9 | name 'Google'
10 | }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:3.2.0'
14 |
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module appBuild.gradle files
17 | //添加下面两句,进行配置
18 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
19 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | google()
26 | jcenter()
27 | maven {
28 | url 'https://maven.google.com/'
29 | name 'Google'
30 | }
31 | }
32 | }
33 |
34 | task clean(type: Delete) {
35 | delete rootProject.buildDir
36 | }
37 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 | android.enableAapt2=false
19 | android.enableJetifier=true
20 | android.useAndroidX=true
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/image/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/1.png
--------------------------------------------------------------------------------
/image/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/2.png
--------------------------------------------------------------------------------
/image/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/4.jpg
--------------------------------------------------------------------------------
/image/4.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/4.mp4
--------------------------------------------------------------------------------
/image/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/5.jpg
--------------------------------------------------------------------------------
/image/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangchong211/YCBannerView/22d2a7fe1651c097877f84e619f1a1c71179b359/image/6.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':YCBannerLib'
2 | include ':SnapBannerLib'
3 | include ':GalleryBannerLib'
4 |
--------------------------------------------------------------------------------