18 | */
19 | public class BitmapUtils {
20 |
21 | public static boolean saveBitmap(Bitmap bitmap, String filePath) {
22 | File file=new File(filePath);
23 | try {
24 | BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream(file));
25 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
26 | bos.flush();
27 | bos.close();
28 | return true;
29 | } catch (IOException e) {
30 | e.printStackTrace();
31 | return false;
32 | }
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/maning/mnimagebrowser/utils/DatasUtils.java:
--------------------------------------------------------------------------------
1 | package com.maning.mnimagebrowser.utils;
2 |
3 | import java.util.ArrayList;
4 |
5 | public class DatasUtils {
6 |
7 | public static ArrayList getDatas() {
8 | ArrayList sourceImageList = new ArrayList<>();
9 | sourceImageList.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1523527461022&di=cf56170de9cd14bd24299af8597ee88d&imgtype=0&src=http%3A%2F%2Fpic13.nipic.com%2F20110414%2F7056815_094945110000_2.jpg");
10 | sourceImageList.add("https://i.loli.net/2020/07/03/4eYAaqHP8TbzFlO.png");
11 | sourceImageList.add("https://i.loli.net/2020/07/03/vf59KgBpw2SAd8Z.jpg");
12 | sourceImageList.add("https://user-gold-cdn.xitu.io/2019/1/25/168839e977414cc1?imageView2/2/w/800/q/100");
13 | sourceImageList.add("https://i.loli.net/2020/07/03/R2gmx8M6Ipq9Tet.jpg");
14 | sourceImageList.add("https://i.loli.net/2020/07/03/rJoGVeEAuaR2vUc.jpg");
15 | sourceImageList.add("https://i.loli.net/2020/07/03/okhQsTYLFz8vt4R.jpg");
16 | sourceImageList.add("https://i.loli.net/2020/07/03/DlvVI6tUxhCXrgn.jpg");
17 | sourceImageList.add("https://i.loli.net/2020/07/03/VuPorMXWSpt8sqH.jpg");
18 |
19 | return sourceImageList;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/maning/mnimagebrowser/view/SquareLayout.java:
--------------------------------------------------------------------------------
1 | package com.maning.mnimagebrowser.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.RelativeLayout;
6 |
7 | /**
8 | * Created by maning on 2017/5/25.
9 | */
10 |
11 | public class SquareLayout extends RelativeLayout {
12 | public SquareLayout(Context context, AttributeSet attrs, int defStyle) {
13 | super(context, attrs, defStyle);
14 | }
15 |
16 | public SquareLayout(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | public SquareLayout(Context context) {
21 | super(context);
22 | }
23 |
24 | @SuppressWarnings("unused")
25 | @Override
26 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
27 | super.onMeasure(widthMeasureSpec, widthMeasureSpec);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/maning/mnimagebrowser/view/SuperGridView.java:
--------------------------------------------------------------------------------
1 | package com.maning.mnimagebrowser.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.GridView;
6 |
7 | /**
8 | * @author : maning
9 | * @date : 2020/11/23
10 | * @desc :
11 | */
12 | public class SuperGridView extends GridView {
13 |
14 | public SuperGridView(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | }
17 |
18 | public SuperGridView(Context context) {
19 | super(context);
20 | }
21 |
22 | public SuperGridView(Context context, AttributeSet attrs, int defStyle) {
23 | super(context, attrs, defStyle);
24 | }
25 |
26 | @Override
27 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
28 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
29 | super.onMeasure(widthMeasureSpec, expandSpec);
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/activity_anmie_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/activity_anmie_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/default_placeholder.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/default_placeholder.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_01.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_02.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_close.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_more.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_save_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_save_fail.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_save_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/icon_save_success.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/long_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/long_pic.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/long_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/drawable-xxhdpi/long_test.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/custom_indicator_bg_selected.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/custom_indicator_bg_unselected.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
15 |
16 |
24 |
25 |
26 |
27 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
17 |
18 |
26 |
27 |
32 |
33 |
41 |
42 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/image_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_custom_image_view_fresco.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_custom_progress_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_custom_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
30 |
31 |
32 |
33 |
40 |
41 |
55 |
56 |
63 |
64 |
71 |
72 |
79 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_main_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
23 |
24 |
29 |
30 |
35 |
36 |
41 |
42 |
43 |
44 |
48 |
49 |
53 |
54 |
60 |
61 |
66 |
67 |
72 |
73 |
74 |
75 |
76 |
80 |
81 |
85 |
86 |
91 |
92 |
97 |
98 |
103 |
104 |
105 |
106 |
110 |
111 |
115 |
116 |
122 |
123 |
128 |
129 |
134 |
135 |
140 |
141 |
142 |
143 |
147 |
148 |
152 |
153 |
159 |
160 |
165 |
166 |
171 |
172 |
173 |
174 |
175 |
179 |
180 |
184 |
185 |
191 |
192 |
196 |
197 |
201 |
202 |
208 |
209 |
213 |
214 |
218 |
219 |
225 |
226 |
230 |
231 |
235 |
236 |
242 |
243 |
247 |
248 |
252 |
253 |
258 |
259 |
263 |
264 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/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/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Default
6 | DepthPage
7 | RotateDown
8 | RotateUp
9 | ZoomIn
10 | ZoomOut
11 | ZoomOutSlide
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #00000000
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 | MNImageBrowser
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 | apply from: "config.gradle"
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | jcenter()
8 | maven { url "https://jitpack.io" }
9 | mavenCentral()
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:4.0.0'
13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | maven { url "https://jitpack.io" }
24 | mavenCentral()
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | /**
2 | * 全局统一配置
3 | */
4 | ext {
5 |
6 | /**
7 | * 版本统一管理
8 | */
9 | versions = [
10 | versionCode : 137, //版本号
11 | versionName : "1.3.7", //版本名称
12 |
13 | compileSdkVersion: 29,
14 | minSdkVersion : 14,
15 | targetSdkVersion : 28,
16 |
17 | ]
18 |
19 | appId = [
20 | "app": "com.maning.mnimagebrowser",
21 | ]
22 |
23 | dependenciesGoogle = [
24 | annotation : 'androidx.annotation:annotation:1.1.0',
25 | supportv4 : 'androidx.legacy:legacy-support-v4:1.0.0',
26 | appcompat : 'androidx.appcompat:appcompat:1.2.0',
27 | design : 'com.google.android.material:material:1.0.0',
28 | recyclerView : 'androidx.recyclerview:recyclerview:1.0.0',
29 | constraintlayout: 'androidx.constraintlayout:constraintlayout:1.1.3',
30 | multidex : 'androidx.multidex:multidex:2.0.0',
31 | ]
32 |
33 | dependenciesOther = [
34 | "picasso" : "com.squareup.picasso:picasso:2.71828",
35 | "glide" : "com.github.bumptech.glide:glide:4.11.0",
36 | "fresco" : "com.facebook.fresco:fresco:2.2.0",
37 | "mnprogresshud": "com.github.maning0303:MNProgressHUD:V1.1.8X",
38 | "permission" : "com.yanzhenjie.permission:x:2.0.1",
39 | ]
40 |
41 | dependenciesCompiler = [
42 | "glide_compiler": "com.github.bumptech.glide:compiler:4.11.0",
43 | ]
44 |
45 | dependenciesDebug = [
46 | "leakcanary": "com.squareup.leakcanary:leakcanary-android:2.5",
47 | ]
48 |
49 | }
--------------------------------------------------------------------------------
/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.useAndroidX=true
19 | android.enableJetifier=true
20 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maning0303/MNImageBrowser/e13292683fe10577642ead98cd1b9e90ba23c4f5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Dec 09 15:09:46 CST 2020
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-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 |
4 | group='com.github.maning0303'
5 |
6 | def versions = rootProject.ext.versions
7 | def appId = rootProject.ext.appId
8 |
9 | android {
10 | compileSdkVersion versions.compileSdkVersion
11 | defaultConfig {
12 | minSdkVersion versions.minSdkVersion
13 | targetSdkVersion versions.targetSdkVersion
14 | versionCode versions.versionCode
15 | versionName versions.versionName
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | }
25 |
26 | dependencies {
27 | // implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | compileOnly 'androidx.appcompat:appcompat:1.2.0'
29 | compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
30 | }
31 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/maning/Develop/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 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
15 |
16 |
19 |
20 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/ImageEngine.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.widget.ImageView;
6 |
7 | /**
8 | * author : maning
9 | * time : 2018/04/10
10 | * desc : 图片引擎
11 | * version: 1.0
12 | */
13 | public interface ImageEngine {
14 |
15 | /**
16 | * 加载图片方法
17 | *
18 | * @param context 上下文
19 | * @param url 图片地址
20 | * @param imageView ImageView
21 | * @param progressView 进度View
22 | * @param customImageView 自定义加载图片,替换PhotoView
23 | */
24 | void loadImage(Context context, String url, ImageView imageView, View progressView, View customImageView);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/listeners/OnActivityLifeListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.listeners;
2 |
3 | /**
4 | * author : maning
5 | * time : 2018/06/04
6 | * desc : 页面生命周期
7 | * version: 1.0
8 | */
9 | public interface OnActivityLifeListener {
10 |
11 | void onCreate();
12 |
13 | void onResume();
14 |
15 | void onPause();
16 |
17 | void onDestory();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/listeners/OnClickListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.listeners;
2 |
3 | import android.view.View;
4 | import android.widget.ImageView;
5 |
6 | import androidx.fragment.app.FragmentActivity;
7 |
8 | /**
9 | * author : maning
10 | * time : 2018/04/10
11 | * desc : 点击监听
12 | * version: 1.0
13 | */
14 | public interface OnClickListener {
15 |
16 | void onClick(FragmentActivity activity, View view, int position, String url);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/listeners/OnLongClickListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.listeners;
2 |
3 | import android.view.View;
4 | import android.widget.ImageView;
5 |
6 | import androidx.fragment.app.FragmentActivity;
7 |
8 | /**
9 | * author : maning
10 | * time : 2018/04/10
11 | * desc : 长按监听
12 | * version: 1.0
13 | */
14 | public interface OnLongClickListener {
15 |
16 | void onLongClick(FragmentActivity activity, View view, int position, String url);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/listeners/OnPageChangeListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.listeners;
2 |
3 | /**
4 | * author : maning
5 | * time : 2018/06/04
6 | * desc : 滑动监听
7 | * version: 1.0
8 | */
9 | public interface OnPageChangeListener {
10 |
11 | void onPageSelected(int position);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/ABaseTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | import androidx.viewpager.widget.ViewPager;
22 |
23 | public abstract class ABaseTransformer implements ViewPager.PageTransformer {
24 |
25 | /**
26 | * Called each {@link #transformPage(View, float)}.
27 | *
28 | * @param page
29 | * Apply the transformation to this page
30 | * @param position
31 | * Position of page relative to the current front-and-center position of the pager. 0 is front and
32 | * center. 1 is one full page position to the right, and -1 is one page position to the left.
33 | */
34 | protected abstract void onTransform(View page, float position);
35 |
36 | /**
37 | * Apply a property transformation to the given page. For most use cases, this method should not be overridden.
38 | * Instead use {@link #transformPage(View, float)} to perform typical transformations.
39 | *
40 | * @param page
41 | * Apply the transformation to this page
42 | * @param position
43 | * Position of page relative to the current front-and-center position of the pager. 0 is front and
44 | * center. 1 is one full page position to the right, and -1 is one page position to the left.
45 | */
46 | @Override
47 | public void transformPage(View page, float position) {
48 | onPreTransform(page, position);
49 | onTransform(page, position);
50 | onPostTransform(page, position);
51 | }
52 |
53 | /**
54 | * If the position offset of a fragment is less than negative one or greater than one, returning true will set the
55 | * fragment alpha to 0f. Otherwise fragment alpha is always defaulted to 1f.
56 | *
57 | * @return
58 | */
59 | protected boolean hideOffscreenPages() {
60 | return true;
61 | }
62 |
63 | /**
64 | * Indicates if the default animations of the view pager should be used.
65 | *
66 | * @return
67 | */
68 | protected boolean isPagingEnabled() {
69 | return false;
70 | }
71 |
72 | /**
73 | * Called each {@link #transformPage(View, float)} before {{@link #onTransform(View, float)}.
74 | *
75 | * The default implementation attempts to reset all view properties. This is useful when toggling transforms that do
76 | * not modify the same page properties. For instance changing from a transformation that applies rotation to a
77 | * transformation that fades can inadvertently leave a fragment stuck with a rotation or with some degree of applied
78 | * alpha.
79 | *
80 | * @param page
81 | * Apply the transformation to this page
82 | * @param position
83 | * Position of page relative to the current front-and-center position of the pager. 0 is front and
84 | * center. 1 is one full page position to the right, and -1 is one page position to the left.
85 | */
86 | protected void onPreTransform(View page, float position) {
87 | final float width = page.getWidth();
88 |
89 | page.setRotationX(0);
90 | page.setRotationY(0);
91 | page.setRotation(0);
92 | page.setScaleX(1);
93 | page.setScaleY(1);
94 | page.setPivotX(0);
95 | page.setPivotY(0);
96 | page.setTranslationY(0);
97 | page.setTranslationX(isPagingEnabled() ? 0f : -width * position);
98 |
99 | if (hideOffscreenPages()) {
100 | page.setAlpha(position <= -1f || position >= 1f ? 0f : 1f);
101 | page.setEnabled(false);
102 | } else {
103 | page.setEnabled(true);
104 | page.setAlpha(1f);
105 | }
106 | }
107 |
108 | /**
109 | * Called each {@link #transformPage(View, float)} after {@link #onTransform(View, float)}.
110 | *
111 | * @param page
112 | * Apply the transformation to this page
113 | * @param position
114 | * Position of page relative to the current front-and-center position of the pager. 0 is front and
115 | * center. 1 is one full page position to the right, and -1 is one page position to the left.
116 | */
117 | protected void onPostTransform(View page, float position) {
118 | }
119 |
120 | /**
121 | *
122 | * @param val
123 | * @param min
124 | * @return
125 | */
126 | protected static final float min(float val, float min) {
127 | return val < min ? min : val;
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/DefaultTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class DefaultTransformer extends ABaseTransformer {
22 |
23 | @Override
24 | protected void onTransform(View view, float position) {
25 | }
26 |
27 | @Override
28 | public boolean isPagingEnabled() {
29 | return true;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/DepthPageTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class DepthPageTransformer extends ABaseTransformer {
22 |
23 | private static final float MIN_SCALE = 0.75f;
24 |
25 | @Override
26 | protected void onTransform(View view, float position) {
27 | if (position <= 0f) {
28 | view.setTranslationX(0f);
29 | view.setScaleX(1f);
30 | view.setScaleY(1f);
31 | } else if (position <= 1f) {
32 | final float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
33 | view.setAlpha(1 - position);
34 | view.setPivotY(0.5f * view.getHeight());
35 | view.setTranslationX(view.getWidth() * -position);
36 | view.setScaleX(scaleFactor);
37 | view.setScaleY(scaleFactor);
38 | }
39 | }
40 |
41 | @Override
42 | protected boolean isPagingEnabled() {
43 | return true;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/RotateDownTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class RotateDownTransformer extends ABaseTransformer {
22 |
23 | private static final float ROT_MOD = -15f;
24 |
25 | @Override
26 | protected void onTransform(View view, float position) {
27 | final float width = view.getWidth();
28 | final float height = view.getHeight();
29 | final float rotation = ROT_MOD * position * -1.25f;
30 |
31 | view.setPivotX(width * 0.5f);
32 | view.setPivotY(height);
33 | view.setRotation(rotation);
34 | }
35 |
36 | @Override
37 | protected boolean isPagingEnabled() {
38 | return true;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/RotateUpTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class RotateUpTransformer extends ABaseTransformer {
22 |
23 | private static final float ROT_MOD = -15f;
24 |
25 | @Override
26 | protected void onTransform(View view, float position) {
27 | final float width = view.getWidth();
28 | final float rotation = ROT_MOD * position;
29 |
30 | view.setPivotX(width * 0.5f);
31 | view.setPivotY(0f);
32 | view.setTranslationX(0f);
33 | view.setRotation(rotation);
34 | }
35 |
36 | @Override
37 | protected boolean isPagingEnabled() {
38 | return true;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/ZoomInTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class ZoomInTransformer extends ABaseTransformer {
22 |
23 | @Override
24 | protected void onTransform(View view, float position) {
25 | final float scale = position < 0 ? position + 1f : Math.abs(1f - position);
26 | view.setScaleX(scale);
27 | view.setScaleY(scale);
28 | view.setPivotX(view.getWidth() * 0.5f);
29 | view.setPivotY(view.getHeight() * 0.5f);
30 | view.setAlpha(position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/ZoomOutSlideTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class ZoomOutSlideTransformer extends ABaseTransformer {
22 |
23 | private static final float MIN_SCALE = 0.85f;
24 | private static final float MIN_ALPHA = 0.5f;
25 |
26 | @Override
27 | protected void onTransform(View view, float position) {
28 | if (position >= -1 || position <= 1) {
29 | // Modify the default slide transition to shrink the page as well
30 | final float height = view.getHeight();
31 | final float width = view.getWidth();
32 | final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
33 | final float vertMargin = height * (1 - scaleFactor) / 2;
34 | final float horzMargin = width * (1 - scaleFactor) / 2;
35 |
36 | // Center vertically
37 | view.setPivotY(0.5f * height);
38 | view.setPivotX(0.5f * width);
39 |
40 | if (position < 0) {
41 | view.setTranslationX(horzMargin - vertMargin / 2);
42 | } else {
43 | view.setTranslationX(-horzMargin + vertMargin / 2);
44 | }
45 |
46 | // Scale the page down (between MIN_SCALE and 1)
47 | view.setScaleX(scaleFactor);
48 | view.setScaleY(scaleFactor);
49 |
50 | // Fade the page relative to its size.
51 | view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/transforms/ZoomOutTransformer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Toxic Bakery
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.maning.imagebrowserlibrary.transforms;
18 |
19 | import android.view.View;
20 |
21 | public class ZoomOutTransformer extends ABaseTransformer {
22 |
23 | @Override
24 | protected void onTransform(View view, float position) {
25 | final float scale = 1f + Math.abs(position);
26 | view.setScaleX(scale);
27 | view.setScaleY(scale);
28 | view.setPivotX(view.getWidth() * 0.5f);
29 | view.setPivotY(view.getHeight() * 0.5f);
30 | view.setAlpha(position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
31 | if(position == -1){
32 | view.setTranslationX(view.getWidth() * -1);
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/FastClickUtils.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils;
2 |
3 |
4 | public class FastClickUtils {
5 | private static long lastClickTime = 0;//上次点击的时间
6 | private static int spaceTime = 500;//时间间隔
7 |
8 | public static boolean isFastClick() {
9 | long currentTime = System.currentTimeMillis();
10 | boolean isFastClick;//是否快速点击
11 | if (currentTime - lastClickTime > spaceTime) {
12 | isFastClick = false;
13 | } else {
14 | isFastClick = true;
15 | }
16 | lastClickTime = currentTime;
17 | return isFastClick;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/BarHide.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * bar的状态
5 | *
6 | * @author geyifeng
7 | * @date 2017/4/25
8 | */
9 | public enum BarHide {
10 | /**
11 | * 隐藏状态栏
12 | * Flag hide status bar bar hide.
13 | */
14 | FLAG_HIDE_STATUS_BAR,
15 | /**
16 | * 隐藏导航栏
17 | * Flag hide navigation bar bar hide.
18 | */
19 | FLAG_HIDE_NAVIGATION_BAR,
20 | /**
21 | * 隐藏状态栏和导航栏
22 | * Flag hide bar bar hide.
23 | */
24 | FLAG_HIDE_BAR,
25 | /**
26 | * 显示状态栏和导航栏
27 | * Flag show bar bar hide.
28 | */
29 | FLAG_SHOW_BAR
30 | }
31 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/BarParams.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.graphics.Color;
4 | import android.view.View;
5 | import android.view.WindowManager;
6 |
7 | import androidx.annotation.ColorInt;
8 | import androidx.annotation.FloatRange;
9 |
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | /**
14 | * 沉浸式参数信息
15 | *
16 | * @author geyifeng
17 | * @date 2017 /5/9
18 | */
19 | public class BarParams implements Cloneable {
20 | /**
21 | * 状态栏颜色
22 | * The Status bar color.
23 | */
24 | @ColorInt
25 | public int statusBarColor = Color.TRANSPARENT;
26 | /**
27 | * 导航栏颜色
28 | * The Navigation bar color.
29 | */
30 | @ColorInt
31 | public int navigationBarColor = Color.BLACK;
32 |
33 | /**
34 | * The Default navigation bar color.
35 | */
36 | public int defaultNavigationBarColor = Color.BLACK;
37 | /**
38 | * 状态栏透明度
39 | * The Status bar alpha.
40 | */
41 | @FloatRange(from = 0f, to = 1f)
42 | public float statusBarAlpha = 0.0f;
43 | /**
44 | * 导航栏透明度
45 | * The Navigation bar alpha.
46 | */
47 | @FloatRange(from = 0f, to = 1f)
48 | public float navigationBarAlpha = 0.0f;
49 | /**
50 | * 有导航栏的情况,全屏显示
51 | * The Full screen.
52 | */
53 | public boolean fullScreen = false;
54 | /**
55 | * 是否隐藏了导航栏
56 | * The Hide navigation bar.
57 | */
58 | public boolean hideNavigationBar = false;
59 | /**
60 | * 隐藏Bar
61 | * The Bar hide.
62 | */
63 | public BarHide barHide = BarHide.FLAG_SHOW_BAR;
64 | /**
65 | * 状态栏字体深色与亮色标志位
66 | * The Dark font.
67 | */
68 | public boolean statusBarDarkFont = false;
69 |
70 | /**
71 | * 导航栏图标深色与亮色标志位
72 | * The Navigation bar dark icon.
73 | */
74 | public boolean navigationBarDarkIcon = false;
75 | /**
76 | * 是否启用 自动根据StatusBar颜色调整深色模式与亮色模式
77 | * The Auto status bar dark mode enable.
78 | */
79 | public boolean autoStatusBarDarkModeEnable = false;
80 |
81 | /**
82 | * 是否启用 自动根据NavigationBar颜色调整深色模式与亮色模式
83 | * The Auto navigation bar dark mode enable.
84 | */
85 | public boolean autoNavigationBarDarkModeEnable = false;
86 |
87 | /**
88 | * The Auto status bar dark mode alpha.
89 | */
90 | @FloatRange(from = 0f, to = 1f)
91 | public float autoStatusBarDarkModeAlpha = 0.0f;
92 |
93 | /**
94 | * The Auto navigation bar dark mode alpha.
95 | */
96 | @FloatRange(from = 0f, to = 1f)
97 | public float autoNavigationBarDarkModeAlpha = 0.0f;
98 |
99 | /**
100 | * 是否可以修改状态栏颜色
101 | * The Status bar flag.
102 | */
103 | public boolean statusBarColorEnabled = true;
104 | /**
105 | * 状态栏变换后的颜色
106 | * The Status bar color transform.
107 | */
108 | @ColorInt
109 | public int statusBarColorTransform = Color.BLACK;
110 | /**
111 | * 导航栏变换后的颜色
112 | * The Navigation bar color transform.
113 | */
114 | @ColorInt
115 | public int navigationBarColorTransform = Color.BLACK;
116 | /**
117 | * 支持view变色
118 | * The View map.
119 | */
120 | Map> viewMap = new HashMap<>();
121 | /**
122 | * The View alpha.
123 | */
124 | @FloatRange(from = 0f, to = 1f)
125 | public float viewAlpha = 0.0f;
126 | /**
127 | * The Status bar color content view.
128 | */
129 | @ColorInt
130 | public int contentColor = Color.TRANSPARENT;
131 | /**
132 | * The Status bar color content view transform.
133 | */
134 | @ColorInt
135 | public int contentColorTransform = Color.BLACK;
136 | /**
137 | * The Status bar content view alpha.
138 | */
139 | @FloatRange(from = 0f, to = 1f)
140 | public float contentAlpha = 0.0f;
141 | /**
142 | * 解决标题栏与状态栏重叠问题
143 | * The Fits.
144 | */
145 | public boolean fits = false;
146 | /**
147 | * 解决标题栏与状态栏重叠问题
148 | * The Title bar view.
149 | */
150 | public View titleBarView;
151 | /**
152 | * 解决标题栏与状态栏重叠问题
153 | * The Status bar view by height.
154 | */
155 | public View statusBarView;
156 | /**
157 | * flymeOS状态栏字体变色
158 | * The Flyme os status bar font color.
159 | */
160 | @ColorInt
161 | public int flymeOSStatusBarFontColor;
162 | /**
163 | * 结合actionBar使用
164 | * The Is support action bar.
165 | */
166 | public boolean isSupportActionBar = false;
167 | /**
168 | * 解决软键盘与输入框冲突问题
169 | * The Keyboard enable.
170 | */
171 | public boolean keyboardEnable = false;
172 |
173 | /**
174 | * 软键盘属性
175 | * The Keyboard mode.
176 | */
177 | public int keyboardMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
178 | | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
179 | /**
180 | * 是否能修改导航栏颜色
181 | * The Navigation bar enable.
182 | */
183 | public boolean navigationBarEnable = true;
184 | /**
185 | * 是否能修改4.4手机以及华为emui3.1导航栏颜色
186 | * The Navigation bar with kitkat enable.
187 | */
188 | public boolean navigationBarWithKitkatEnable = true;
189 | /**
190 | * 是否可以修改emui3系列手机导航栏
191 | * The Navigation bar with emui 3 enable.
192 | */
193 | public boolean navigationBarWithEMUI3Enable = true;
194 | /**
195 | * 是否可以沉浸式
196 | * The Init enable.
197 | */
198 | public boolean barEnable = true;
199 | /**
200 | * 软键盘监听类
201 | * The On keyboard listener.
202 | */
203 | OnKeyboardListener onKeyboardListener;
204 |
205 | /**
206 | * 导航栏显示隐藏监听
207 | */
208 | OnNavigationBarListener onNavigationBarListener;
209 |
210 | /**
211 | * 横竖屏监听
212 | */
213 | OnBarListener onBarListener;
214 |
215 | @Override
216 | protected BarParams clone() {
217 | BarParams barParams = null;
218 | try {
219 | barParams = (BarParams) super.clone();
220 | } catch (CloneNotSupportedException ignored) {
221 | }
222 | return barParams;
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/BarProperties.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * Bar相关信息
5 | *
6 | * @author geyifeng
7 | * @date 2019-05-10 18:43
8 | */
9 | public class BarProperties {
10 |
11 | /**
12 | * 是否是竖屏
13 | */
14 | private boolean portrait;
15 | /**
16 | * 是否是左横屏
17 | */
18 | private boolean landscapeLeft;
19 | /**
20 | * 是否是右横屏
21 | */
22 | private boolean landscapeRight;
23 | /**
24 | * 是否是刘海屏
25 | */
26 | private boolean notchScreen;
27 | /**
28 | * 是否有导航栏
29 | */
30 | private boolean hasNavigationBar;
31 | /**
32 | * 状态栏高度,刘海屏横竖屏有可能状态栏高度不一样
33 | */
34 | private int statusBarHeight;
35 | /**
36 | * 导航栏高度
37 | */
38 | private int navigationBarHeight;
39 | /**
40 | * 导航栏宽度
41 | */
42 | private int navigationBarWidth;
43 | /**
44 | * 刘海屏高度
45 | */
46 | private int notchHeight;
47 | /**
48 | * ActionBar高度
49 | */
50 | private int actionBarHeight;
51 |
52 | public boolean isPortrait() {
53 | return portrait;
54 | }
55 |
56 | void setPortrait(boolean portrait) {
57 | this.portrait = portrait;
58 | }
59 |
60 | public boolean isLandscapeLeft() {
61 | return landscapeLeft;
62 | }
63 |
64 | void setLandscapeLeft(boolean landscapeLeft) {
65 | this.landscapeLeft = landscapeLeft;
66 | }
67 |
68 | public boolean isLandscapeRight() {
69 | return landscapeRight;
70 | }
71 |
72 | void setLandscapeRight(boolean landscapeRight) {
73 | this.landscapeRight = landscapeRight;
74 | }
75 |
76 | public boolean isNotchScreen() {
77 | return notchScreen;
78 | }
79 |
80 | void setNotchScreen(boolean notchScreen) {
81 | this.notchScreen = notchScreen;
82 | }
83 |
84 | public boolean hasNavigationBar() {
85 | return hasNavigationBar;
86 | }
87 |
88 | void setNavigationBar(boolean hasNavigationBar) {
89 | this.hasNavigationBar = hasNavigationBar;
90 | }
91 |
92 | public int getStatusBarHeight() {
93 | return statusBarHeight;
94 | }
95 |
96 | void setStatusBarHeight(int statusBarHeight) {
97 | this.statusBarHeight = statusBarHeight;
98 | }
99 |
100 | public int getNavigationBarHeight() {
101 | return navigationBarHeight;
102 | }
103 |
104 | void setNavigationBarHeight(int navigationBarHeight) {
105 | this.navigationBarHeight = navigationBarHeight;
106 | }
107 |
108 | public int getNavigationBarWidth() {
109 | return navigationBarWidth;
110 | }
111 |
112 | void setNavigationBarWidth(int navigationBarWidth) {
113 | this.navigationBarWidth = navigationBarWidth;
114 | }
115 |
116 | public int getNotchHeight() {
117 | return notchHeight;
118 | }
119 |
120 | void setNotchHeight(int notchHeight) {
121 | this.notchHeight = notchHeight;
122 | }
123 |
124 | public int getActionBarHeight() {
125 | return actionBarHeight;
126 | }
127 |
128 | void setActionBarHeight(int actionBarHeight) {
129 | this.actionBarHeight = actionBarHeight;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/Constants.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import com.maning.imagebrowserlibrary.R;
4 |
5 | /**
6 | * @author geyifeng
7 | * @date 2019/4/12 6:39 PM
8 | */
9 | class Constants {
10 | /**
11 | * android 4.4或者emui3状态栏ID识位
12 | */
13 | static final int IMMERSION_ID_STATUS_BAR_VIEW = R.id.mn_ib_status_bar_view;
14 | /**
15 | * android 4.4或者emui3导航栏ID识位
16 | */
17 | static final int IMMERSION_ID_NAVIGATION_BAR_VIEW = R.id.mn_ib_navigation_bar_view;
18 | /**
19 | * 状态栏高度标识位
20 | */
21 | static final String IMMERSION_STATUS_BAR_HEIGHT = "status_bar_height";
22 | /**
23 | * 导航栏竖屏高度标识位
24 | */
25 | static final String IMMERSION_NAVIGATION_BAR_HEIGHT = "navigation_bar_height";
26 | /**
27 | * 导航栏横屏高度标识位
28 | */
29 | static final String IMMERSION_NAVIGATION_BAR_HEIGHT_LANDSCAPE = "navigation_bar_height_landscape";
30 | /**
31 | * 导航栏宽度标识位位
32 | */
33 | static final String IMMERSION_NAVIGATION_BAR_WIDTH = "navigation_bar_width";
34 | /**
35 | * MIUI导航栏显示隐藏标识位
36 | */
37 | static final String IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW = "force_fsg_nav_bar";
38 | /**
39 | * EMUI导航栏显示隐藏标识位
40 | */
41 | static final String IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW = "navigationbar_is_min";
42 | /**
43 | * MIUI状态栏字体黑色与白色标识位
44 | */
45 | static final String IMMERSION_MIUI_STATUS_BAR_DARK = "EXTRA_FLAG_STATUS_BAR_DARK_MODE";
46 | /**
47 | * MIUI导航栏图标黑色与白色标识位
48 | */
49 | static final String IMMERSION_MIUI_NAVIGATION_BAR_DARK = "EXTRA_FLAG_NAVIGATION_BAR_DARK_MODE";
50 |
51 | /**
52 | * 自动改变字体颜色的临界值标识位
53 | */
54 | static final int IMMERSION_BOUNDARY_COLOR = 0xFFBABABA;
55 |
56 | /**
57 | * 修复状态栏与布局重叠标识位,默认不修复
58 | */
59 | static final int FLAG_FITS_DEFAULT = 0X00;
60 | /**
61 | * 修复状态栏与布局重叠标识位,使用titleBar方法修复
62 | */
63 | static final int FLAG_FITS_TITLE = 0X01;
64 | /**
65 | * 修复状态栏与布局重叠标识位,使用titleBarMarginTop方法修复
66 | */
67 | static final int FLAG_FITS_TITLE_MARGIN_TOP = 0X02;
68 | /**
69 | * 修复状态栏与布局重叠标识位,使用StatusBarView方法修复
70 | */
71 | static final int FLAG_FITS_STATUS = 0X03;
72 | /**
73 | * 修复状态栏与布局重叠标识位,使用fitsSystemWindows方法修复
74 | */
75 | static final int FLAG_FITS_SYSTEM_WINDOWS = 0X04;
76 | }
77 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/EMUI3NavigationBarObserver.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Application;
4 | import android.database.ContentObserver;
5 | import android.net.Uri;
6 | import android.os.Build;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.provider.Settings;
10 |
11 | import java.util.ArrayList;
12 |
13 | import static com.maning.imagebrowserlibrary.utils.immersionbar.Constants.IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW;
14 |
15 |
16 | /**
17 | * 华为Emui3状态栏监听器
18 | *
19 | * @author geyifeng
20 | * @date 2019/4/10 6:02 PM
21 | */
22 | final class EMUI3NavigationBarObserver extends ContentObserver {
23 |
24 | private ArrayList mCallbacks;
25 | private Application mApplication;
26 | private Boolean mIsRegister = false;
27 |
28 | static EMUI3NavigationBarObserver getInstance() {
29 | return NavigationBarObserverInstance.INSTANCE;
30 | }
31 |
32 | private EMUI3NavigationBarObserver() {
33 | super(new Handler(Looper.getMainLooper()));
34 | }
35 |
36 | void register(Application application) {
37 | this.mApplication = application;
38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mApplication != null
39 | && mApplication.getContentResolver() != null && !mIsRegister) {
40 | Uri uri = Settings.System.getUriFor(IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW);
41 | if (uri != null) {
42 | mApplication.getContentResolver().registerContentObserver(uri, true, this);
43 | mIsRegister = true;
44 | }
45 | }
46 | }
47 |
48 | @Override
49 | public void onChange(boolean selfChange) {
50 | super.onChange(selfChange);
51 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mApplication != null && mApplication.getContentResolver() != null
52 | && mCallbacks != null && !mCallbacks.isEmpty()) {
53 | int show = Settings.System.getInt(mApplication.getContentResolver(), IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW, 0);
54 | for (ImmersionCallback callback : mCallbacks) {
55 | callback.onNavigationBarChange(show != 1);
56 | }
57 | }
58 | }
59 |
60 | void addOnNavigationBarListener(ImmersionCallback callback) {
61 | if (callback == null) {
62 | return;
63 | }
64 | if (mCallbacks == null) {
65 | mCallbacks = new ArrayList<>();
66 | }
67 | if (!mCallbacks.contains(callback)) {
68 | mCallbacks.add(callback);
69 | }
70 | }
71 |
72 | void removeOnNavigationBarListener(ImmersionCallback callback) {
73 | if (callback == null || mCallbacks == null) {
74 | return;
75 | }
76 | mCallbacks.remove(callback);
77 | }
78 |
79 | private static class NavigationBarObserverInstance {
80 | private static final EMUI3NavigationBarObserver INSTANCE = new EMUI3NavigationBarObserver();
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/FitsKeyboard.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Rect;
5 | import android.os.Build;
6 | import android.view.View;
7 | import android.view.ViewTreeObserver;
8 | import android.view.Window;
9 | import android.widget.FrameLayout;
10 |
11 | import androidx.drawerlayout.widget.DrawerLayout;
12 |
13 | /**
14 | * 适配软键盘弹出问题
15 | *
16 | * @author geyifeng
17 | * @date 2018/11/9 10:24 PM
18 | */
19 | class FitsKeyboard implements ViewTreeObserver.OnGlobalLayoutListener {
20 |
21 | private int mStatusBarHeight;
22 | private int mActionBarHeight;
23 | private ImmersionBar mImmersionBar;
24 | private Activity mActivity;
25 | private Window mWindow;
26 | private View mDecorView;
27 | private View mContentView;
28 | private View mChildView;
29 | private int mPaddingLeft = 0, mPaddingTop = 0, mPaddingRight = 0, mPaddingBottom = 0;
30 | private int mTempKeyboardHeight;
31 | private boolean mIsAddListener;
32 |
33 | FitsKeyboard(ImmersionBar immersionBar, Activity activity, Window window) {
34 | mImmersionBar = immersionBar;
35 | mActivity = activity;
36 | mWindow = window;
37 | mDecorView = mWindow.getDecorView();
38 | FrameLayout frameLayout = mDecorView.findViewById(android.R.id.content);
39 | mChildView = frameLayout.getChildAt(0);
40 | if (mChildView != null) {
41 | if (mChildView instanceof DrawerLayout) {
42 | mChildView = ((DrawerLayout) mChildView).getChildAt(0);
43 | }
44 | if (mChildView != null) {
45 | mPaddingLeft = mChildView.getPaddingLeft();
46 | mPaddingTop = mChildView.getPaddingTop();
47 | mPaddingRight = mChildView.getPaddingRight();
48 | mPaddingBottom = mChildView.getPaddingBottom();
49 | }
50 | }
51 | mContentView = mChildView != null ? mChildView : frameLayout;
52 | BarConfig barConfig = new BarConfig(mActivity);
53 | mStatusBarHeight = barConfig.getStatusBarHeight();
54 | mActionBarHeight = barConfig.getActionBarHeight();
55 | }
56 |
57 | void enable(int mode) {
58 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
59 | mWindow.setSoftInputMode(mode);
60 | if (!mIsAddListener) {
61 | mDecorView.getViewTreeObserver().addOnGlobalLayoutListener(this);
62 | mIsAddListener = true;
63 | }
64 | }
65 | }
66 |
67 | /**
68 | * 为啥要更新?因为横竖屏切换状态栏高度有可能不一样
69 | * Update bar config.
70 | *
71 | * @param barConfig the bar config
72 | */
73 | void updateBarConfig(BarConfig barConfig) {
74 | mStatusBarHeight = barConfig.getStatusBarHeight();
75 | if (mImmersionBar != null && mImmersionBar.isActionBarBelowLOLLIPOP()) {
76 | mActionBarHeight = barConfig.getActionBarHeight();
77 | }
78 | }
79 |
80 | void disable() {
81 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mIsAddListener) {
82 | if (mChildView != null) {
83 | mContentView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
84 | } else {
85 | mContentView.setPadding(mImmersionBar.getPaddingLeft(),
86 | mImmersionBar.getPaddingTop(),
87 | mImmersionBar.getPaddingRight(),
88 | mImmersionBar.getPaddingBottom());
89 | }
90 | }
91 | }
92 |
93 | void cancel() {
94 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mIsAddListener) {
95 | mDecorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
96 | mIsAddListener = false;
97 | }
98 | }
99 |
100 | @Override
101 | public void onGlobalLayout() {
102 | if (mImmersionBar != null && mImmersionBar.getBarParams() != null && mImmersionBar.getBarParams().keyboardEnable) {
103 | int bottom = 0, keyboardHeight, navigationBarHeight = ImmersionBar.getNavigationBarHeight(mActivity);
104 | boolean isPopup = false;
105 | Rect rect = new Rect();
106 | //获取当前窗口可视区域大小
107 | mDecorView.getWindowVisibleDisplayFrame(rect);
108 | keyboardHeight = mContentView.getHeight() - rect.bottom;
109 | if (keyboardHeight != mTempKeyboardHeight) {
110 | mTempKeyboardHeight = keyboardHeight;
111 | if (!ImmersionBar.checkFitsSystemWindows(mWindow.getDecorView().findViewById(android.R.id.content))) {
112 | if (mChildView != null) {
113 | if (mImmersionBar.getBarParams().isSupportActionBar) {
114 | keyboardHeight += mActionBarHeight + mStatusBarHeight;
115 | }
116 | if (mImmersionBar.getBarParams().fits) {
117 | keyboardHeight += mStatusBarHeight;
118 | }
119 | if (keyboardHeight > navigationBarHeight) {
120 | bottom = keyboardHeight + mPaddingBottom;
121 | isPopup = true;
122 | }
123 | mContentView.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, bottom);
124 | } else {
125 | bottom = mImmersionBar.getPaddingBottom();
126 | keyboardHeight -= navigationBarHeight;
127 | if (keyboardHeight > navigationBarHeight) {
128 | bottom = keyboardHeight + navigationBarHeight;
129 | isPopup = true;
130 | }
131 | mContentView.setPadding(mImmersionBar.getPaddingLeft(),
132 | mImmersionBar.getPaddingTop(),
133 | mImmersionBar.getPaddingRight(),
134 | bottom);
135 | }
136 | } else {
137 | keyboardHeight -= navigationBarHeight;
138 | if (keyboardHeight > navigationBarHeight) {
139 | isPopup = true;
140 | }
141 | }
142 | if (keyboardHeight < 0) {
143 | keyboardHeight = 0;
144 | }
145 | if (mImmersionBar.getBarParams().onKeyboardListener != null) {
146 | mImmersionBar.getBarParams().onKeyboardListener.onKeyboardChange(isPopup, keyboardHeight);
147 | }
148 | if (!isPopup && mImmersionBar.getBarParams().barHide != BarHide.FLAG_SHOW_BAR) {
149 | mImmersionBar.setBar();
150 | }
151 | }
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/FlymeOSStatusBarFontUtils.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.os.Build;
5 | import android.view.View;
6 | import android.view.Window;
7 | import android.view.WindowManager;
8 |
9 | import java.lang.reflect.Field;
10 | import java.lang.reflect.InvocationTargetException;
11 | import java.lang.reflect.Method;
12 |
13 | /**
14 | * Flyme OS 修改状态栏字体颜色工具类
15 | *
16 | * @author gyf
17 | * @date 2017 /05/30
18 | */
19 | public class FlymeOSStatusBarFontUtils {
20 | private static Method mSetStatusBarColorIcon;
21 | private static Method mSetStatusBarDarkIcon;
22 | private static Field mStatusBarColorFiled;
23 | private static int SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0;
24 |
25 | static {
26 | try {
27 | mSetStatusBarColorIcon = Activity.class.getMethod("setStatusBarDarkIcon", int.class);
28 | } catch (NoSuchMethodException ignored) {
29 |
30 | }
31 | try {
32 | mSetStatusBarDarkIcon = Activity.class.getMethod("setStatusBarDarkIcon", boolean.class);
33 | } catch (NoSuchMethodException ignored) {
34 |
35 | }
36 | try {
37 | mStatusBarColorFiled = WindowManager.LayoutParams.class.getField("statusBarColor");
38 | } catch (NoSuchFieldException ignored) {
39 |
40 | }
41 | try {
42 | Field field = View.class.getField("SYSTEM_UI_FLAG_LIGHT_STATUS_BAR");
43 | SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = field.getInt(null);
44 | } catch (NoSuchFieldException ignored) {
45 |
46 | } catch (IllegalAccessException ignored) {
47 |
48 | }
49 | }
50 |
51 | /**
52 | * 判断颜色是否偏黑色
53 | *
54 | * @param color 颜色
55 | * @param level 级别
56 | * @return boolean boolean
57 | */
58 | public static boolean isBlackColor(int color, int level) {
59 | int grey = toGrey(color);
60 | return grey < level;
61 | }
62 |
63 | /**
64 | * 颜色转换成灰度值
65 | *
66 | * @param rgb 颜色
67 | * @return the int
68 | * @return 灰度值
69 | */
70 | public static int toGrey(int rgb) {
71 | int blue = rgb & 0x000000FF;
72 | int green = (rgb & 0x0000FF00) >> 8;
73 | int red = (rgb & 0x00FF0000) >> 16;
74 | return (red * 38 + green * 75 + blue * 15) >> 7;
75 | }
76 |
77 | /**
78 | * 设置状态栏字体图标颜色
79 | *
80 | * @param activity 当前activity
81 | * @param color 颜色
82 | */
83 | public static void setStatusBarDarkIcon(Activity activity, int color) {
84 | if (mSetStatusBarColorIcon != null) {
85 | try {
86 | mSetStatusBarColorIcon.invoke(activity, color);
87 | } catch (IllegalAccessException e) {
88 | e.printStackTrace();
89 | } catch (InvocationTargetException e) {
90 | e.printStackTrace();
91 | }
92 | } else {
93 | boolean whiteColor = isBlackColor(color, 50);
94 | if (mStatusBarColorFiled != null) {
95 | setStatusBarDarkIcon(activity, whiteColor, whiteColor);
96 | setStatusBarDarkIcon(activity.getWindow(), color);
97 | } else {
98 | setStatusBarDarkIcon(activity, whiteColor);
99 | }
100 | }
101 | }
102 |
103 | /**
104 | * 设置状态栏字体图标颜色(只限全屏非activity情况)
105 | *
106 | * @param window 当前窗口
107 | * @param color 颜色
108 | */
109 | public static void setStatusBarDarkIcon(Window window, int color) {
110 | try {
111 | setStatusBarColor(window, color);
112 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
113 | setStatusBarDarkIcon(window.getDecorView(), true);
114 | }
115 | } catch (Exception e) {
116 | e.printStackTrace();
117 | }
118 | }
119 |
120 | /**
121 | * 设置状态栏字体图标颜色
122 | *
123 | * @param activity 当前activity
124 | * @param dark 是否深色 true为深色 false 为白色
125 | */
126 | public static void setStatusBarDarkIcon(Activity activity, boolean dark) {
127 | setStatusBarDarkIcon(activity, dark, true);
128 | }
129 |
130 | private static boolean changeMeizuFlag(WindowManager.LayoutParams winParams, String flagName, boolean on) {
131 | try {
132 | Field f = winParams.getClass().getDeclaredField(flagName);
133 | f.setAccessible(true);
134 | int bits = f.getInt(winParams);
135 | Field f2 = winParams.getClass().getDeclaredField("meizuFlags");
136 | f2.setAccessible(true);
137 | int meizuFlags = f2.getInt(winParams);
138 | int oldFlags = meizuFlags;
139 | if (on) {
140 | meizuFlags |= bits;
141 | } else {
142 | meizuFlags &= ~bits;
143 | }
144 | if (oldFlags != meizuFlags) {
145 | f2.setInt(winParams, meizuFlags);
146 | return true;
147 | }
148 | } catch (NoSuchFieldException e) {
149 | e.printStackTrace();
150 | } catch (IllegalAccessException e) {
151 | e.printStackTrace();
152 | } catch (IllegalArgumentException e) {
153 | e.printStackTrace();
154 | } catch (Throwable e) {
155 | e.printStackTrace();
156 | }
157 | return false;
158 | }
159 |
160 | /**
161 | * 设置状态栏颜色
162 | *
163 | * @param view
164 | * @param dark
165 | */
166 | private static void setStatusBarDarkIcon(View view, boolean dark) {
167 | int oldVis = view.getSystemUiVisibility();
168 | int newVis = oldVis;
169 | if (dark) {
170 | newVis |= SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
171 | } else {
172 | newVis &= ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
173 | }
174 | if (newVis != oldVis) {
175 | view.setSystemUiVisibility(newVis);
176 | }
177 | }
178 |
179 | /**
180 | * 设置状态栏颜色
181 | *
182 | * @param window
183 | * @param color
184 | */
185 | private static void setStatusBarColor(Window window, int color) {
186 | WindowManager.LayoutParams winParams = window.getAttributes();
187 | if (mStatusBarColorFiled != null) {
188 | try {
189 | int oldColor = mStatusBarColorFiled.getInt(winParams);
190 | if (oldColor != color) {
191 | mStatusBarColorFiled.set(winParams, color);
192 | window.setAttributes(winParams);
193 | }
194 | } catch (IllegalAccessException e) {
195 | e.printStackTrace();
196 | }
197 | }
198 | }
199 |
200 | /**
201 | * 设置状态栏字体图标颜色(只限全屏非activity情况)
202 | *
203 | * @param window 当前窗口
204 | * @param dark 是否深色 true为深色 false 为白色
205 | */
206 | public static void setStatusBarDarkIcon(Window window, boolean dark) {
207 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
208 | changeMeizuFlag(window.getAttributes(), "MEIZU_FLAG_DARK_STATUS_BAR_ICON", dark);
209 | } else {
210 | View decorView = window.getDecorView();
211 | setStatusBarDarkIcon(decorView, dark);
212 | setStatusBarColor(window, 0);
213 | }
214 | }
215 |
216 | private static void setStatusBarDarkIcon(Activity activity, boolean dark, boolean flag) {
217 | if (mSetStatusBarDarkIcon != null) {
218 | try {
219 | mSetStatusBarDarkIcon.invoke(activity, dark);
220 | } catch (IllegalAccessException e) {
221 | e.printStackTrace();
222 | } catch (InvocationTargetException e) {
223 | e.printStackTrace();
224 | }
225 | } else {
226 | if (flag) {
227 | setStatusBarDarkIcon(activity.getWindow(), dark);
228 | }
229 | }
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/ImmersionCallback.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * The interface Immersion callback.
5 | *
6 | * @author geyifeng
7 | * @date 2019 /4/11 5:04 PM
8 | */
9 | interface ImmersionCallback extends OnNavigationBarListener, Runnable {
10 | }
11 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/ImmersionDelegate.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.res.Configuration;
6 | import android.os.Build;
7 | import android.view.Surface;
8 |
9 | import androidx.fragment.app.DialogFragment;
10 | import androidx.fragment.app.Fragment;
11 |
12 | /**
13 | * @author geyifeng
14 | * @date 2019/4/12 4:01 PM
15 | */
16 | class ImmersionDelegate implements Runnable {
17 |
18 | private ImmersionBar mImmersionBar;
19 | private int mStatusBarHeight = 0;
20 | private BarProperties mBarProperties;
21 | private OnBarListener mOnBarListener;
22 | private int mNotchHeight;
23 |
24 | ImmersionDelegate(Object o) {
25 | if (o instanceof Activity) {
26 | if (mImmersionBar == null) {
27 | mImmersionBar = new ImmersionBar((Activity) o);
28 | mStatusBarHeight = ImmersionBar.getStatusBarHeight((Activity) o);
29 | }
30 | } else if (o instanceof Fragment) {
31 | if (mImmersionBar == null) {
32 | if (o instanceof DialogFragment) {
33 | mImmersionBar = new ImmersionBar((DialogFragment) o);
34 | } else {
35 | mImmersionBar = new ImmersionBar((Fragment) o);
36 | }
37 | mStatusBarHeight = ImmersionBar.getStatusBarHeight((Fragment) o);
38 | }
39 | } else if (o instanceof android.app.Fragment) {
40 | if (mImmersionBar == null) {
41 | if (o instanceof android.app.DialogFragment) {
42 | mImmersionBar = new ImmersionBar((android.app.DialogFragment) o);
43 | } else {
44 | mImmersionBar = new ImmersionBar((android.app.Fragment) o);
45 | }
46 | mStatusBarHeight = ImmersionBar.getStatusBarHeight((android.app.Fragment) o);
47 | }
48 | }
49 | }
50 |
51 | ImmersionDelegate(Activity activity, Dialog dialog) {
52 | if (mImmersionBar == null) {
53 | mImmersionBar = new ImmersionBar(activity, dialog);
54 | mStatusBarHeight = ImmersionBar.getStatusBarHeight(activity);
55 | }
56 | }
57 |
58 | public ImmersionBar get() {
59 | return mImmersionBar;
60 | }
61 |
62 | void onActivityCreated(Configuration configuration) {
63 | barChanged(configuration);
64 | }
65 |
66 | void onResume() {
67 | if (mImmersionBar != null && !mImmersionBar.isFragment() && mImmersionBar.initialized()) {
68 | if (OSUtils.isEMUI3_x() && mImmersionBar.getBarParams().navigationBarWithEMUI3Enable) {
69 | reinitialize();
70 | } else {
71 | if (mImmersionBar.getBarParams().barHide != BarHide.FLAG_SHOW_BAR) {
72 | mImmersionBar.setBar();
73 | }
74 | }
75 | }
76 | }
77 |
78 | void onDestroy() {
79 | mBarProperties = null;
80 | if (mImmersionBar != null) {
81 | mImmersionBar.destroy();
82 | mImmersionBar = null;
83 | }
84 | }
85 |
86 | void onConfigurationChanged(Configuration newConfig) {
87 | if (mImmersionBar != null) {
88 | if (OSUtils.isEMUI3_x() || Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
89 | if (mImmersionBar.initialized() && !mImmersionBar.isFragment() && mImmersionBar.getBarParams().navigationBarWithKitkatEnable) {
90 | reinitialize();
91 | } else {
92 | fitsWindows();
93 | }
94 | } else {
95 | fitsWindows();
96 | }
97 | barChanged(newConfig);
98 | }
99 | }
100 |
101 | /**
102 | * 重新初始化,适配一些特殊机型
103 | */
104 | private void reinitialize() {
105 | if (mImmersionBar != null) {
106 | mImmersionBar.init();
107 | }
108 | }
109 |
110 | /**
111 | * 状态栏高度改变的时候重新适配布局重叠问题
112 | */
113 | private void fitsWindows() {
114 | int statusBarHeight = ImmersionBar.getStatusBarHeight(mImmersionBar.getActivity());
115 | if (mStatusBarHeight != statusBarHeight) {
116 | mImmersionBar.fitsWindows();
117 | mStatusBarHeight = statusBarHeight;
118 | }
119 | }
120 |
121 |
122 | /**
123 | * 横竖屏切换监听
124 | * Orientation change.
125 | *
126 | * @param configuration the configuration
127 | */
128 | private void barChanged(Configuration configuration) {
129 | if (mImmersionBar != null && mImmersionBar.initialized() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
130 | mOnBarListener = mImmersionBar.getBarParams().onBarListener;
131 | if (mOnBarListener != null) {
132 | final Activity activity = mImmersionBar.getActivity();
133 | if (mBarProperties == null) {
134 | mBarProperties = new BarProperties();
135 | }
136 | mBarProperties.setPortrait(configuration.orientation == Configuration.ORIENTATION_PORTRAIT);
137 | int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
138 | if (rotation == Surface.ROTATION_90) {
139 | mBarProperties.setLandscapeLeft(true);
140 | mBarProperties.setLandscapeRight(false);
141 | } else if (rotation == Surface.ROTATION_270) {
142 | mBarProperties.setLandscapeLeft(false);
143 | mBarProperties.setLandscapeRight(true);
144 | } else {
145 | mBarProperties.setLandscapeLeft(false);
146 | mBarProperties.setLandscapeRight(false);
147 | }
148 | activity.getWindow().getDecorView().post(this);
149 | }
150 | }
151 | }
152 |
153 | @Override
154 | public void run() {
155 | if (mImmersionBar != null && mImmersionBar.getActivity() != null) {
156 | Activity activity = mImmersionBar.getActivity();
157 | BarConfig barConfig = new BarConfig(activity);
158 | mBarProperties.setStatusBarHeight(barConfig.getStatusBarHeight());
159 | mBarProperties.setNavigationBar(barConfig.hasNavigationBar());
160 | mBarProperties.setNavigationBarHeight(barConfig.getNavigationBarHeight());
161 | mBarProperties.setNavigationBarWidth(barConfig.getNavigationBarWidth());
162 | mBarProperties.setActionBarHeight(barConfig.getActionBarHeight());
163 | boolean notchScreen = NotchUtils.hasNotchScreen(activity);
164 | mBarProperties.setNotchScreen(notchScreen);
165 | if (notchScreen && mNotchHeight == 0) {
166 | mNotchHeight = NotchUtils.getNotchHeight(activity);
167 | mBarProperties.setNotchHeight(mNotchHeight);
168 | }
169 | mOnBarListener.onBarChange(mBarProperties);
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/NavigationBarObserver.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Application;
4 | import android.database.ContentObserver;
5 | import android.net.Uri;
6 | import android.os.Build;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.provider.Settings;
10 |
11 | import java.util.ArrayList;
12 |
13 | import static com.maning.imagebrowserlibrary.utils.immersionbar.Constants.IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW;
14 | import static com.maning.imagebrowserlibrary.utils.immersionbar.Constants.IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW;
15 |
16 | /**
17 | * 导航栏显示隐藏处理,目前只支持emui和miui带有导航栏的手机
18 | *
19 | * @author geyifeng
20 | * @date 2019/4/10 6:02 PM
21 | */
22 | final class NavigationBarObserver extends ContentObserver {
23 |
24 | private ArrayList mListeners;
25 | private Application mApplication;
26 | private Boolean mIsRegister = false;
27 |
28 | static NavigationBarObserver getInstance() {
29 | return NavigationBarObserverInstance.INSTANCE;
30 | }
31 |
32 | private NavigationBarObserver() {
33 | super(new Handler(Looper.getMainLooper()));
34 | }
35 |
36 | void register(Application application) {
37 | this.mApplication = application;
38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mApplication != null
39 | && mApplication.getContentResolver() != null && !mIsRegister) {
40 | Uri uri = null;
41 | if (OSUtils.isMIUI()) {
42 | uri = Settings.Global.getUriFor(IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW);
43 | } else if (OSUtils.isEMUI()) {
44 | if (OSUtils.isEMUI3_x() || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
45 | uri = Settings.System.getUriFor(IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW);
46 | } else {
47 | uri = Settings.Global.getUriFor(IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW);
48 | }
49 | }
50 | if (uri != null) {
51 | mApplication.getContentResolver().registerContentObserver(uri, true, this);
52 | mIsRegister = true;
53 | }
54 | }
55 | }
56 |
57 | @Override
58 | public void onChange(boolean selfChange) {
59 | super.onChange(selfChange);
60 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mApplication != null && mApplication.getContentResolver() != null
61 | && mListeners != null && !mListeners.isEmpty()) {
62 | int show = 0;
63 | if (OSUtils.isMIUI()) {
64 | show = Settings.Global.getInt(mApplication.getContentResolver(), IMMERSION_MIUI_NAVIGATION_BAR_HIDE_SHOW, 0);
65 | } else if (OSUtils.isEMUI()) {
66 | if (OSUtils.isEMUI3_x() || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
67 | show = Settings.System.getInt(mApplication.getContentResolver(), IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW, 0);
68 | } else {
69 | show = Settings.Global.getInt(mApplication.getContentResolver(), IMMERSION_EMUI_NAVIGATION_BAR_HIDE_SHOW, 0);
70 | }
71 | }
72 | for (OnNavigationBarListener onNavigationBarListener : mListeners) {
73 | onNavigationBarListener.onNavigationBarChange(show != 1);
74 | }
75 | }
76 | }
77 |
78 | void addOnNavigationBarListener(OnNavigationBarListener listener) {
79 | if (listener == null) {
80 | return;
81 | }
82 | if (mListeners == null) {
83 | mListeners = new ArrayList<>();
84 | }
85 | if (!mListeners.contains(listener)) {
86 | mListeners.add(listener);
87 | }
88 | }
89 |
90 | void removeOnNavigationBarListener(OnNavigationBarListener listener) {
91 | if (listener == null || mListeners == null) {
92 | return;
93 | }
94 | mListeners.remove(listener);
95 | }
96 |
97 | private static class NavigationBarObserverInstance {
98 | private static final NavigationBarObserver INSTANCE = new NavigationBarObserver();
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/OSUtils.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.text.TextUtils;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * 手机系统判断
10 | *
11 | * @author geyifeng
12 | * @date 2017/4/18
13 | */
14 | public class OSUtils {
15 |
16 | private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
17 | private static final String KEY_EMUI_VERSION_NAME = "ro.build.version.emui";
18 | private static final String KEY_DISPLAY = "ro.build.display.id";
19 |
20 | /**
21 | * 判断是否为miui
22 | * Is miui boolean.
23 | *
24 | * @return the boolean
25 | */
26 | public static boolean isMIUI() {
27 | String property = getSystemProperty(KEY_MIUI_VERSION_NAME, "");
28 | return !TextUtils.isEmpty(property);
29 | }
30 |
31 | /**
32 | * 判断miui版本是否大于等于6
33 | * Is miui 6 later boolean.
34 | *
35 | * @return the boolean
36 | */
37 | public static boolean isMIUI6Later() {
38 | String version = getMIUIVersion();
39 | int num;
40 | if ((!version.isEmpty())) {
41 | try {
42 | num = Integer.valueOf(version.substring(1));
43 | return num >= 6;
44 | } catch (NumberFormatException e) {
45 | return false;
46 | }
47 | } else {
48 | return false;
49 | }
50 | }
51 |
52 | /**
53 | * 获得miui的版本
54 | * Gets miui version.
55 | *
56 | * @return the miui version
57 | */
58 | public static String getMIUIVersion() {
59 | return isMIUI() ? getSystemProperty(KEY_MIUI_VERSION_NAME, "") : "";
60 | }
61 |
62 | /**
63 | * 判断是否为emui
64 | * Is emui boolean.
65 | *
66 | * @return the boolean
67 | */
68 | public static boolean isEMUI() {
69 | String property = getSystemProperty(KEY_EMUI_VERSION_NAME, "");
70 | return !TextUtils.isEmpty(property);
71 | }
72 |
73 | /**
74 | * 得到emui的版本
75 | * Gets emui version.
76 | *
77 | * @return the emui version
78 | */
79 | public static String getEMUIVersion() {
80 | return isEMUI() ? getSystemProperty(KEY_EMUI_VERSION_NAME, "") : "";
81 | }
82 |
83 | /**
84 | * 判断是否为emui3.1版本
85 | * Is emui 3 1 boolean.
86 | *
87 | * @return the boolean
88 | */
89 | public static boolean isEMUI3_1() {
90 | String property = getEMUIVersion();
91 | if ("EmotionUI 3".equals(property) || property.contains("EmotionUI_3.1")) {
92 | return true;
93 | }
94 | return false;
95 | }
96 |
97 | /**
98 | * 判断是否为emui3.0版本
99 | * Is emui 3 1 boolean.
100 | *
101 | * @return the boolean
102 | */
103 | public static boolean isEMUI3_0() {
104 | String property = getEMUIVersion();
105 | if (property.contains("EmotionUI_3.0")) {
106 | return true;
107 | }
108 | return false;
109 | }
110 |
111 | /**
112 | * 判断是否为emui3.x版本
113 | * Is emui 3 x boolean.
114 | *
115 | * @return the boolean
116 | */
117 | public static boolean isEMUI3_x() {
118 | return OSUtils.isEMUI3_0() || OSUtils.isEMUI3_1();
119 | }
120 |
121 | /**
122 | * 判断是否为flymeOS
123 | * Is flyme os boolean.
124 | *
125 | * @return the boolean
126 | */
127 | public static boolean isFlymeOS() {
128 | return getFlymeOSFlag().toLowerCase().contains("flyme");
129 | }
130 |
131 | /**
132 | * 判断flymeOS的版本是否大于等于4
133 | * Is flyme os 4 later boolean.
134 | *
135 | * @return the boolean
136 | */
137 | public static boolean isFlymeOS4Later() {
138 | String version = getFlymeOSVersion();
139 | int num;
140 | if (!version.isEmpty()) {
141 | try {
142 | if (version.toLowerCase().contains("os")) {
143 | num = Integer.valueOf(version.substring(9, 10));
144 | } else {
145 | num = Integer.valueOf(version.substring(6, 7));
146 | }
147 | return num >= 4;
148 | } catch (NumberFormatException e) {
149 | return false;
150 | }
151 | }
152 | return false;
153 | }
154 |
155 | /**
156 | * 判断flymeOS的版本是否等于5
157 | * Is flyme os 5 boolean.
158 | *
159 | * @return the boolean
160 | */
161 | public static boolean isFlymeOS5() {
162 | String version = getFlymeOSVersion();
163 | int num;
164 | if (!version.isEmpty()) {
165 | try {
166 | if (version.toLowerCase().contains("os")) {
167 | num = Integer.valueOf(version.substring(9, 10));
168 | } else {
169 | num = Integer.valueOf(version.substring(6, 7));
170 | }
171 | return num == 5;
172 | } catch (NumberFormatException e) {
173 | return false;
174 | }
175 | }
176 | return false;
177 | }
178 |
179 |
180 | /**
181 | * 得到flymeOS的版本
182 | * Gets flyme os version.
183 | *
184 | * @return the flyme os version
185 | */
186 | public static String getFlymeOSVersion() {
187 | return isFlymeOS() ? getSystemProperty(KEY_DISPLAY, "") : "";
188 | }
189 |
190 | private static String getFlymeOSFlag() {
191 | return getSystemProperty(KEY_DISPLAY, "");
192 | }
193 |
194 | private static String getSystemProperty(String key, String defaultValue) {
195 | try {
196 | @SuppressLint("PrivateApi") Class> clz = Class.forName("android.os.SystemProperties");
197 | Method method = clz.getMethod("get", String.class, String.class);
198 | return (String) method.invoke(clz, key, defaultValue);
199 | } catch (Exception e) {
200 | e.printStackTrace();
201 | }
202 | return defaultValue;
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/OnBarListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * The interface On bar listener.
5 | *
6 | * @author geyifeng
7 | * @date 2019 -05-10 18:22
8 | */
9 | public interface OnBarListener {
10 |
11 | /**
12 | * On bar info change.
13 | *
14 | * @param barProperties the bar info
15 | */
16 | void onBarChange(BarProperties barProperties);
17 | }
18 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/OnKeyboardListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * 软键盘监听
5 | *
6 | * @author geyifeng
7 | * @date 2017/8/28
8 | */
9 | public interface OnKeyboardListener {
10 | /**
11 | * On keyboard change.
12 | *
13 | * @param isPopup the is popup 是否弹出
14 | * @param keyboardHeight the keyboard height 软键盘高度
15 | */
16 | void onKeyboardChange(boolean isPopup, int keyboardHeight);
17 | }
18 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/OnNavigationBarListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | /**
4 | * The interface On navigation bar listener.
5 | *
6 | * @author geyifeng
7 | * @date 2019 /4/10 6:12 PM
8 | */
9 | public interface OnNavigationBarListener {
10 | /**
11 | * On navigation bar change.
12 | *
13 | * @param show the show
14 | */
15 | void onNavigationBarChange(boolean show);
16 | }
17 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/RequestManagerFragment.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.app.Fragment;
6 | import android.content.res.Configuration;
7 | import android.os.Bundle;
8 |
9 | import androidx.annotation.Nullable;
10 |
11 | /**
12 | * @author geyifeng
13 | * @date 2019/4/11 6:43 PM
14 | */
15 | public final class RequestManagerFragment extends Fragment {
16 |
17 | private ImmersionDelegate mDelegate;
18 |
19 | public ImmersionBar get(Object o) {
20 | if (mDelegate == null) {
21 | mDelegate = new ImmersionDelegate(o);
22 | }
23 | return mDelegate.get();
24 | }
25 |
26 | public ImmersionBar get(Activity activity, Dialog dialog) {
27 | if (mDelegate == null) {
28 | mDelegate = new ImmersionDelegate(activity, dialog);
29 | }
30 | return mDelegate.get();
31 | }
32 |
33 | @Override
34 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
35 | super.onActivityCreated(savedInstanceState);
36 | if (mDelegate != null) {
37 | mDelegate.onActivityCreated(getResources().getConfiguration());
38 | }
39 | }
40 |
41 | @Override
42 | public void onResume() {
43 | super.onResume();
44 | if (mDelegate != null) {
45 | mDelegate.onResume();
46 | }
47 | }
48 |
49 | @Override
50 | public void onDestroy() {
51 | super.onDestroy();
52 | if (mDelegate != null) {
53 | mDelegate.onDestroy();
54 | mDelegate = null;
55 | }
56 | }
57 |
58 | @Override
59 | public void onConfigurationChanged(Configuration newConfig) {
60 | super.onConfigurationChanged(newConfig);
61 | if (mDelegate != null) {
62 | mDelegate.onConfigurationChanged(newConfig);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/RequestManagerRetriever.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.os.Build;
6 | import android.os.Handler;
7 | import android.os.Looper;
8 | import android.os.Message;
9 |
10 | import androidx.annotation.NonNull;
11 | import androidx.annotation.Nullable;
12 | import androidx.annotation.RequiresApi;
13 | import androidx.fragment.app.DialogFragment;
14 | import androidx.fragment.app.Fragment;
15 | import androidx.fragment.app.FragmentActivity;
16 | import androidx.fragment.app.FragmentManager;
17 |
18 | import java.util.HashMap;
19 | import java.util.Map;
20 |
21 | /**
22 | * @author geyifeng
23 | * @date 2019/4/12 4:21 PM
24 | */
25 | class RequestManagerRetriever implements Handler.Callback {
26 |
27 | private String mTag = ImmersionBar.class.getName();
28 |
29 | private Handler mHandler;
30 |
31 | private static final int ID_REMOVE_FRAGMENT_MANAGER = 1;
32 | private static final int ID_REMOVE_SUPPORT_FRAGMENT_MANAGER = 2;
33 |
34 | private static class Holder {
35 | private static final RequestManagerRetriever INSTANCE = new RequestManagerRetriever();
36 | }
37 |
38 | static RequestManagerRetriever getInstance() {
39 | return Holder.INSTANCE;
40 | }
41 |
42 | private RequestManagerRetriever() {
43 | mHandler = new Handler(Looper.getMainLooper(), this);
44 | }
45 |
46 | private final Map mPendingFragments = new HashMap<>();
47 | private final Map mPendingSupportFragments = new HashMap<>();
48 |
49 | public ImmersionBar get(Activity activity) {
50 | checkNotNull(activity, "activity is null");
51 | if (activity instanceof FragmentActivity) {
52 | return getSupportFragment(((FragmentActivity) activity).getSupportFragmentManager(), mTag + activity.toString()).get(activity);
53 | } else {
54 | return getFragment(activity.getFragmentManager(), mTag + activity.toString()).get(activity);
55 | }
56 | }
57 |
58 | public ImmersionBar get(Fragment fragment) {
59 | checkNotNull(fragment, "fragment is null");
60 | checkNotNull(fragment.getActivity(), "fragment.getActivity() is null");
61 | if (fragment instanceof DialogFragment) {
62 | checkNotNull(((DialogFragment) fragment).getDialog(), "fragment.getDialog() is null");
63 | }
64 | return getSupportFragment(fragment.getChildFragmentManager(), mTag + fragment.toString()).get(fragment);
65 | }
66 |
67 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
68 | public ImmersionBar get(android.app.Fragment fragment) {
69 | checkNotNull(fragment, "fragment is null");
70 | checkNotNull(fragment.getActivity(), "fragment.getActivity() is null");
71 | if (fragment instanceof android.app.DialogFragment) {
72 | checkNotNull(((android.app.DialogFragment) fragment).getDialog(), "fragment.getDialog() is null");
73 | }
74 | return getFragment(fragment.getChildFragmentManager(), mTag + fragment.toString()).get(fragment);
75 | }
76 |
77 | public ImmersionBar get(Activity activity, Dialog dialog) {
78 | checkNotNull(activity, "activity is null");
79 | checkNotNull(dialog, "dialog is null");
80 | if (activity instanceof FragmentActivity) {
81 | return getSupportFragment(((FragmentActivity) activity).getSupportFragmentManager(), mTag + dialog.toString()).get(activity, dialog);
82 | } else {
83 | return getFragment(activity.getFragmentManager(), mTag + dialog.toString()).get(activity, dialog);
84 | }
85 | }
86 |
87 | public void destroy(Activity activity, Dialog dialog) {
88 | if (activity == null || dialog == null) {
89 | return;
90 | }
91 | if (activity instanceof FragmentActivity) {
92 | SupportRequestManagerFragment fragment = getSupportFragment(((FragmentActivity) activity).getSupportFragmentManager(), mTag + dialog.toString(), true);
93 | if (fragment != null) {
94 | fragment.get(activity, dialog).destroy();
95 | }
96 | } else {
97 | RequestManagerFragment fragment = getFragment(activity.getFragmentManager(),mTag + dialog.toString(), true);
98 | if (fragment != null) {
99 | fragment.get(activity, dialog).destroy();
100 | }
101 | }
102 | }
103 |
104 | @Override
105 | public boolean handleMessage(Message msg) {
106 | boolean handled = true;
107 | switch (msg.what) {
108 | case ID_REMOVE_FRAGMENT_MANAGER:
109 | android.app.FragmentManager fm = (android.app.FragmentManager) msg.obj;
110 | mPendingFragments.remove(fm);
111 | break;
112 | case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
113 | FragmentManager supportFm = (FragmentManager) msg.obj;
114 | mPendingSupportFragments.remove(supportFm);
115 | break;
116 | default:
117 | handled = false;
118 | break;
119 | }
120 | return handled;
121 | }
122 |
123 | private RequestManagerFragment getFragment(android.app.FragmentManager fm, String tag) {
124 | return getFragment(fm, tag, false);
125 | }
126 |
127 | private RequestManagerFragment getFragment(android.app.FragmentManager fm, String tag, boolean destroy) {
128 | RequestManagerFragment fragment = (RequestManagerFragment) fm.findFragmentByTag(tag);
129 | if (fragment == null) {
130 | fragment = mPendingFragments.get(fm);
131 | if (fragment == null) {
132 | if (destroy) {
133 | return null;
134 | }
135 | fragment = new RequestManagerFragment();
136 | mPendingFragments.put(fm, fragment);
137 | fm.beginTransaction().add(fragment, tag).commitAllowingStateLoss();
138 | mHandler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
139 | }
140 | }
141 | if (destroy) {
142 | fm.beginTransaction().remove(fragment).commitAllowingStateLoss();
143 | return null;
144 | }
145 | return fragment;
146 | }
147 |
148 | private SupportRequestManagerFragment getSupportFragment(FragmentManager fm, String tag) {
149 | return getSupportFragment(fm, tag, false);
150 | }
151 |
152 | private SupportRequestManagerFragment getSupportFragment(FragmentManager fm, String tag, boolean destroy) {
153 | SupportRequestManagerFragment fragment = (SupportRequestManagerFragment) fm.findFragmentByTag(tag);
154 | if (fragment == null) {
155 | fragment = mPendingSupportFragments.get(fm);
156 | if (fragment == null) {
157 | if (destroy) {
158 | return null;
159 | }
160 | fragment = new SupportRequestManagerFragment();
161 | mPendingSupportFragments.put(fm, fragment);
162 | fm.beginTransaction().add(fragment, tag).commitAllowingStateLoss();
163 | mHandler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
164 | }
165 | }
166 | if (destroy) {
167 | fm.beginTransaction().remove(fragment).commitAllowingStateLoss();
168 | return null;
169 | }
170 | return fragment;
171 | }
172 |
173 | private static void checkNotNull(@Nullable T arg, @NonNull String message) {
174 | if (arg == null) {
175 | throw new NullPointerException(message);
176 | }
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/utils/immersionbar/SupportRequestManagerFragment.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.utils.immersionbar;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.res.Configuration;
6 | import android.os.Bundle;
7 |
8 | import androidx.annotation.Nullable;
9 | import androidx.fragment.app.Fragment;
10 |
11 | /**
12 | * @author geyifeng
13 | * @date 2019/4/11 6:43 PM
14 | */
15 | public final class SupportRequestManagerFragment extends Fragment {
16 |
17 | private ImmersionDelegate mDelegate;
18 |
19 | public ImmersionBar get(Object o) {
20 | if (mDelegate == null) {
21 | mDelegate = new ImmersionDelegate(o);
22 | }
23 | return mDelegate.get();
24 | }
25 |
26 | public ImmersionBar get(Activity activity, Dialog dialog) {
27 | if (mDelegate == null) {
28 | mDelegate = new ImmersionDelegate(activity, dialog);
29 | }
30 | return mDelegate.get();
31 | }
32 |
33 | @Override
34 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
35 | super.onActivityCreated(savedInstanceState);
36 | if (mDelegate != null) {
37 | mDelegate.onActivityCreated(getResources().getConfiguration());
38 | }
39 | }
40 |
41 | @Override
42 | public void onResume() {
43 | super.onResume();
44 | if (mDelegate != null) {
45 | mDelegate.onResume();
46 | }
47 | }
48 |
49 | @Override
50 | public void onDestroy() {
51 | super.onDestroy();
52 | if (mDelegate != null) {
53 | mDelegate.onDestroy();
54 | mDelegate = null;
55 | }
56 | }
57 |
58 | @Override
59 | public void onConfigurationChanged(Configuration newConfig) {
60 | super.onConfigurationChanged(newConfig);
61 | if (mDelegate != null) {
62 | mDelegate.onConfigurationChanged(newConfig);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/MNGestureView.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.util.AttributeSet;
6 | import android.util.DisplayMetrics;
7 | import android.util.Log;
8 | import android.view.MotionEvent;
9 | import android.view.ViewConfiguration;
10 | import android.view.WindowManager;
11 | import android.widget.LinearLayout;
12 | import android.widget.RelativeLayout;
13 |
14 | /**
15 | * 手势View
16 | */
17 | public class MNGestureView extends RelativeLayout {
18 |
19 | public MNGestureView(Context context) {
20 | this(context, null);
21 | }
22 |
23 | public MNGestureView(Context context, AttributeSet attrs) {
24 | this(context, attrs, 0);
25 | }
26 |
27 | public MNGestureView(Context context, AttributeSet attrs, int defStyleAttr) {
28 | super(context, attrs, defStyleAttr);
29 | }
30 |
31 | private static final int mHeight = 500;
32 | private float mDisplacementX;
33 | private float mDisplacementY;
34 | private float mInitialTy;
35 | private float mInitialTx;
36 | private boolean mTracking;
37 |
38 | @Override
39 | public boolean onTouchEvent(MotionEvent event) {
40 | return true;
41 | }
42 |
43 | @Override
44 | public boolean onInterceptTouchEvent(MotionEvent event) {
45 | switch (event.getActionMasked()) {
46 | case MotionEvent.ACTION_DOWN:
47 |
48 | mDisplacementX = event.getRawX();
49 | mDisplacementY = event.getRawY();
50 |
51 | mInitialTy = getTranslationY();
52 | mInitialTx = getTranslationX();
53 |
54 | break;
55 |
56 | case MotionEvent.ACTION_MOVE:
57 | // get the delta distance in X and Y direction
58 | float deltaX = event.getRawX() - mDisplacementX;
59 | float deltaY = event.getRawY() - mDisplacementY;
60 |
61 | //只有在不缩放的状态才能下滑
62 | if(onCanSwipeListener!= null){
63 | boolean canSwipe = onCanSwipeListener.canSwipe();
64 | if(!canSwipe){
65 | break;
66 | }
67 | }
68 |
69 | // set the touch and cancel event
70 | if (deltaY > 0 && (Math.abs(deltaY) > ViewConfiguration.get(getContext()).getScaledTouchSlop() * 2 && Math.abs(deltaX) < Math.abs(deltaY) / 2)
71 | || mTracking) {
72 |
73 | onSwipeListener.onSwiping(deltaY);
74 |
75 | setBackgroundColor(Color.TRANSPARENT);
76 |
77 | mTracking = true;
78 |
79 | setTranslationY(mInitialTy + deltaY);
80 | setTranslationX(mInitialTx + deltaX);
81 |
82 | float mScale = 1 - deltaY / mHeight;
83 | if (mScale < 0.3) {
84 | mScale = 0.3f;
85 | }
86 | setScaleX(mScale);
87 | setScaleY(mScale);
88 |
89 | }
90 | if (deltaY < 0) {
91 | setViewDefault();
92 | }
93 |
94 | break;
95 |
96 | case MotionEvent.ACTION_UP:
97 |
98 | if (mTracking) {
99 | mTracking = false;
100 | float currentTranslateY = getTranslationY();
101 |
102 | if (currentTranslateY > mHeight / 3) {
103 | onSwipeListener.downSwipe();
104 | break;
105 | }
106 |
107 | }
108 | setViewDefault();
109 |
110 | onSwipeListener.overSwipe();
111 | break;
112 | }
113 | return false;
114 | }
115 |
116 | private void setViewDefault(){
117 | //恢复默认
118 | setAlpha(1);
119 | setTranslationX(0);
120 | setTranslationY(0);
121 | setScaleX(1);
122 | setScaleY(1);
123 | }
124 |
125 |
126 | public interface OnSwipeListener {
127 | //向下滑动
128 | void downSwipe();
129 |
130 | //结束
131 | void overSwipe();
132 |
133 | //正在滑动
134 | void onSwiping(float y);
135 | }
136 |
137 |
138 | private OnSwipeListener onSwipeListener;
139 |
140 | public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
141 | this.onSwipeListener = onSwipeListener;
142 | }
143 |
144 | public interface OnCanSwipeListener{
145 | //可不可以下滑关闭
146 | boolean canSwipe();
147 | }
148 |
149 | private OnCanSwipeListener onCanSwipeListener;
150 |
151 | public void setOnGestureListener(OnCanSwipeListener onCanSwipeListener){
152 | this.onCanSwipeListener = onCanSwipeListener;
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/MNViewPager.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.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 | /**
10 | * Created by maning on 2017/11/13.
11 | * 解决多点触摸和ViewPager焦点冲突
12 | * 报出下面的错误:java.lang.IllegalArgumentException: pointerIndex out of range
13 | */
14 |
15 | public class MNViewPager extends ViewPager {
16 |
17 | public MNViewPager(Context context) {
18 | super(context);
19 | }
20 |
21 | public MNViewPager(Context context, AttributeSet attrs) {
22 | super(context, attrs);
23 | }
24 |
25 | @Override
26 | public boolean onTouchEvent(MotionEvent ev) {
27 | try {
28 | return super.onTouchEvent(ev);
29 | } catch (IllegalArgumentException ex) {
30 | ex.printStackTrace();
31 | }
32 | return false;
33 | }
34 |
35 | @Override
36 | public boolean onInterceptTouchEvent(MotionEvent ev) {
37 | try {
38 | return super.onInterceptTouchEvent(ev);
39 | } catch (IllegalArgumentException ex) {
40 | ex.printStackTrace();
41 | }
42 | return false;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/indicator/CircleIndicator.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.indicator;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.database.DataSetObserver;
6 | import android.os.Build;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 |
10 | import androidx.annotation.DrawableRes;
11 | import androidx.annotation.Nullable;
12 | import androidx.viewpager.widget.PagerAdapter;
13 | import androidx.viewpager.widget.ViewPager;
14 |
15 | /**
16 | * CircleIndicator work with ViewPager
17 | */
18 | public class CircleIndicator extends MBaseCircleIndicator {
19 |
20 | private ViewPager mViewpager;
21 |
22 | public CircleIndicator(Context context) {
23 | super(context);
24 | }
25 |
26 | public CircleIndicator(Context context, AttributeSet attrs) {
27 | super(context, attrs);
28 | }
29 |
30 | public CircleIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
31 | super(context, attrs, defStyleAttr);
32 | }
33 |
34 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
35 | public CircleIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
36 | super(context, attrs, defStyleAttr, defStyleRes);
37 | }
38 |
39 | public void setViewPager(@Nullable ViewPager viewPager) {
40 | mViewpager = viewPager;
41 | if (mViewpager != null && mViewpager.getAdapter() != null) {
42 | mLastPosition = -1;
43 | createIndicators();
44 | mViewpager.removeOnPageChangeListener(mInternalPageChangeListener);
45 | mViewpager.addOnPageChangeListener(mInternalPageChangeListener);
46 | mInternalPageChangeListener.onPageSelected(mViewpager.getCurrentItem());
47 | }
48 | }
49 |
50 | private void createIndicators() {
51 | PagerAdapter adapter = mViewpager.getAdapter();
52 | int count;
53 | if (adapter == null) {
54 | count = 0;
55 | } else {
56 | count = adapter.getCount();
57 | }
58 | createIndicators(count, mViewpager.getCurrentItem());
59 | }
60 |
61 | public void updateIndicatorBackgroundResId(@DrawableRes int mIndicatorBackgroundResId, @DrawableRes int mIndicatorUnselectedBackgroundResId) {
62 | this.mIndicatorBackgroundResId = mIndicatorBackgroundResId;
63 | this.mIndicatorUnselectedBackgroundResId = mIndicatorUnselectedBackgroundResId;
64 | }
65 |
66 | private final ViewPager.OnPageChangeListener mInternalPageChangeListener =
67 | new ViewPager.OnPageChangeListener() {
68 |
69 | @Override
70 | public void onPageScrolled(int position, float positionOffset,
71 | int positionOffsetPixels) {
72 | }
73 |
74 | @Override
75 | public void onPageSelected(int position) {
76 |
77 | if (mViewpager.getAdapter() == null
78 | || mViewpager.getAdapter().getCount() <= 0) {
79 | return;
80 | }
81 | animatePageSelected(position);
82 | }
83 |
84 | @Override
85 | public void onPageScrollStateChanged(int state) {
86 | }
87 | };
88 |
89 | public DataSetObserver getDataSetObserver() {
90 | return mInternalDataSetObserver;
91 | }
92 |
93 | private final DataSetObserver mInternalDataSetObserver = new DataSetObserver() {
94 | @Override
95 | public void onChanged() {
96 | super.onChanged();
97 | if (mViewpager == null) {
98 | return;
99 | }
100 | PagerAdapter adapter = mViewpager.getAdapter();
101 | int newCount = adapter != null ? adapter.getCount() : 0;
102 | int currentCount = getChildCount();
103 | if (newCount == currentCount) {
104 | // No change
105 | return;
106 | } else if (mLastPosition < newCount) {
107 | mLastPosition = mViewpager.getCurrentItem();
108 | } else {
109 | mLastPosition = -1;
110 | }
111 | createIndicators();
112 | }
113 | };
114 |
115 | /**
116 | * @deprecated User ViewPager addOnPageChangeListener
117 | */
118 | @Deprecated
119 | public void setOnPageChangeListener(
120 | ViewPager.OnPageChangeListener onPageChangeListener) {
121 | if (mViewpager == null) {
122 | throw new NullPointerException("can not find Viewpager , setViewPager first");
123 | }
124 | mViewpager.removeOnPageChangeListener(onPageChangeListener);
125 | mViewpager.addOnPageChangeListener(onPageChangeListener);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/indicator/Config.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.indicator;
2 |
3 | import android.view.Gravity;
4 | import android.widget.LinearLayout;
5 |
6 | import androidx.annotation.AnimatorRes;
7 | import androidx.annotation.DrawableRes;
8 |
9 | import com.maning.imagebrowserlibrary.R;
10 |
11 | public class Config {
12 |
13 | int width = -1;
14 | int height = -1;
15 | int margin = -1;
16 | @AnimatorRes
17 | int animatorResId = R.animator.mn_browser_indicator_scale;
18 | @AnimatorRes
19 | int animatorReverseResId = 0;
20 | @DrawableRes
21 | int backgroundResId = R.drawable.mn_browser_indicator_bg_selected;
22 | @DrawableRes
23 | int unselectedBackgroundId = R.drawable.mn_browser_indicator_bg_unselected;
24 | int orientation = LinearLayout.HORIZONTAL;
25 | int gravity = Gravity.CENTER;
26 |
27 | Config() {
28 | }
29 |
30 | public static class Builder {
31 |
32 | private final Config mConfig;
33 |
34 | public Builder() {
35 | mConfig = new Config();
36 | }
37 |
38 | public Builder width(int width) {
39 | mConfig.width = width;
40 | return this;
41 | }
42 |
43 | public Builder height(int height) {
44 | mConfig.height = height;
45 | return this;
46 | }
47 |
48 | public Builder margin(int margin) {
49 | mConfig.margin = margin;
50 | return this;
51 | }
52 |
53 | public Builder animator(@AnimatorRes int animatorResId) {
54 | mConfig.animatorResId = animatorResId;
55 | return this;
56 | }
57 |
58 | public Builder animatorReverse(@AnimatorRes int animatorReverseResId) {
59 | mConfig.animatorReverseResId = animatorReverseResId;
60 | return this;
61 | }
62 |
63 | public Builder drawable(@DrawableRes int backgroundResId) {
64 | mConfig.backgroundResId = backgroundResId;
65 | return this;
66 | }
67 |
68 | public Builder drawableUnselected(@DrawableRes int unselectedBackgroundId) {
69 | mConfig.unselectedBackgroundId = unselectedBackgroundId;
70 | return this;
71 | }
72 |
73 | public Builder orientation(int orientation) {
74 | mConfig.orientation = orientation;
75 | return this;
76 | }
77 |
78 | public Builder gravity(int gravity) {
79 | mConfig.gravity = gravity;
80 | return this;
81 | }
82 |
83 | public Config build() {
84 | return mConfig;
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/Compat.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.maning.imagebrowserlibrary.view.photoview;
17 |
18 | import android.annotation.TargetApi;
19 | import android.os.Build.VERSION;
20 | import android.os.Build.VERSION_CODES;
21 | import android.view.View;
22 |
23 | class Compat {
24 |
25 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60;
26 |
27 | public static void postOnAnimation(View view, Runnable runnable) {
28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
29 | postOnAnimationJellyBean(view, runnable);
30 | } else {
31 | view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
32 | }
33 | }
34 |
35 | @TargetApi(16)
36 | private static void postOnAnimationJellyBean(View view, Runnable runnable) {
37 | view.postOnAnimation(runnable);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/CustomGestureDetector.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.maning.imagebrowserlibrary.view.photoview;
17 |
18 | import android.content.Context;
19 | import android.view.MotionEvent;
20 | import android.view.ScaleGestureDetector;
21 | import android.view.VelocityTracker;
22 | import android.view.ViewConfiguration;
23 |
24 | /**
25 | * Does a whole lot of gesture detecting.
26 | */
27 | class CustomGestureDetector {
28 |
29 | private static final int INVALID_POINTER_ID = -1;
30 |
31 | private int mActivePointerId = INVALID_POINTER_ID;
32 | private int mActivePointerIndex = 0;
33 | private final ScaleGestureDetector mDetector;
34 |
35 | private VelocityTracker mVelocityTracker;
36 | private boolean mIsDragging;
37 | private float mLastTouchX;
38 | private float mLastTouchY;
39 | private final float mTouchSlop;
40 | private final float mMinimumVelocity;
41 | private OnGestureListener mListener;
42 |
43 | CustomGestureDetector(Context context, OnGestureListener listener) {
44 | final ViewConfiguration configuration = ViewConfiguration
45 | .get(context);
46 | mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
47 | mTouchSlop = configuration.getScaledTouchSlop();
48 |
49 | mListener = listener;
50 | ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() {
51 |
52 | @Override
53 | public boolean onScale(ScaleGestureDetector detector) {
54 | float scaleFactor = detector.getScaleFactor();
55 |
56 | if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor)) {
57 | return false;
58 | }
59 |
60 | mListener.onScale(scaleFactor,
61 | detector.getFocusX(), detector.getFocusY());
62 | return true;
63 | }
64 |
65 | @Override
66 | public boolean onScaleBegin(ScaleGestureDetector detector) {
67 | return true;
68 | }
69 |
70 | @Override
71 | public void onScaleEnd(ScaleGestureDetector detector) {
72 | // NO-OP
73 | }
74 | };
75 | mDetector = new ScaleGestureDetector(context, mScaleListener);
76 | }
77 |
78 | private float getActiveX(MotionEvent ev) {
79 | try {
80 | return ev.getX(mActivePointerIndex);
81 | } catch (Exception e) {
82 | return ev.getX();
83 | }
84 | }
85 |
86 | private float getActiveY(MotionEvent ev) {
87 | try {
88 | return ev.getY(mActivePointerIndex);
89 | } catch (Exception e) {
90 | return ev.getY();
91 | }
92 | }
93 |
94 | public boolean isScaling() {
95 | return mDetector.isInProgress();
96 | }
97 |
98 | public boolean isDragging() {
99 | return mIsDragging;
100 | }
101 |
102 | public boolean onTouchEvent(MotionEvent ev) {
103 | try {
104 | mDetector.onTouchEvent(ev);
105 | return processTouchEvent(ev);
106 | } catch (IllegalArgumentException e) {
107 | // Fix for support lib bug, happening when onDestroy is called
108 | return true;
109 | }
110 | }
111 |
112 | private boolean processTouchEvent(MotionEvent ev) {
113 | final int action = ev.getAction();
114 | switch (action & MotionEvent.ACTION_MASK) {
115 | case MotionEvent.ACTION_DOWN:
116 | mActivePointerId = ev.getPointerId(0);
117 |
118 | mVelocityTracker = VelocityTracker.obtain();
119 | if (null != mVelocityTracker) {
120 | mVelocityTracker.addMovement(ev);
121 | }
122 |
123 | mLastTouchX = getActiveX(ev);
124 | mLastTouchY = getActiveY(ev);
125 | mIsDragging = false;
126 | break;
127 | case MotionEvent.ACTION_MOVE:
128 | final float x = getActiveX(ev);
129 | final float y = getActiveY(ev);
130 | final float dx = x - mLastTouchX, dy = y - mLastTouchY;
131 |
132 | if (!mIsDragging) {
133 | // Use Pythagoras to see if drag length is larger than
134 | // touch slop
135 | mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
136 | }
137 |
138 | if (mIsDragging) {
139 | mListener.onDrag(dx, dy);
140 | mLastTouchX = x;
141 | mLastTouchY = y;
142 |
143 | if (null != mVelocityTracker) {
144 | mVelocityTracker.addMovement(ev);
145 | }
146 | }
147 | break;
148 | case MotionEvent.ACTION_CANCEL:
149 | mActivePointerId = INVALID_POINTER_ID;
150 | // Recycle Velocity Tracker
151 | if (null != mVelocityTracker) {
152 | mVelocityTracker.recycle();
153 | mVelocityTracker = null;
154 | }
155 | break;
156 | case MotionEvent.ACTION_UP:
157 | mActivePointerId = INVALID_POINTER_ID;
158 | if (mIsDragging) {
159 | if (null != mVelocityTracker) {
160 | mLastTouchX = getActiveX(ev);
161 | mLastTouchY = getActiveY(ev);
162 |
163 | // Compute velocity within the last 1000ms
164 | mVelocityTracker.addMovement(ev);
165 | mVelocityTracker.computeCurrentVelocity(1000);
166 |
167 | final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
168 | .getYVelocity();
169 |
170 | // If the velocity is greater than minVelocity, call
171 | // listener
172 | if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
173 | mListener.onFling(mLastTouchX, mLastTouchY, -vX,
174 | -vY);
175 | }
176 | }
177 | }
178 |
179 | // Recycle Velocity Tracker
180 | if (null != mVelocityTracker) {
181 | mVelocityTracker.recycle();
182 | mVelocityTracker = null;
183 | }
184 | break;
185 | case MotionEvent.ACTION_POINTER_UP:
186 | final int pointerIndex = Util.getPointerIndex(ev.getAction());
187 | final int pointerId = ev.getPointerId(pointerIndex);
188 | if (pointerId == mActivePointerId) {
189 | // This was our active pointer going up. Choose a new
190 | // active pointer and adjust accordingly.
191 | final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
192 | mActivePointerId = ev.getPointerId(newPointerIndex);
193 | mLastTouchX = ev.getX(newPointerIndex);
194 | mLastTouchY = ev.getY(newPointerIndex);
195 | }
196 | break;
197 | }
198 |
199 | mActivePointerIndex = ev
200 | .findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
201 | : 0);
202 | return true;
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnGestureListener.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.maning.imagebrowserlibrary.view.photoview;
17 |
18 | interface OnGestureListener {
19 |
20 | void onDrag(float dx, float dy);
21 |
22 | void onFling(float startX, float startY, float velocityX,
23 | float velocityY);
24 |
25 | void onScale(float scaleFactor, float focusX, float focusY);
26 |
27 | }
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnMatrixChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for
7 | * this View.
8 | */
9 | public interface OnMatrixChangedListener {
10 |
11 | /**
12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because
13 | * the View's bounds have changed, or the user has zoomed.
14 | *
15 | * @param rect - Rectangle displaying the Drawable's new bounds.
16 | */
17 | void onMatrixChanged(RectF rect);
18 | }
19 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnOutsidePhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Callback when the user tapped outside of the photo
7 | */
8 | public interface OnOutsidePhotoTapListener {
9 |
10 | /**
11 | * The outside of the photo has been tapped
12 | */
13 | void onOutsidePhotoTap(ImageView imageView);
14 | }
15 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnPhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * A callback to be invoked when the Photo is tapped with a single
7 | * tap.
8 | */
9 | public interface OnPhotoTapListener {
10 |
11 | /**
12 | * A callback to receive where the user taps on a photo. You will only receive a callback if
13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored.
14 | *
15 | * @param view ImageView the user tapped.
16 | * @param x where the user tapped from the of the Drawable, as percentage of the
17 | * Drawable width.
18 | * @param y where the user tapped from the top of the Drawable, as percentage of the
19 | * Drawable height.
20 | */
21 | void onPhotoTap(ImageView view, float x, float y);
22 | }
23 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnScaleChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 |
4 | /**
5 | * Interface definition for callback to be invoked when attached ImageView scale changes
6 | */
7 | public interface OnScaleChangedListener {
8 |
9 | /**
10 | * Callback for when the scale changes
11 | *
12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in)
13 | * @param focusX focal point X position
14 | * @param focusY focal point Y position
15 | */
16 | void onScaleChange(float scaleFactor, float focusX, float focusY);
17 | }
18 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnSingleFlingListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | import android.view.MotionEvent;
4 |
5 | /**
6 | * A callback to be invoked when the ImageView is flung with a single
7 | * touch
8 | */
9 | public interface OnSingleFlingListener {
10 |
11 | /**
12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if
13 | * the user flings anywhere on the view.
14 | *
15 | * @param e1 MotionEvent the user first touch.
16 | * @param e2 MotionEvent the user last touch.
17 | * @param velocityX distance of user's horizontal fling.
18 | * @param velocityY distance of user's vertical fling.
19 | */
20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
21 | }
22 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnViewDragListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | /**
4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event
5 | */
6 | public interface OnViewDragListener {
7 |
8 | /**
9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the
10 | * user is scaling.
11 | *
12 | * @param dx The change of the coordinates in the x-direction
13 | * @param dy The change of the coordinates in the y-direction
14 | */
15 | void onDrag(float dx, float dy);
16 | }
17 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/OnViewTapListener.java:
--------------------------------------------------------------------------------
1 | package com.maning.imagebrowserlibrary.view.photoview;
2 |
3 | import android.view.View;
4 |
5 | public interface OnViewTapListener {
6 |
7 | /**
8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if
9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored.
10 | *
11 | * @param view - View the user tapped.
12 | * @param x - where the user tapped from the left of the View.
13 | * @param y - where the user tapped from the top of the View.
14 | */
15 | void onViewTap(View view, float x, float y);
16 | }
17 |
--------------------------------------------------------------------------------
/imagebrowserlibrary/src/main/java/com/maning/imagebrowserlibrary/view/photoview/PhotoView.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *