├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── drawable
│ │ │ │ ├── robot.png
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── item_rcy.xml
│ │ │ │ ├── activity_list.xml
│ │ │ │ └── activity_main.xml
│ │ │ └── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── dell
│ │ │ └── picturecache
│ │ │ ├── adapter
│ │ │ ├── TestAdapter.java
│ │ │ └── RecyclerviewAdapter.java
│ │ │ ├── ListActivity.java
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── dell
│ │ │ └── picturecache
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── dell
│ │ └── picturecache
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── lib_rhythm
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── style.xml
│ │ │ └── drawable
│ │ │ │ ├── add_realnameahtu.png
│ │ │ │ └── anim_flag_iceland.gif
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── picture
│ │ │ │ └── lib_rhythm
│ │ │ │ ├── constant
│ │ │ │ ├── GraphicalType.java
│ │ │ │ ├── VisitType.java
│ │ │ │ ├── AnimateType.java
│ │ │ │ └── Watermark.java
│ │ │ │ ├── cache
│ │ │ │ ├── Callback.java
│ │ │ │ ├── Cache.java
│ │ │ │ ├── LruCache.java
│ │ │ │ ├── LocalCache.java
│ │ │ │ └── NetCache.java
│ │ │ │ ├── transformation
│ │ │ │ └── BlurTransformation.java
│ │ │ │ ├── bean
│ │ │ │ ├── WatermarkInfo.java
│ │ │ │ └── TagInfo.java
│ │ │ │ ├── animate
│ │ │ │ └── AnimateManage.java
│ │ │ │ ├── widgets
│ │ │ │ ├── vague
│ │ │ │ │ └── VagueView.java
│ │ │ │ └── gif
│ │ │ │ │ └── GifImageView.java
│ │ │ │ ├── utils
│ │ │ │ ├── Utils.java
│ │ │ │ └── BitmapUtils.java
│ │ │ │ ├── Rhythm.java
│ │ │ │ └── RequestCreator.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── picture
│ │ │ └── lib_rhythm
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── picture
│ │ └── lib_rhythm
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── com
└── lib
│ └── pic_cache
│ ├── maven-metadata.xml.md5
│ ├── 1.0.1
│ ├── pic_cache-1.0.1.aar.md5
│ ├── pic_cache-1.0.1.pom.md5
│ ├── pic_cache-1.0.1-sources.jar.md5
│ ├── pic_cache-1.0.1.aar.sha1
│ ├── pic_cache-1.0.1.pom.sha1
│ ├── pic_cache-1.0.1-sources.jar.sha1
│ ├── pic_cache-1.0.1.aar
│ ├── pic_cache-1.0.1-sources.jar
│ └── pic_cache-1.0.1.pom
│ ├── maven-metadata.xml.sha1
│ └── maven-metadata.xml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
└── vcs.xml
├── gradle.properties
├── gradlew.bat
├── README.md
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib_rhythm/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':lib_rhythm'
2 |
--------------------------------------------------------------------------------
/com/lib/pic_cache/maven-metadata.xml.md5:
--------------------------------------------------------------------------------
1 | 60353d9bc1bbf2fce644780a501ed3c6
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.aar.md5:
--------------------------------------------------------------------------------
1 | 3e6b02e455cec30588c2b477fc4c4ec4
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.pom.md5:
--------------------------------------------------------------------------------
1 | 87d341b9a56314dc674ea6af40bfa0be
--------------------------------------------------------------------------------
/com/lib/pic_cache/maven-metadata.xml.sha1:
--------------------------------------------------------------------------------
1 | 3b6fc5266f99d39f85e5546907ce734c54a8debd
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1-sources.jar.md5:
--------------------------------------------------------------------------------
1 | 4a11fd527f2c73555dbe78e8b992977e
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.aar.sha1:
--------------------------------------------------------------------------------
1 | 2f6a7b89be74e8a8604ec40e90829dd18934aeb3
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.pom.sha1:
--------------------------------------------------------------------------------
1 | 7ed9a3693b9d931545bae85da6c30c98ae6a3bc0
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1-sources.jar.sha1:
--------------------------------------------------------------------------------
1 | f173efdfe8f385d1af6fc74cbbe726bb4618e749
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PictureCache
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/lib_rhythm/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | lib_rhythm
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/robot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/drawable/robot.png
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.aar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1-sources.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/com/lib/pic_cache/1.0.1/pic_cache-1.0.1-sources.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/lib_rhythm/src/main/res/drawable/add_realnameahtu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/lib_rhythm/src/main/res/drawable/add_realnameahtu.png
--------------------------------------------------------------------------------
/lib_rhythm/src/main/res/drawable/anim_flag_iceland.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xiangmingzhe/PictureCache/HEAD/lib_rhythm/src/main/res/drawable/anim_flag_iceland.gif
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/res/values/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Nov 07 10:48:41 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/com/lib/pic_cache/maven-metadata.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.lib
4 | pic_cache
5 |
6 | 1.0.1
7 |
8 | 1.0.1
9 |
10 | 20191202022304
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/constant/GraphicalType.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.constant;
2 |
3 | /**
4 | * Time:2019/11/14
5 | * Author:xmz-dell
6 | * Description:
7 | * 图片风格
8 | */
9 | public enum GraphicalType {
10 | /**
11 | * 圆形
12 | */
13 | CIRCLE,
14 | /**
15 | *椭圆
16 | */
17 | OVAL,
18 | /**
19 | * 模糊特效
20 | */
21 | VAGUE
22 | }
23 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/constant/VisitType.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.constant;
2 |
3 | /**
4 | * Time:2019/11/14
5 | * Author:xmz-dell
6 | * Description:
7 | * 访问类型
8 | */
9 | public enum VisitType {
10 | /**
11 | * http请求
12 | */
13 | HTTP,
14 | /**
15 | * 资源ID
16 | */
17 | RESOURCES,
18 | /**
19 | * 本地文件
20 | */
21 | LOCAL,
22 | }
23 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/constant/AnimateType.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.constant;
2 |
3 | /**
4 | * Time:2019/11/18
5 | * Author:xmz-dell
6 | * Description:
7 | */
8 | public enum AnimateType {
9 | /**
10 | * 淡入淡出效果
11 | */
12 | CROSS_FADE,
13 | /**
14 | * 无动画
15 | */
16 | DONT_ANIMATE,
17 | /**
18 | * 自定义动画
19 | */
20 | ANIMATE,
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/cache/Callback.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.cache;
2 |
3 | /**
4 | * Time:2019/11/7
5 | * Author:xmz-dell
6 | * Description:
7 | */
8 | public interface Callback {
9 | void onSuccess();
10 |
11 | void onError();
12 |
13 | public static class EmptyCallback implements Callback {
14 |
15 | @Override public void onSuccess() {
16 | }
17 |
18 | @Override public void onError() {
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib_rhythm/src/test/java/com/picture/lib_rhythm/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm;
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 | }
--------------------------------------------------------------------------------
/app/src/test/java/com/example/dell/picturecache/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache;
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 | }
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/constant/Watermark.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.constant;
2 |
3 | /**
4 | * Time:2019/11/19
5 | * Author:xmz-dell
6 | * Description:
7 | */
8 | public enum Watermark {
9 | /**
10 | * 左上角
11 | */
12 | LEFT_TOP,
13 | /**
14 | * 右下角
15 | */
16 | RIGHT_BOTTOM,
17 |
18 | /**
19 | * 右上角
20 | */
21 | RIGHT_TOP,
22 | /**
23 | * 左下角
24 | */
25 | LEFT_BOTTOM,
26 | /**
27 | * 中间
28 | */
29 | CENTER,
30 | }
31 |
--------------------------------------------------------------------------------
/com/lib/pic_cache/1.0.1/pic_cache-1.0.1.pom:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.lib
6 | pic_cache
7 | 1.0.1
8 | aar
9 |
10 |
11 | com.android.support
12 | appcompat-v7
13 | 28.0.0
14 | compile
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_rcy.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/lib_rhythm/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/lib_rhythm/src/androidTest/java/com/picture/lib_rhythm/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.picture.lib_rhythm.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/dell/picturecache/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.dell.picturecache", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/transformation/BlurTransformation.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.transformation;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Time:2019/11/18
7 | * Author:xmz-dell
8 | * Description:高斯模糊实体类
9 | */
10 | public class BlurTransformation {
11 | private int radius;
12 | private int scale;
13 | public BlurTransformation(int radius){
14 | this.radius=radius;
15 | }
16 | public BlurTransformation(int radius,int scale){
17 | this.radius=radius;
18 | this.scale=scale;
19 | }
20 |
21 | public int getRadius() {
22 | return radius;
23 | }
24 |
25 | public void setRadius(int radius) {
26 | this.radius = radius;
27 | }
28 |
29 | public int getScale() {
30 | return scale;
31 | }
32 |
33 | public void setScale(int scale) {
34 | this.scale = scale;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
15 |
21 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/cache/Cache.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.cache;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | * Time:2019/11/7
7 | * Author:xmz-dell
8 | * Description:
9 | */
10 | public interface Cache {
11 | Bitmap get(String key);
12 |
13 | void set(String key, Bitmap bitmap);
14 |
15 | int size();
16 |
17 | int maxSize();
18 |
19 | void clear();
20 |
21 | void clearKeyUri(String keyPrefix);
22 |
23 | Cache NONE = new Cache() {
24 | @Override
25 | public Bitmap get(String key) {
26 | return null;
27 | }
28 |
29 | @Override
30 | public void set(String key, Bitmap bitmap) {
31 | // Ignore.
32 | }
33 |
34 | @Override
35 | public int size() {
36 | return 0;
37 | }
38 |
39 | @Override
40 | public int maxSize() {
41 | return 0;
42 | }
43 |
44 | @Override
45 | public void clear() {
46 | }
47 |
48 | @Override
49 | public void clearKeyUri(String keyPrefix) {
50 | }
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.example.dell.picturecache"
7 | minSdkVersion 15
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(include: ['*.jar'], dir: 'libs')
23 | implementation 'com.android.support:appcompat-v7:28.0.0'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
25 | testImplementation 'junit:junit:4.12'
26 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
28 | implementation project(':lib_rhythm')
29 | implementation "com.android.support:recyclerview-v7:28+"
30 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'
31 | // implementation 'com.github.xiangmingzhe:PictureCache:1.0.1'
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dell/picturecache/adapter/TestAdapter.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.Nullable;
5 | import android.util.Log;
6 | import android.widget.ImageView;
7 |
8 | import com.chad.library.adapter.base.BaseQuickAdapter;
9 | import com.chad.library.adapter.base.BaseViewHolder;
10 | import com.example.dell.picturecache.R;
11 | import com.picture.lib_rhythm.Rhythm;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * Time:2019/11/12
17 | * Author:xmz-dell
18 | * Description:
19 | */
20 | public class TestAdapter extends BaseQuickAdapter {
21 | private Context mContext;
22 | public TestAdapter(int layoutResId, @Nullable List data) {
23 | super(layoutResId, data);
24 | }
25 | public void setContext(Context context){
26 | this.mContext=context;
27 | }
28 | @Override
29 | protected void convert(BaseViewHolder helper, String item) {
30 | ImageView imageView=helper.getView(R.id.image);
31 | if(helper.getPosition()!=1){
32 | Rhythm.with(mContext)
33 | .transform(10.0f).boarder(3)
34 | .load(item)
35 | .crossFade()
36 | .placeholder(R.drawable.ic_launcher_background)
37 | .error(R.drawable.robot)
38 | .into(imageView);
39 | }else{
40 | Rhythm.with(mContext)
41 | .transform(10.0f).boarder(3)
42 | .load(item)
43 | .placeholder(R.drawable.ic_launcher_background)
44 | .error(R.drawable.robot)
45 | .into(imageView);
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib_rhythm/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'maven'
3 |
4 |
5 | ext {
6 | // 从Github上clone下来的项目的本地地址
7 | GITHUB_REPO_PATH = "D:\\cache\\PictureCache" //这里指定的就是刚刚新建项目后clone下来的在本地的路径
8 | PUBLISH_GROUP_ID = 'com.lib'
9 | PUBLISH_ARTIFACT_ID = 'pic_cache'
10 | PUBLISH_VERSION = '1.0.1'
11 | }
12 | uploadArchives {
13 | repositories.mavenDeployer {
14 | def deployPath = file(project.GITHUB_REPO_PATH)
15 | repository(url: "file://${deployPath.absolutePath}")
16 | pom.project {
17 | groupId project.PUBLISH_GROUP_ID
18 | artifactId project.PUBLISH_ARTIFACT_ID
19 | version project.PUBLISH_VERSION
20 | }
21 | }
22 | }
23 |
24 | // 源代码一起打包
25 | task androidSourcesJar(type: Jar) {
26 | classifier = 'sources'
27 | from android.sourceSets.main.java.sourceFiles
28 | }
29 | artifacts {
30 | archives androidSourcesJar
31 | }
32 |
33 |
34 | android {
35 | compileSdkVersion 28
36 |
37 |
38 |
39 | defaultConfig {
40 | minSdkVersion 15
41 | targetSdkVersion 28
42 | versionCode 1
43 | versionName "1.0"
44 |
45 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
46 |
47 | }
48 |
49 | buildTypes {
50 | release {
51 | minifyEnabled false
52 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
53 | }
54 | }
55 | repositories {
56 | flatDir {
57 | dirs 'libs'
58 | }
59 |
60 | }
61 | }
62 |
63 | dependencies {
64 | implementation fileTree(dir: 'libs', include: ['*.jar'])
65 |
66 | implementation 'com.android.support:appcompat-v7:28.0.0'
67 | testImplementation 'junit:junit:4.12'
68 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
69 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dell/picturecache/adapter/RecyclerviewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import com.example.dell.picturecache.MainActivity;
14 | import com.example.dell.picturecache.R;
15 | import com.picture.lib_rhythm.Rhythm;
16 |
17 | import java.util.List;
18 |
19 | /**
20 | * Time:2019/11/12
21 | * Author:xmz-dell
22 | * Description:
23 | */
24 | public class RecyclerviewAdapter extends RecyclerView.Adapter {
25 |
26 | private Context context;
27 | private List data;
28 |
29 | public RecyclerviewAdapter(Context context,List data){
30 | this.context = context;
31 | this.data = data;
32 |
33 | }
34 |
35 | @Override
36 | public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
37 | View view = LayoutInflater.from(context).inflate(R.layout.item_rcy,parent,false);
38 | return new ViewHolder(view);
39 | }
40 |
41 | @Override
42 | public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
43 | Rhythm.with(context)
44 | .transform(10.0f).boarder(3)
45 | .load(data.get(position))
46 | .into(holder.imageView);
47 | holder.itemView.setOnClickListener(new View.OnClickListener() {
48 | @Override
49 | public void onClick(View v) {
50 | Log.e("这里是点击每一行item的响应事件",""+position);
51 | }
52 | });
53 |
54 | }
55 |
56 | @Override
57 | public int getItemCount() {
58 | return data.size();
59 | }
60 |
61 | public class ViewHolder extends RecyclerView.ViewHolder{
62 | private ImageView imageView;
63 | public ViewHolder(View itemView) {
64 | super(itemView);
65 | imageView= itemView.findViewById(R.id.image);
66 | }
67 | }
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/bean/WatermarkInfo.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.bean;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | import com.picture.lib_rhythm.constant.Watermark;
6 |
7 | /**
8 | * Time:2019/11/19
9 | * Author:xmz-dell
10 | * Description:
11 | */
12 | public class WatermarkInfo {
13 | private Watermark watermark;
14 | private int paddingLeft;
15 | private int paddingTop;
16 | private int paddingRight;
17 | private int paddingBottom;
18 | private Bitmap bitmap;//水印图片
19 |
20 | public WatermarkInfo(Watermark watermark,Bitmap watermarkBitmap){
21 | this.watermark=watermark;
22 | this.bitmap=watermarkBitmap;
23 | }
24 | public WatermarkInfo(Watermark watermark,Bitmap watermarkBitmap,int paddingLeft,int paddingTop,int paddingRight,int paddingBottom){
25 | this.watermark=watermark;
26 | this.bitmap=watermarkBitmap;
27 | this.paddingLeft=paddingLeft;
28 | this.paddingTop=paddingTop;
29 | this.paddingBottom=paddingBottom;
30 | this.paddingRight=paddingRight;
31 | }
32 | public Watermark getWatermark() {
33 | return watermark;
34 | }
35 |
36 | public void setWatermark(Watermark watermark) {
37 | this.watermark = watermark;
38 | }
39 |
40 | public int getPaddingLeft() {
41 | return paddingLeft;
42 | }
43 |
44 | public void setPaddingLeft(int paddingLeft) {
45 | this.paddingLeft = paddingLeft;
46 | }
47 |
48 | public int getPaddingTop() {
49 | return paddingTop;
50 | }
51 |
52 | public void setPaddingTop(int paddingTop) {
53 | this.paddingTop = paddingTop;
54 | }
55 |
56 | public int getPaddingRight() {
57 | return paddingRight;
58 | }
59 |
60 | public void setPaddingRight(int paddingRight) {
61 | this.paddingRight = paddingRight;
62 | }
63 |
64 | public int getPaddingBottom() {
65 | return paddingBottom;
66 | }
67 |
68 | public void setPaddingBottom(int paddingBottom) {
69 | this.paddingBottom = paddingBottom;
70 | }
71 |
72 | public Bitmap getBitmap() {
73 | return bitmap;
74 | }
75 |
76 | public void setBitmap(Bitmap bitmap) {
77 | this.bitmap = bitmap;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/animate/AnimateManage.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.animate;
2 |
3 | import android.animation.AnimatorInflater;
4 | import android.animation.ObjectAnimator;
5 | import android.animation.ValueAnimator;
6 | import android.content.Context;
7 | import android.util.Log;
8 | import android.view.animation.AlphaAnimation;
9 | import android.view.animation.Animation;
10 | import android.view.animation.AnimationSet;
11 | import android.view.animation.AnimationUtils;
12 | import android.widget.ImageView;
13 |
14 | import com.picture.lib_rhythm.R;
15 | import com.picture.lib_rhythm.RequestCreator;
16 | import com.picture.lib_rhythm.Rhythm;
17 | import com.picture.lib_rhythm.constant.AnimateType;
18 |
19 | /**
20 | * Time:2019/11/18
21 | * Author:xmz-dell
22 | * Description:
23 | */
24 | public class AnimateManage {
25 | volatile static AnimateManage singleton;
26 | private int animateID;//动画资源ID
27 | private AlphaAnimation alphaAnimation;
28 | private static String TAG="AnimateManage";
29 | public static AnimateManage getInstance() {
30 | if (singleton == null) {
31 | synchronized (AnimateManage.class) {
32 | if (singleton == null) {
33 | singleton = new AnimateManage();
34 | }
35 | }
36 | }
37 | return singleton;
38 | }
39 |
40 | /**
41 | * 为目标控件增绑定动画
42 | *
43 | * @param into
44 | */
45 | public void bindAnimate(ImageView into, Context context,AnimateType animateType) {
46 | if (into == null) {
47 | throw new NullPointerException("into Can not be empty");
48 | }
49 | if(animateType==null){
50 | return;
51 | }
52 | Log.d(TAG,"bindAnimate:"+animateType.name());
53 | switch (animateType.name()) {
54 | case "CROSS_FADE":
55 | startAlphaAnimation(into);
56 | break;
57 | case "ANIMATE":
58 | Animation valueAnimator = (Animation) AnimationUtils.loadAnimation(context, animateID);
59 | into.setAnimation(valueAnimator);
60 | valueAnimator.start();
61 | break;
62 | default:
63 | into.clearAnimation();
64 | break;
65 | }
66 | }
67 |
68 | private void startAlphaAnimation(ImageView into) {
69 |
70 | AnimationSet animationSet = new AnimationSet(true);
71 | AlphaAnimation animation = new AlphaAnimation(0.1f, 1f);
72 | animation.setDuration(3000);
73 | animation.setFillAfter(true);
74 | animationSet.addAnimation(animation);
75 | into.startAnimation(animationSet);
76 |
77 | }
78 |
79 | public AnimateManage setAnimateID(int animateID) {
80 | this.animateID = animateID;
81 | return this;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PictureCache
2 | ## 关于
3 | ### PictureCache 是一个功能强大且易于使用的Android库。该库封装了Android开发中的大部分图片加载时的需求,通过使用其封装的API,可以大大提高开发效率。
4 | ### 使用效果,请根据简书地址查看。
5 | ### 简书地址:https://www.jianshu.com/p/e9a458a18be8
6 |
7 | # Android Studio集成方式
8 | ### 项目的build.gradle中引用如下:
9 | ```
10 | implementation 'com.lib:pic_cache:1.0.1'
11 |
12 | ```
13 | ### 根项目的build.gradle引用如下:
14 |
15 | ```
16 | allprojects {
17 | repositories {
18 | google()
19 | jcenter()
20 | maven { url "https://raw.githubusercontent.com/xiangmingzhe/PictureCache/master"}
21 | }
22 | }
23 | ```
24 |
25 | ## 设置图片四周圆角:
26 | Rhythm.with(context).load(url).transform(10.0f).into(imageView);
27 | ## 设置占位图:
28 | Rhythm.with(context).load(url).placeholder(R.drawable.xx).into(imageView);
29 | ## 加载错误视图:
30 | Rhythm.with(context).load(url).error(R.drawable.xx).into(imageView);
31 | ## 设置成圆形图片
32 | Rhythm.with(context).load(url).style(TypeEnum.CIRCLE).into(imageView);
33 | ## 设置圆形or圆角图片边框
34 | Rhythm.with(context).load(url).style(TypeEnum.CIRCLE).boarder(2).into(imageView);
35 |
36 | Rhythm.with(context).load(url).transform(10.0f).boarder(2).into(imageView);
37 | ## 增加图片渐变
38 |
39 | ## 图片懒加载
40 |
41 | ## 取消单个加载
42 | Rhythm.with(ListActivity.this).cancleTask(tag);
43 | ## 取消所有加载
44 | Rhythm.with(context).cancleAllTask();
45 |
46 | ## 加载图片高斯模糊效果
47 | Rhythm.with(context).bitmapTransform(new BlurTransformation(10)).into(imageView);
48 | 其中BlurTransformation中分别包括模糊半径和指定模糊前缩小的倍数。
49 |
50 |
51 | # 动画相关
52 | ### 图片淡入淡出效果
53 | Rhythm.with(context).load(url).crossFade().into(imageView);
54 | ### 支持图片自定义动画
55 | Rhythm.with(context).load(url).Animation(R.anim.xx).into(imageView);
56 | ### 设置无动画
57 | Rhythm.with(context).load(url).dontAnimation().into(imageView);
58 | # 增加图片水印功能,详细功能:分为居中,左上角,右上角,左下角,右下角
59 | ### (1)居中水印
60 | Rhythm.with(context).load(url).watermark(new WatermarkInfo(Watermark.CENTER,watermakeBitmap)).into(imageView);
61 | ### (2)左上角水印
62 | Rhythm.with(context).load(url)
63 | .watermark(new WatermarkInfo(Watermark.LEFT_TOP,watermakeBitmap,paddingLeft,paddingTop,paddingRight,paddingBottom))
64 | .into(imageView);
65 | ### (3)右上角水印
66 | Rhythm.with(context).load(url)
67 | .watermark(new WatermarkInfo(Watermark.RIGHT_TOP,watermakeBitmap,paddingLeft,paddingTop,paddingRight,paddingBottom))
68 | .into(imageView);
69 | ### (4)左下角水印
70 | Rhythm.with(context).load(url)
71 | .watermark(new WatermarkInfo(Watermark.LEFT_BOTTOM,watermakeBitmap,paddingLeft,paddingTop,paddingRight,paddingBottom))
72 | .into(imageView);
73 | ### (5)右下角水印
74 | Rhythm.with(context).load(url)
75 | .watermark(new WatermarkInfo(Watermark.RIGHT_BOTTOM,watermakeBitmap,paddingLeft,paddingTop,paddingRight,paddingBottom))
76 | .into(imageView);
77 |
78 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/widgets/vague/VagueView.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.widgets.vague;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Color;
6 | import android.media.Image;
7 | import android.os.Handler;
8 | import android.util.Log;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.picture.lib_rhythm.Rhythm;
15 | import com.picture.lib_rhythm.utils.BitmapUtils;
16 |
17 | import java.util.Arrays;
18 |
19 | /**
20 | * Time:2019/11/14
21 | * Author:xmz-dell
22 | * Description:
23 | */
24 | public class VagueView {
25 | volatile static VagueView singleton=null;
26 | private Bitmap mBitmap;
27 | private ImageView into;
28 | private Context context;
29 | public static VagueView with(Context context) {
30 | if (singleton == null) {
31 | synchronized (VagueView.class) {
32 | if (singleton == null) {
33 | singleton = new Builder(context).build();
34 | }
35 | }
36 | }
37 | return singleton;
38 | }
39 | public VagueView(Context context){
40 | this.context=context;
41 | }
42 |
43 | /***
44 | * 目标控件
45 | * @param into
46 | * @return
47 | */
48 | public VagueView into(ImageView into){
49 | this.into=into;
50 | return this;
51 | }
52 |
53 | /**
54 | * 目标资源
55 | * @param mBitmap
56 | * @return
57 | */
58 | public VagueView targetResources(Bitmap mBitmap){
59 | this.mBitmap=mBitmap;
60 | return this;
61 | }
62 | private byte[]bs;
63 | private Bitmap buildBitmap;
64 | /**
65 | * 构建模糊视图
66 | */
67 | public void buildVagueView(){
68 | if(this.mBitmap==null||this.into==null){
69 | throw new NullPointerException("targetResources cannot be empty|| into cannot be empty");
70 | }
71 | byte[]bytes= BitmapUtils.getBitmapByte(mBitmap);
72 | bs = Arrays.copyOfRange(bytes, 1, 40);
73 | handler.postDelayed(runnable,100);
74 | }
75 | private Handler handler=new Handler();
76 | private Runnable runnable=new Runnable() {
77 | @Override
78 | public void run() {
79 | // if(buildBitmap!=null){
80 | // buildBitmap.recycle();
81 | // buildBitmap=null;
82 | // }
83 | buildBitmap=BitmapUtils.getBitmapFromByte(bs);
84 | if(buildBitmap!=null){
85 | into.setImageBitmap(buildBitmap);
86 | }
87 |
88 | }
89 | };
90 | public static class Builder{
91 | private Context context;
92 | public Builder(Context context) {
93 | if (context == null) {
94 | throw new IllegalArgumentException("Context cannot be empty");
95 | }
96 | this.context = context.getApplicationContext();
97 | }
98 | public VagueView build(){
99 | return new VagueView(context);
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/cache/LruCache.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.cache;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.text.TextUtils;
6 |
7 | import com.picture.lib_rhythm.utils.Utils;
8 |
9 | import java.util.LinkedHashMap;
10 | import java.util.Map;
11 |
12 | /**
13 | * Time:2019/11/7
14 | * Author:xmz-dell
15 | * Description:
16 | */
17 | public class LruCache implements Cache{
18 | private int size;
19 | private int maxSize;
20 | private int cacheCount; //缓存计数
21 | private int evictionCount;//清除计数
22 | private final LinkedHashMap map;
23 |
24 | public LruCache(Context context){
25 | this(Utils.calculateMemoryCacheSize(context));
26 | }
27 | public LruCache(int maxSize){
28 | if(maxSize<=0){
29 | throw new IllegalArgumentException("Max size Cannot be less than or equal to 0");
30 | }
31 | this.maxSize=maxSize;
32 | this.map = new LinkedHashMap(0, 0.75f, true);
33 | }
34 |
35 | @Override
36 | public Bitmap get(String key) {
37 | if(TextUtils.isEmpty(key)){
38 | throw new NullPointerException("key Can not be empty");
39 | }
40 | synchronized (this){
41 | Bitmap bitmap;
42 | bitmap=map.get(key);
43 | if(bitmap!=null){
44 | cacheCount++;
45 | return bitmap;
46 | }
47 | }
48 | return null;
49 | }
50 |
51 | @Override
52 | public void set(String key, Bitmap bitmap) {
53 | if(TextUtils.isEmpty(key)||bitmap==null){
54 | throw new NullPointerException("key Can not be empty||bitmap Can not be empty");
55 | }
56 | Bitmap readyMoveBitmap;//等待移动的bitmap
57 | size+= Utils.getBitmapBytes(bitmap);//得到当前bitmap大小并叠加
58 | readyMoveBitmap=map.put(key,bitmap);
59 | if(readyMoveBitmap!=null){
60 | size-=Utils.getBitmapBytes(readyMoveBitmap);
61 | }
62 |
63 | reduceMemoryPressure();
64 | }
65 |
66 | /**
67 | * //如果当前size超过maxsize 就从前往后移除bitmap 来减少内存
68 | */
69 | public void reduceMemoryPressure(){
70 | while(true){
71 | String key;
72 | Bitmap bitmap;
73 | synchronized (this){
74 | if(size<0||map.isEmpty()){
75 | throw new NullPointerException("size Cannot be less than 0 ||map Can not be empty");
76 | }
77 | if(size<=maxSize||map.isEmpty()){//如果没有超过阈值就结束整个死循环;
78 | break;
79 | }
80 | Map.Entry decompose = map.entrySet().iterator().next();
81 | key=decompose.getKey();
82 | bitmap=decompose.getValue();
83 | map.remove(key);
84 | size-=Utils.getBitmapBytes(bitmap);
85 | evictionCount++;
86 | }
87 | }
88 | }
89 | @Override
90 | public int size() {
91 | return size;
92 | }
93 |
94 | @Override
95 | public int maxSize() {
96 | return maxSize;
97 | }
98 |
99 | @Override
100 | public void clear() {
101 | reduceMemoryPressure();
102 | }
103 |
104 | @Override
105 | public void clearKeyUri(String keyPrefix) {
106 |
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/bean/TagInfo.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.bean;
2 |
3 | import android.graphics.Bitmap;
4 | import android.widget.ImageView;
5 |
6 | import com.picture.lib_rhythm.constant.AnimateType;
7 | import com.picture.lib_rhythm.constant.Watermark;
8 | import com.picture.lib_rhythm.transformation.BlurTransformation;
9 |
10 | /**
11 | * Time:2019/11/12
12 | * Author:xmz-dell
13 | * Description:
14 | */
15 | public class TagInfo {
16 | private String url;
17 | private ImageView into;
18 | private Bitmap bitmap;
19 | private AnimateType animateType;
20 | private int animateID;
21 | private boolean isTag;
22 | private WatermarkInfo watermarkInfo;
23 | private BlurTransformation blurTransformation;
24 | public TagInfo(String url,ImageView into){
25 | this.url=url;
26 | this.into=into;
27 | }
28 | public TagInfo(String url,ImageView into,AnimateType animateType,int animateID){
29 | this.url=url;
30 | this.into=into;
31 | this.animateType=animateType;
32 | this.animateID=animateID;
33 | }
34 | public TagInfo(String url,ImageView into,AnimateType animateType,int animateID,BlurTransformation blurTransformation){
35 | this.url=url;
36 | this.into=into;
37 | this.animateType=animateType;
38 | this.animateID=animateID;
39 | this.blurTransformation=blurTransformation;
40 | }
41 | public TagInfo(String url,ImageView into,AnimateType animateType,int animateID,BlurTransformation blurTransformation,WatermarkInfo watermarkInfo){
42 | this.url=url;
43 | this.into=into;
44 | this.animateType=animateType;
45 | this.animateID=animateID;
46 | this.blurTransformation=blurTransformation;
47 | this.watermarkInfo=watermarkInfo;
48 | }
49 | public boolean isTag() {
50 | return isTag;
51 | }
52 |
53 | public void setTag(boolean tag) {
54 | isTag = tag;
55 | }
56 |
57 | public String getUrl() {
58 | return url;
59 | }
60 |
61 | public void setUrl(String url) {
62 | this.url = url;
63 | }
64 |
65 | public ImageView getInto() {
66 | return into;
67 | }
68 |
69 | public void setInto(ImageView into) {
70 | this.into = into;
71 | }
72 |
73 | public Bitmap getBitmap() {
74 | return bitmap;
75 | }
76 |
77 | public void setBitmap(Bitmap bitmap) {
78 | this.bitmap = bitmap;
79 | }
80 |
81 | public void setAnimateType(AnimateType animateType) {
82 | this.animateType = animateType;
83 | }
84 |
85 | public AnimateType getAnimateType() {
86 | return animateType;
87 | }
88 |
89 | public int getAnimateID() {
90 | return animateID;
91 | }
92 |
93 | public void setAnimateID(int animateID) {
94 | this.animateID = animateID;
95 | }
96 |
97 | public BlurTransformation getBlurTransformation() {
98 | return blurTransformation;
99 | }
100 |
101 | public void setBlurTransformation(BlurTransformation blurTransformation) {
102 | this.blurTransformation = blurTransformation;
103 | }
104 |
105 | public WatermarkInfo getWatermarkInfo() {
106 | return watermarkInfo;
107 | }
108 |
109 | public void setWatermarkInfo(WatermarkInfo watermarkInfo) {
110 | this.watermarkInfo = watermarkInfo;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
21 |
22 |
29 |
36 |
43 |
44 |
45 |
52 |
59 |
66 |
73 |
80 |
87 |
94 |
101 |
108 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dell/picturecache/ListActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache;
2 |
3 | import android.app.Activity;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 | import android.widget.Button;
10 |
11 | import com.example.dell.picturecache.adapter.RecyclerviewAdapter;
12 | import com.example.dell.picturecache.adapter.TestAdapter;
13 | import com.picture.lib_rhythm.Rhythm;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | public class ListActivity extends Activity {
19 | private RecyclerView rcy;
20 | private Button bt_cancleall;
21 | private Button bt_canclesingle;
22 | private String url="https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E";
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_list);
27 | initView();
28 | }
29 | private void initView(){
30 | bt_cancleall=findViewById(R.id.bt_cancleall);
31 | bt_canclesingle=findViewById(R.id.bt_canclesingle);
32 | bt_cancleall.setOnClickListener(new View.OnClickListener() {
33 | @Override
34 | public void onClick(View v) {
35 | Rhythm.with(ListActivity.this).cancleAllTask();
36 | }
37 | });
38 | bt_canclesingle.setOnClickListener(new View.OnClickListener() {
39 | @Override
40 | public void onClick(View v) {
41 | Rhythm.with(ListActivity.this).cancleTask("http://res.img.ifeng.com/2012/0428/wm_0ebc84813b2d4ac3b4096d6cbbe196d9.jpg");
42 | }
43 | });
44 | rcy=findViewById(R.id.rcy);
45 | LinearLayoutManager layoutManager = new LinearLayoutManager(this);
46 | layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
47 | rcy.setLayoutManager(layoutManager);
48 | TestAdapter adapter = new TestAdapter(R.layout.item_rcy, urlList());
49 | adapter.setContext(this);
50 | rcy.setAdapter(adapter);
51 | }
52 | private ListurlList(){
53 | ListstringList=new ArrayList<>();
54 | stringList.add("http://pic1.win4000.com/wallpaper/5/58e6f9a62e989.jpg");
55 | stringList.add("http://img4.imgtn.bdimg.com/it/u=3749936194,4185944615&fm=214&gp=0.jpg");
56 | stringList.add("http://res.img.ifeng.com/2012/0428/wm_0ebc84813b2d4ac3b4096d6cbbe196d9.jpg");
57 | stringList.add("http://pic1.win4000.com/wallpaper/5/58e6f99e65c3a.jpg");
58 | stringList.add("http://img010.hc360.cn/m1/M05/7D/12/wKhQcFQ1ZiKEC66RAAAAAHBFgKg402.jpg");
59 | stringList.add("http://img003.hc360.cn/m6/M04/4D/73/wKhQolYohXeEfWz9AAAAAEFYOl4869.JPG");
60 |
61 |
62 |
63 | stringList.add("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1186878998,3597197046&fm=15&gp=0.jpg");
64 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491422&di=1b9f7210e98335c311e575eff160a871&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F7%2F57eb892e7431e.jpg");
65 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491422&di=7239a2eca34de15dc0ae362a938f499d&imgtype=0&src=http%3A%2F%2Fwww.qqoi.cn%2Fimg_bizhi%2F70707972.jpeg");
66 | stringList.add("https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3120478776,2048301353&fm=26&gp=0.jpg");
67 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491421&di=1d37d910b7d6c153d2d561ffe74e3a0b&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2018-11-27%2F5bfce839a79b4.jpg");
68 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491421&di=7bede38544b5528cacf5c3c2acb9de51&imgtype=0&src=http%3A%2F%2Fp2.qhimgs4.com%2Ft0173189944640e215c.jpg");
69 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491420&di=0534745e2197fab1c37746e1b89c9beb&imgtype=0&src=http%3A%2F%2Fsc.68design.net%2Fphotofiles%2F201807%2FKUukqkpm5n.jpg");
70 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491419&di=6ed3929f5f638906648718c694f536ff&imgtype=0&src=http%3A%2F%2Fimg-download.pchome.net%2Fdownload%2F1k1%2F34%2F55%2Fofhy7l-1o88.jpg");
71 | stringList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574660491419&di=2e262de1639d01787a8226189b383744&imgtype=0&src=http%3A%2F%2Fstatic01.coloros.com%2Fbbs%2Fdata%2Fattachment%2Fforum%2F201508%2F27%2F084342curucwvezb30cll0.jpg");
72 |
73 |
74 |
75 | return stringList;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/cache/LocalCache.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.cache;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.os.Environment;
7 | import android.text.TextUtils;
8 | import android.util.Log;
9 |
10 | import com.picture.lib_rhythm.utils.Utils;
11 |
12 | import java.io.File;
13 | import java.io.FileInputStream;
14 | import java.io.FileOutputStream;
15 | import java.io.IOException;
16 | import java.io.UnsupportedEncodingException;
17 | import java.security.MessageDigest;
18 | import java.security.NoSuchAlgorithmException;
19 |
20 | /**
21 | * Time:2019/11/7
22 | * Author:xmz-dell
23 | * Description:本地文件
24 | * */
25 | public class LocalCache {
26 | private String cachePath;
27 |
28 | public LocalCache(Context context, String uniqueName) {
29 | if(TextUtils.isEmpty(uniqueName)){
30 | throw new NullPointerException("uniqueName Can not be empty");
31 | }
32 | cachePath = getCacheDirString(context, uniqueName);
33 | }
34 |
35 | /**
36 | * 根据url获取bitmap
37 | * @param url
38 | * @return
39 | */
40 | public Bitmap getBitmapFromLocal(String url){
41 | try{
42 | File file = new File(cachePath, encode(url));
43 | if (file.exists()) {
44 | // 如果文件存在
45 | Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
46 | return bitmap;
47 | }
48 | }catch (Exception e){
49 | e.printStackTrace();
50 | }
51 | return null;
52 | }
53 |
54 | /**
55 | * 获取缓存目录的路径
56 | * @param context
57 | * @param uniqueName
58 | * @return
59 | */
60 | private String getCacheDirString(Context context, String uniqueName) {
61 | File file = null;
62 | if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
63 | || !Environment.isExternalStorageRemovable()) {
64 | file = new File(context.getExternalCacheDir(), uniqueName);
65 | } else {
66 | file = new File(context.getCacheDir(), uniqueName);
67 | }
68 | if (!file.exists()) {
69 | file.mkdirs();
70 | }
71 | return file.getAbsolutePath();
72 | }
73 |
74 | /**
75 | * 设置Bitmap数据到本地
76 | *
77 | * @param url
78 | * @param bitmap
79 | */
80 | public void setBitmapToLocal(String url, Bitmap bitmap) {
81 | if(TextUtils.isEmpty(url)||bitmap==null){
82 | throw new NullPointerException("url Can not be empty || bitmap Can not be empty");
83 | }
84 | if(Utils.calculateSdCardCacheSize() T getService(Context context, String service) {
55 | return (T) context.getSystemService(service);
56 | }
57 |
58 | /**
59 | * 得到整个app分配的内存阈值
60 | * @param context
61 | * @return
62 | */
63 | public static int calculateMemoryCacheSize(Context context) {
64 | ActivityManager am = getService(context, ACTIVITY_SERVICE);
65 | boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
66 | int memoryClass = am.getMemoryClass();
67 | if (largeHeap && SDK_INT >= HONEYCOMB) {
68 | memoryClass = am.getLargeMemoryClass();
69 | }
70 | return 1024 * 1024 * memoryClass / 7;
71 | }
72 |
73 | /**
74 | * 获取sd剩余的空间
75 | * @return
76 | */
77 | public static long calculateSdCardCacheSize(){
78 | File datapath = Environment.getDataDirectory();
79 | StatFs dataFs=new StatFs(datapath.getPath());
80 | long sizes=(long)dataFs.getFreeBlocks()*(long)dataFs.getBlockSize();
81 | return sizes;
82 | }
83 |
84 | /**
85 | * 检查当前线程是否是主线程
86 | */
87 | public static void checkMain() {
88 | if (!isMain()) {
89 | throw new IllegalStateException("Method call should happen from the main thread.");
90 | }
91 | }
92 | public static boolean isMain() {
93 | return Looper.getMainLooper().getThread() == Thread.currentThread();
94 | }
95 |
96 |
97 | /**
98 | * 判断字符串是否为URL
99 | * @param urls 用户头像key
100 | * @return true:是URL、false:不是URL
101 | */
102 | public static boolean isHttpUrl(String urls) {
103 | boolean isurl = false;
104 | String regex = "(((https|http)?://)?([a-z0-9]+[.])|(www.))"
105 | + "\\w+[.|\\/]([a-z0-9]{0,})?[[.]([a-z0-9]{0,})]+((/[\\S&&[^,;\u4E00-\u9FA5]]+)+)?([.][a-z0-9]{0,}+|/?)";//设置正则表达式
106 | Pattern pat = Pattern.compile(regex.trim());//比对
107 | Matcher mat = pat.matcher(urls.trim());
108 | isurl = mat.matches();//判断是否匹配
109 | if (isurl) {
110 | isurl = true;
111 | }
112 | Log.d("--","isHttpUrl:"+isurl+"---:"+urls);
113 | return isurl;
114 | }
115 | public static boolean isNetUrl(String url) {
116 | boolean reault = false;
117 | if (url != null) {
118 | if (url.toLowerCase().startsWith("http") || url.toLowerCase().startsWith("rtsp") || url.toLowerCase().startsWith("mms")) {
119 | reault = true;
120 | }
121 | }
122 | return reault;
123 | }
124 | /**
125 | * 判断字符串是否为资源ID
126 | * @param resourcesId
127 | * @return
128 | */
129 | public static boolean isResourcesId(String resourcesId){
130 | try{
131 | Long.parseLong(resourcesId);
132 | return true;
133 | }catch (Exception e){
134 | return false;
135 | }
136 | }
137 |
138 | /**
139 | * 得到url的具体类型
140 | * @param url
141 | * @return
142 | */
143 | public static VisitType getUrlType(String url){
144 | if(isNetUrl(url)){
145 | return HTTP;
146 | }else if(isResourcesId(url)){
147 | return RESOURCES;
148 | }
149 | return LOCAL;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/widgets/gif/GifImageView.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.widgets.gif;
2 | import android.content.Context;
3 | import android.content.res.TypedArray;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Movie;
8 | import android.os.SystemClock;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.util.TypedValue;
12 | import android.view.View;
13 | import android.widget.ImageView;
14 |
15 |
16 | import com.picture.lib_rhythm.R;
17 |
18 | import java.io.InputStream;
19 | import java.lang.reflect.Field;
20 | /**
21 | * Time:2019/11/8
22 | * Author:xmz-dell
23 | * Description:
24 | */
25 | public class GifImageView extends ImageView
26 | {
27 |
28 |
29 | /**
30 | * 播放GIF动画的关键类
31 | */
32 | private Movie mMovie;
33 | /**
34 | * 控制播放的按钮
35 | */
36 | private Bitmap mStartButton;
37 |
38 | /**
39 | * 记录动画开始的时间
40 | */
41 | private long mMovieStart;
42 |
43 | /**
44 | * GIF图片的宽度
45 | */
46 | private int mImageWidth;
47 |
48 | /**
49 | * GIF图片的高度
50 | */
51 | private int mImageHeight;
52 |
53 | /**
54 | * 图片是否正在播放
55 | */
56 | private boolean isPlaying;
57 |
58 | /**
59 | * 是否允许自动播放
60 | */
61 | private boolean isAutoPlay;
62 |
63 | public GifImageView(Context context)
64 | {
65 | super(context);
66 | Log.e("ten", "72");
67 | }
68 |
69 | public GifImageView(Context context, AttributeSet attrs)
70 | {
71 | this(context, attrs, 0);
72 | Log.e("ten", "73");
73 | }
74 |
75 | public GifImageView(Context context, AttributeSet attrs, int defStyleAttr)
76 | {
77 | super(context, attrs, defStyleAttr);
78 |
79 | setImageResLoad(context, attrs, defStyleAttr);
80 |
81 | }
82 | public void isAutoPlay(boolean isAutoPlay){
83 | this.isAutoPlay=isAutoPlay;
84 | invalidate();
85 | }
86 | private void setImageResLoad(Context context, AttributeSet attrs, int defStyleAttr)
87 | {
88 | TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GifImageView);
89 | Log.e("ten", "1 ");
90 | int resourceID = getResourcesID(typedArray);
91 |
92 | if (resourceID != 0) {
93 | Log.e("ten", "2 ");
94 | InputStream inputStream = getResources().openRawResource(resourceID);
95 | //对图片进行解码
96 | mMovie = Movie.decodeStream(inputStream);
97 | if (mMovie != null) {
98 | Log.e("ten", "3 ");
99 | // 如果返回值不等于null,就说明这是一个GIF图片,下面获取是否自动播放的属性
100 | isAutoPlay = typedArray.getBoolean(R.styleable.GifImageView_auto_play, false);
101 | Bitmap bitmap ;
102 | bitmap = BitmapFactory.decodeStream(inputStream);
103 | if(bitmap!=null){
104 | mImageWidth = bitmap.getWidth();
105 | mImageHeight = bitmap.getHeight();
106 | bitmap.recycle();
107 | }else{
108 | bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.anim_flag_iceland);
109 | mImageWidth = bitmap.getWidth();
110 | mImageHeight = bitmap.getHeight();
111 | bitmap.recycle();
112 | }
113 |
114 | }
115 |
116 | }
117 | if (typedArray != null) {
118 | typedArray.recycle();
119 | }
120 | }
121 |
122 | /**
123 | * 通过Java反射,获取src指定图片资源所对应的id。
124 | */
125 | public int getResourcesID(TypedArray typedArray)
126 | {
127 | Log.e("ten", "4 ");
128 | try {
129 | Field field = TypedArray.class.getDeclaredField("mValue");
130 | field.setAccessible(true);
131 | TypedValue typedValueObject = (TypedValue) field.get(typedArray);
132 | return typedValueObject.resourceId;
133 | } catch (Exception e) {
134 | e.printStackTrace();
135 | } finally {
136 |
137 | }
138 | return 0;
139 | }
140 |
141 |
142 |
143 |
144 | @Override
145 | protected void onDraw(Canvas canvas)
146 | {
147 | Log.e("ten", "6");
148 | if (mMovie == null) {
149 | Log.e("ten", "7b");
150 | // mMovie等于null,说明是张普通的图片,则直接调用父类的onDraw()方法
151 | super.onDraw(canvas);
152 |
153 | } else {
154 | Log.e("ten", "7c");
155 | //如果mMovie不等于null,那就说明是gif图片
156 | if (isAutoPlay) {
157 | Log.e("ten", "7d");
158 | //如果允许播放,调用palyMovie();
159 | playMovie(canvas);
160 | invalidate();
161 | } else {
162 | Log.e("ten", "7e");
163 | //不允许自动播放,判断是否要播放
164 | if (isPlaying) {
165 | if (playMovie(canvas)) {
166 | isPlaying = false;
167 | Log.e("ten", "7f");
168 | }
169 | invalidate();
170 | } else {
171 | // 还没开始播放就只绘制GIF图片的第一帧,并绘制一个开始按钮
172 | Log.e("ten", "g");
173 | mMovie.setTime(0);
174 | mMovie.draw(canvas, 0, 0);
175 | int imageX = (mImageWidth - mStartButton.getWidth()) / 2;
176 | int imageY = (mImageHeight - mStartButton.getHeight()) / 2;
177 | canvas.drawBitmap(mStartButton, imageX, imageY, null);
178 |
179 | }
180 | }
181 | }
182 | }
183 |
184 | @Override
185 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
186 | {
187 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
188 | Log.e("ten", "onMeasure_1");
189 | if (mMovie != null) {
190 | Log.e("ten", "onMeasure_2");
191 | // 如果是GIF图片则重写设定myImageView的大小
192 | setMeasuredDimension(mImageWidth, mImageHeight);
193 | }
194 | }
195 | /**
196 | * 开始播放GIF动画,播放完成返回true,未完成返回false。
197 | *
198 | * @param canvas
199 | * @return 播放完成返回true,未完成返回false。
200 | */
201 | public boolean playMovie(Canvas canvas)
202 | {
203 | Log.e("ten", "playMovie_1");
204 | long now = SystemClock.uptimeMillis();
205 | if (mMovieStart == 0) {
206 | mMovieStart = now;
207 | }
208 | int duration = mMovie.duration();
209 | if (duration == 0) {
210 | duration = 1000;
211 | }
212 | int loadTime = (int) ((now - mMovieStart) % duration);
213 | mMovie.setTime(loadTime);
214 | mMovie.draw(canvas, 0, 0);
215 | if ((now - mMovieStart) >= duration) {
216 | mMovieStart = 0;
217 | return true;
218 | }
219 | return false;
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/dell/picturecache/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.dell.picturecache;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.ImageView;
11 |
12 | import com.picture.lib_rhythm.Rhythm;
13 | import com.picture.lib_rhythm.bean.WatermarkInfo;
14 | import com.picture.lib_rhythm.constant.GraphicalType;
15 | import com.picture.lib_rhythm.constant.Watermark;
16 | import com.picture.lib_rhythm.transformation.BlurTransformation;
17 |
18 | public class MainActivity extends Activity {
19 | private Button bt_loadimage;
20 | private Button bt_loadimage_id;
21 | private Button bt_loadimage_local;
22 | private Button bt_loadimage_circular;
23 | private ImageView imageView;
24 | private Button bt_loadimage_list;
25 | private Button bt_loadimage_progress;
26 | private Bitmap watermakeBitmap;
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_main);
31 | watermakeBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.add_realnameahtu);
32 | initView();
33 |
34 | }
35 | private void initView(){
36 | bt_loadimage=findViewById(R.id.bt_loadimage);
37 | bt_loadimage_id=findViewById(R.id.bt_loadimage_id);
38 | bt_loadimage_local=findViewById(R.id.bt_loadimage_local);
39 | bt_loadimage_circular=findViewById(R.id.bt_loadimage_circular);
40 | bt_loadimage_list=findViewById(R.id.bt_loadimage_list);
41 | imageView=findViewById(R.id.image);
42 | bt_loadimage_progress=findViewById(R.id.bt_loadimage_progress);
43 | bt_loadimage_list.setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | startActivity(new Intent(MainActivity.this,ListActivity.class));
47 | }
48 | });
49 | bt_loadimage.setOnClickListener(new View.OnClickListener() {
50 | @Override
51 | public void onClick(View v) {
52 | Rhythm.with(MainActivity.this)
53 | .transform(10.0f)
54 | .load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
55 | .into(imageView);
56 | }
57 | });
58 | bt_loadimage_circular.setOnClickListener(new View.OnClickListener() {
59 | @Override
60 | public void onClick(View v) {
61 | Rhythm.with(MainActivity.this)
62 | .style(GraphicalType.CIRCLE).boarder(3)
63 | .load("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3473688000,4044263570&fm=26&gp=0.jpg")
64 | .into(imageView);
65 | }
66 | });
67 | bt_loadimage_id.setOnClickListener(new View.OnClickListener() {
68 | @Override
69 | public void onClick(View v) {
70 | int rid=R.drawable.robot;
71 | Rhythm.with(MainActivity.this).transform(10.0f).bitmapTransform(new BlurTransformation(10)).load(rid).openGif(false).error(R.drawable.robot).placeholder(R.drawable.robot).into(imageView);
72 | }
73 | });
74 | bt_loadimage_local.setOnClickListener(new View.OnClickListener() {
75 | @Override
76 | public void onClick(View v) {
77 | Rhythm.with(MainActivity.this).transform(10.0f).load("https://uinpay.oss-cn-shenzhen.aliyuncs.com/icon/20190515/caifu.png").openGif(false).error(R.drawable.robot).placeholder(R.drawable.robot).into(imageView);
78 | }
79 | });
80 | bt_loadimage_progress.setOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 |
84 | }
85 | });
86 | findViewById(R.id.bt_loadimage_rsblue).setOnClickListener(new View.OnClickListener() {
87 | @Override
88 | public void onClick(View v) {
89 | Rhythm.with(MainActivity.this)
90 | .bitmapTransform(new BlurTransformation(10))
91 | .load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
92 | .into(imageView);
93 | }
94 | });
95 | findViewById(R.id.bt_loadimage_animate).setOnClickListener(new View.OnClickListener() {
96 | @Override
97 | public void onClick(View v) {
98 | Rhythm.with(MainActivity.this)
99 | .crossFade()
100 | .load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
101 | .into(imageView);
102 | }
103 | });
104 |
105 |
106 |
107 | //居中水印
108 | findViewById(R.id.bt_loadimage_center_watermark).setOnClickListener(new View.OnClickListener() {
109 | @Override
110 | public void onClick(View v) {
111 | Rhythm.with(MainActivity.this)
112 | .load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
113 | .watermark(new WatermarkInfo(Watermark.CENTER,watermakeBitmap)).into(imageView);
114 | }
115 | });
116 | //左上水印
117 | findViewById(R.id.bt_loadimage_left_top).setOnClickListener(new View.OnClickListener() {
118 | @Override
119 | public void onClick(View v) {
120 | Rhythm.with(MainActivity.this).load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
121 | .watermark(new WatermarkInfo(Watermark.LEFT_TOP,watermakeBitmap,10,10,0,0)).into(imageView);
122 | }
123 | });
124 | //右上水印
125 | findViewById(R.id.bt_loadimage_right_top).setOnClickListener(new View.OnClickListener() {
126 | @Override
127 | public void onClick(View v) {
128 | Rhythm.with(MainActivity.this).load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
129 | .watermark(new WatermarkInfo(Watermark.RIGHT_TOP,watermakeBitmap,0,10,10,0)).into(imageView);
130 | }
131 | });
132 | //左下水印
133 | findViewById(R.id.bt_loadimage_left_bottom).setOnClickListener(new View.OnClickListener() {
134 | @Override
135 | public void onClick(View v) {
136 | Rhythm.with(MainActivity.this).load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
137 | .watermark(new WatermarkInfo(Watermark.LEFT_BOTTOM,watermakeBitmap,10,0,0,10)).into(imageView);
138 | }
139 | });
140 | //右下水印
141 | findViewById(R.id.bt_loadimage_right_bottom).setOnClickListener(new View.OnClickListener() {
142 | @Override
143 | public void onClick(View v) {
144 | Rhythm.with(MainActivity.this).load("https://pics7.baidu.com/feed/e1fe9925bc315c6019816a380ec27c164854774d.jpeg?token=d21ab74381ca956c4ca28ef5c90e4868&s=30FE7084C273359450A844900300708E")
145 | .watermark(new WatermarkInfo(Watermark.RIGHT_BOTTOM,watermakeBitmap,0,0,10,10)).into(imageView);
146 | }
147 | });
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/lib_rhythm/src/main/java/com/picture/lib_rhythm/cache/NetCache.java:
--------------------------------------------------------------------------------
1 | package com.picture.lib_rhythm.cache;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.drawable.Drawable;
7 | import android.os.AsyncTask;
8 | import android.os.Handler;
9 | import android.os.Message;
10 | import android.text.TextUtils;
11 | import android.util.Log;
12 | import android.widget.ImageView;
13 |
14 | import com.picture.lib_rhythm.R;
15 | import com.picture.lib_rhythm.RequestCreator;
16 | import com.picture.lib_rhythm.bean.TagInfo;
17 | import com.picture.lib_rhythm.utils.BitmapUtils;
18 | import com.picture.lib_rhythm.widgets.gif.GifImageView;
19 |
20 | import java.io.InputStream;
21 | import java.net.HttpURLConnection;
22 | import java.net.URL;
23 | import java.util.Iterator;
24 | import java.util.Map;
25 |
26 | /**
27 | * Time:2019/11/7
28 | * Author:xmz-dell
29 | * Description:网络缓存类
30 | */
31 | public class NetCache {
32 | private LruCache lruCache;
33 | private LocalCache localCache;
34 | private static final String TAG="NetCache";
35 | private Drawable errorDrawable;
36 | private Context mContext;
37 | private float radius=0f;
38 | public BitmapTask bitmapTask;
39 | public NetCache(Cache lruCache,LocalCache localCache){
40 | this.lruCache=(LruCache) lruCache;
41 | this.localCache=localCache;
42 | }
43 | Handler handler = new Handler() {
44 | @Override
45 | public void handleMessage(Message msg) {
46 | Object[] objects = (Object[]) msg.obj;
47 | ImageView imageView = (ImageView) objects[0];
48 | String mUrl = (String) objects[1];
49 | imageView.setTag(mUrl);
50 | setErrorView(objects,imageView);
51 | }
52 | };
53 |
54 | /**
55 | * 错误视图
56 | * @param errorDrawable
57 | * @return
58 | */
59 | public NetCache error(Drawable errorDrawable){
60 | this.errorDrawable=errorDrawable;
61 | return this;
62 | }
63 | /**
64 | * 设置圆角
65 | * @param radius 弧度
66 | * @return
67 | */
68 | public NetCache transform(float radius) {
69 | this.radius=radius;
70 | return this;
71 | }
72 |
73 | /**
74 | * 是否需要设置圆角
75 | * @return
76 | */
77 | private boolean isRoundCorner(){
78 | return radius!=0f?true:false;
79 | }
80 | /**
81 | * 设置错误视图
82 | * @param objects
83 | * @param imageView
84 | */
85 | private void setErrorView(Object[] objects,ImageView imageView){
86 | if(errorDrawable!=null){
87 | boolean isSuccess=(boolean) objects[2];
88 | if(!isSuccess){
89 | if(isRoundCorner()){
90 | Bitmap bitmap=BitmapUtils.toRoundCorner(errorDrawable,radius,0);
91 | imageView.setImageBitmap(bitmap);
92 | }else{
93 | imageView.setImageDrawable(errorDrawable);
94 | }
95 | }
96 | }
97 | }
98 | /**
99 | * 加载图片
100 | * @param iv
101 | * @param url
102 | */
103 | public void loadBitmap(final ImageView iv, final String url, Context context){
104 | if(iv==null||TextUtils.isEmpty(url)||context==null){
105 | throw new NullPointerException("ImageView Can not be empty || url Can not be empty || context Can not be empty");
106 | }
107 | this.mContext=context;
108 | new Handler().post(new Runnable() {
109 | @Override
110 | public void run() {
111 | Bitmap bitmap=loadBitmap(url);
112 | if(bitmap!=null){
113 | sendBitmap(bitmap);
114 | }else{
115 | bitmapTask=new BitmapTask();
116 | pushTaskToMap(url,bitmapTask);
117 | bitmapTask.execute(iv, url);// 启动AsyncTask,
118 | }
119 | }
120 | });
121 | }
122 |
123 | /**
124 | * 将所有异步任务存储
125 | * @param url
126 | * @param bitmapTask
127 | */
128 | private void pushTaskToMap(String url,BitmapTask bitmapTask){
129 | RequestCreator.getInstance().taskMap.put(url,bitmapTask);
130 | }
131 | /**
132 | * 取消单个请求
133 | */
134 | public void cancleTask(String tag){
135 | MaptaskMap= RequestCreator.getInstance().taskMap;
136 | Iterator iterator =taskMap.keySet().iterator();// map中key(键)的迭代器对象
137 | while (iterator.hasNext()){// 循环取键值进行判断
138 | String key = iterator.next();// 键
139 | if(tag.equals(key)){
140 | BitmapTask bitmapTask = taskMap.get(key);
141 | if(bitmapTask!=null){
142 | bitmapTask.cancel(true);
143 | iterator.remove();
144 | break;
145 | }
146 | }
147 | }
148 | }
149 |
150 | /**
151 | * 取消全部请求
152 | */
153 | public void cancleAllTask(){
154 | MaptaskMap= RequestCreator.getInstance().taskMap;
155 | Iterator iterator =taskMap.keySet().iterator();// map中key(键)的迭代器对象
156 | while (iterator.hasNext()){// 循环取键值进行判断
157 | String key = iterator.next();// 键
158 | BitmapTask bitmapTask = taskMap.get(key);
159 | if(bitmapTask!=null){
160 | bitmapTask.cancel(true);
161 | iterator.remove();
162 | }
163 |
164 | }
165 | }
166 |
167 | /**
168 | * 尝试下加载内存-->磁盘
169 | * @param url
170 | * @return
171 | */
172 | private Bitmap loadBitmap(String url){
173 | if(lruCache.get(url)!=null){
174 | return lruCache.get(url);
175 | }
176 | if(localCache.getBitmapFromLocal(url)!=null){
177 | return localCache.getBitmapFromLocal(url);
178 | }
179 | return null;
180 | }
181 |
182 |
183 | /**
184 | * Handler和线程池的封装
185 | *
186 | * 第一个泛型: 参数类型
187 | * 第二个泛型: 更新进度的泛型,
188 | * 第三个泛型是onPostExecute的返回结果
189 | */
190 | public class BitmapTask extends AsyncTask