summaryrefslogtreecommitdiff
path: root/org.fox.ttcomics
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2019-02-03 23:53:57 +0300
committerAndrew Dolgov <[email protected]>2019-02-03 23:53:57 +0300
commit12f64363c82274587ebb07774de1a872f54ca3ae (patch)
tree1ceefcf0d1da0e4e06310cdfc4af8d9e00b55b34 /org.fox.ttcomics
parent31616c82eb5a5548127ddd965a39c6d5dbeb3f69 (diff)
android support libraries -> androidx
use photoview instead of imageviewtouch (included because of TOP_CROP missing) remove obsolete/unused code
Diffstat (limited to 'org.fox.ttcomics')
-rwxr-xr-xorg.fox.ttcomics/build.gradle11
-rwxr-xr-xorg.fox.ttcomics/org.fox.ttcomics.iml87
-rwxr-xr-xorg.fox.ttcomics/src/main/AndroidManifest.xml6
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Compat.java39
-rwxr-xr-xorg.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/CustomGestureDetector.java205
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnGestureListener.java27
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnMatrixChangedListener.java18
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnOutsidePhotoTapListener.java14
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnPhotoTapListener.java22
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnScaleChangedListener.java17
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnSingleFlingListener.java21
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewDragListener.java16
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewTapListener.java16
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoView.java256
-rwxr-xr-xorg.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoViewAttacher.java822
-rw-r--r--org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Util.java37
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouch.java268
-rwxr-xr-xorg.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java512
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Cubic.java20
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Easing.java10
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/FastBitmapDrawable.java84
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/IBitmapDrawable.java14
-rw-r--r--org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/utils/IDisposable.java6
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/Application.java4
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicFragment.java180
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java6
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java25
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java7
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java14
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/PreferencesActivity.java3
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/StateSavedFragment.java3
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java6
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CacheCleanupService.java3
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CompatListActivity.java33
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/IVTViewPager.java39
-rwxr-xr-xorg.fox.ttcomics/src/main/res/layout/activity_main.xml6
-rwxr-xr-xorg.fox.ttcomics/src/main/res/layout/comics_grid_row.xml4
-rwxr-xr-x[-rw-r--r--]org.fox.ttcomics/src/main/res/layout/fragment_comic.xml3
-rwxr-xr-x[-rw-r--r--]org.fox.ttcomics/src/main/res/layout/fragment_comics_grid.xml4
-rwxr-xr-xorg.fox.ttcomics/src/main/res/layout/fragment_comics_pager.xml2
-rwxr-xr-x[-rw-r--r--]org.fox.ttcomics/src/main/res/layout/toolbar.xml2
41 files changed, 1647 insertions, 1225 deletions
diff --git a/org.fox.ttcomics/build.gradle b/org.fox.ttcomics/build.gradle
index 8d2814a..9e52a1c 100755
--- a/org.fox.ttcomics/build.gradle
+++ b/org.fox.ttcomics/build.gradle
@@ -47,10 +47,9 @@ android {
}
dependencies {
- implementation 'com.android.support:support-v4:28.0.0'
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support:cardview-v7:28.0.0'
- implementation 'com.android.support:design:28.0.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
+ implementation 'com.google.android.material:material:1.1.0-alpha03'
implementation 'com.shamanland:fab:0.0.8'
implementation 'jp.co.recruit_mp:android-HeaderFooterGridView:0.2.4'
implementation 'com.github.bumptech.glide:glide:3.8.0'
@@ -61,8 +60,8 @@ dependencies {
compileOnly 'frankiesardo:icepick-processor:3.2.0'
implementation 'com.github.livefront:bridge:v1.1.2'
annotationProcessor 'frankiesardo:icepick-processor:3.2.0'
- implementation 'com.google.android.gms:play-services-base:15.0.1'
- implementation 'com.google.android.gms:play-services-auth:15.0.1'
+ implementation 'com.google.android.gms:play-services-base:16.1.0'
+ implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation files('libs/nineoldandroids-2.4.0.jar')
implementation 'com.gu:option:1.3'
implementation 'net.rdrei.android.dirchooser:library:3.2@aar'
diff --git a/org.fox.ttcomics/org.fox.ttcomics.iml b/org.fox.ttcomics/org.fox.ttcomics.iml
index 394c135..4d82cb9 100755
--- a/org.fox.ttcomics/org.fox.ttcomics.iml
+++ b/org.fox.ttcomics/org.fox.ttcomics.iml
@@ -125,69 +125,72 @@
</content>
<orderEntry type="jdk" jdkName="Android API 28 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="Gradle: com.android.support:design:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: stencil:stencil:0.3.5@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-fragment:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:localbroadcastmanager:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: org.clojure:data.priority-map:0.0.2@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:animated-vector-drawable:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.lifecycle:viewmodel:1.1.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:loader:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.core:runtime:1.1.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.lifecycle:livedata-core:1.1.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.drawerlayout:drawerlayout:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.documentfile:documentfile:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.localbroadcastmanager:localbroadcastmanager:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.cardview:cardview:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-runtime:2.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-livedata-core:2.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-base:16.1.0@aar" level="project" />
<orderEntry type="library" name="Gradle: net.rdrei.android.dirchooser:library:3.2@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:cursoradapter:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.core:core:1.1.0-alpha03@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.customview:customview:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: __local_aars__:C.\Users\fox\Projects\tt-comics\org.fox.ttcomics\libs\nineoldandroids-2.4.0.jar:unspecified@jar" level="project" />
<orderEntry type="library" name="Gradle: com.ToxicBakery.viewpager.transforms:view-pager-transforms:1.2.32@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.lifecycle:runtime:1.1.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-compat:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.asynclayoutinflater:asynclayoutinflater:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.gu:option:1.3@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:cardview-v7:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.interpolator:interpolator:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: quoin:quoin:0.1.2@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-base:15.0.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.slidingpanelayout:slidingpanelayout:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.media:media:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-basement:16.2.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth-api-phone:16.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: jp.co.recruit_mp:android-HeaderFooterGridView:0.2.4@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-vector-drawable:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-core-utils:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:recyclerview-v7:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-tasks:15.0.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-annotations:28.0.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:interpolator:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:transition:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.lifecycle:livedata:1.1.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth:16.0.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.appcompat:appcompat:1.1.0-alpha01@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.legacy:legacy-support-v4:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.arch.core:core-runtime:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: org.clojure:clojure:1.7.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:drawerlayout:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-v4:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.guava:listenablefuture:1.0@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.concurrent:concurrent-futures:1.0.0-alpha02@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.fragment:fragment:1.1.0-alpha02@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.swiperefreshlayout:swiperefreshlayout:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.google.guava:guava:18.0@jar" level="project" />
<orderEntry type="library" name="Gradle: com.google.auto.service:auto-service:1.0-rc2@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:documentfile:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth-base:16.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.viewpager:viewpager:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.legacy:legacy-support-core-ui:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.loader:loader:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: frankiesardo:icepick:3.2.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:slidingpanelayout:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: scout:scout:0.1.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:appcompat-v7:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.github.livefront:bridge:v1.1.2@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.activity:activity:1.0.0-alpha02@aar" level="project" />
<orderEntry type="library" name="Gradle: ch.acra:acra:4.9.1@aar" level="project" />
<orderEntry type="library" name="Gradle: com.github.bumptech.glide:glide:3.8.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:collections:28.0.0@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-livedata:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: frankiesardo:icepick-processor:3.2.0@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-basement:15.0.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.versionedparcelable:versionedparcelable:1.1.0-alpha01@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.material:material:1.1.0-alpha03@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.collection:collection:1.1.0-alpha01@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.vectordrawable:vectordrawable:1.1.0-alpha01@aar" level="project" />
<orderEntry type="library" name="Gradle: com.google.auto:auto-common:0.3@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-core-ui:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:asynclayoutinflater:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:print:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.vectordrawable:vectordrawable-animated:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.annotation:annotation:1.0.1@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-common:2.0.0@jar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.legacy:legacy-support-core-utils:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.print:print:1.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-viewmodel:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: org.clojure:core.cache:0.6.3@jar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.core:common:1.1.1@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:versionedparcelable:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.arch.core:core-common:2.0.0@jar" level="project" />
<orderEntry type="library" name="Gradle: com.shamanland:fab:0.0.8@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth:15.0.1@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.transition:transition:1.0.1@aar" level="project" />
<orderEntry type="library" name="Gradle: slingshot:slingshot:0.10.3@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:viewpager:28.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.nhaarman.listviewanimations:lib-core:3.1.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth-api-phone:15.0.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: android.arch.lifecycle:common:1.1.1@jar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:coordinatorlayout:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:customview:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:swiperefreshlayout:28.0.0@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-auth-base:15.0.1@aar" level="project" />
- <orderEntry type="library" name="Gradle: com.android.support:support-media-compat:28.0.0@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.recyclerview:recyclerview:1.1.0-alpha01@aar" level="project" />
+ <orderEntry type="library" name="Gradle: androidx.coordinatorlayout:coordinatorlayout:1.1.0-alpha01@aar" level="project" />
+ <orderEntry type="library" name="Gradle: com.google.android.gms:play-services-tasks:16.0.1@aar" level="project" />
</component>
</module> \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/AndroidManifest.xml b/org.fox.ttcomics/src/main/AndroidManifest.xml
index 4342ef8..2ee0e0f 100755
--- a/org.fox.ttcomics/src/main/AndroidManifest.xml
+++ b/org.fox.ttcomics/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.fox.ttcomics2"
- android:versionCode="88"
- android:versionName="1.46" >
+ android:versionCode="89"
+ android:versionName="1.47" >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
@@ -70,7 +70,7 @@
android:exported="false"/>
<provider
- android:name="android.support.v4.content.FileProvider"
+ android:name="androidx.core.content.FileProvider"
android:authorities="org.fox.ttcomics2.files"
android:exported="false"
android:grantUriPermissions="true" >
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Compat.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Compat.java
new file mode 100644
index 0000000..d33c31c
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Compat.java
@@ -0,0 +1,39 @@
+/*
+ Copyright 2011, 2012 Chris Banes.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.github.chrisbanes.photoview;
+
+import android.annotation.TargetApi;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.view.View;
+
+class Compat {
+
+ private static final int SIXTY_FPS_INTERVAL = 1000 / 60;
+
+ public static void postOnAnimation(View view, Runnable runnable) {
+ if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
+ postOnAnimationJellyBean(view, runnable);
+ } else {
+ view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
+ }
+ }
+
+ @TargetApi(16)
+ private static void postOnAnimationJellyBean(View view, Runnable runnable) {
+ view.postOnAnimation(runnable);
+ }
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/CustomGestureDetector.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/CustomGestureDetector.java
new file mode 100755
index 0000000..822754f
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/CustomGestureDetector.java
@@ -0,0 +1,205 @@
+/*
+ Copyright 2011, 2012 Chris Banes.
+ <p/>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ <p/>
+ http://www.apache.org/licenses/LICENSE-2.0
+ <p/>
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.github.chrisbanes.photoview;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+/**
+ * Does a whole lot of gesture detecting.
+ */
+class CustomGestureDetector {
+
+ private static final int INVALID_POINTER_ID = -1;
+
+ private int mActivePointerId = INVALID_POINTER_ID;
+ private int mActivePointerIndex = 0;
+ private final ScaleGestureDetector mDetector;
+
+ private VelocityTracker mVelocityTracker;
+ private boolean mIsDragging;
+ private float mLastTouchX;
+ private float mLastTouchY;
+ private final float mTouchSlop;
+ private final float mMinimumVelocity;
+ private OnGestureListener mListener;
+
+ CustomGestureDetector(Context context, OnGestureListener listener) {
+ final ViewConfiguration configuration = ViewConfiguration
+ .get(context);
+ mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+ mTouchSlop = configuration.getScaledTouchSlop();
+
+ mListener = listener;
+ ScaleGestureDetector.OnScaleGestureListener mScaleListener = new ScaleGestureDetector.OnScaleGestureListener() {
+
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ float scaleFactor = detector.getScaleFactor();
+
+ if (Float.isNaN(scaleFactor) || Float.isInfinite(scaleFactor))
+ return false;
+
+ if (scaleFactor >= 0) {
+ mListener.onScale(scaleFactor,
+ detector.getFocusX(), detector.getFocusY());
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ return true;
+ }
+
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ // NO-OP
+ }
+ };
+ mDetector = new ScaleGestureDetector(context, mScaleListener);
+ }
+
+ private float getActiveX(MotionEvent ev) {
+ try {
+ return ev.getX(mActivePointerIndex);
+ } catch (Exception e) {
+ return ev.getX();
+ }
+ }
+
+ private float getActiveY(MotionEvent ev) {
+ try {
+ return ev.getY(mActivePointerIndex);
+ } catch (Exception e) {
+ return ev.getY();
+ }
+ }
+
+ public boolean isScaling() {
+ return mDetector.isInProgress();
+ }
+
+ public boolean isDragging() {
+ return mIsDragging;
+ }
+
+ public boolean onTouchEvent(MotionEvent ev) {
+ try {
+ mDetector.onTouchEvent(ev);
+ return processTouchEvent(ev);
+ } catch (IllegalArgumentException e) {
+ // Fix for support lib bug, happening when onDestroy is called
+ return true;
+ }
+ }
+
+ private boolean processTouchEvent(MotionEvent ev) {
+ final int action = ev.getAction();
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ mActivePointerId = ev.getPointerId(0);
+
+ mVelocityTracker = VelocityTracker.obtain();
+ if (null != mVelocityTracker) {
+ mVelocityTracker.addMovement(ev);
+ }
+
+ mLastTouchX = getActiveX(ev);
+ mLastTouchY = getActiveY(ev);
+ mIsDragging = false;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ final float x = getActiveX(ev);
+ final float y = getActiveY(ev);
+ final float dx = x - mLastTouchX, dy = y - mLastTouchY;
+
+ if (!mIsDragging) {
+ // Use Pythagoras to see if drag length is larger than
+ // touch slop
+ mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
+ }
+
+ if (mIsDragging) {
+ mListener.onDrag(dx, dy);
+ mLastTouchX = x;
+ mLastTouchY = y;
+
+ if (null != mVelocityTracker) {
+ mVelocityTracker.addMovement(ev);
+ }
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ mActivePointerId = INVALID_POINTER_ID;
+ // Recycle Velocity Tracker
+ if (null != mVelocityTracker) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ mActivePointerId = INVALID_POINTER_ID;
+ if (mIsDragging) {
+ if (null != mVelocityTracker) {
+ mLastTouchX = getActiveX(ev);
+ mLastTouchY = getActiveY(ev);
+
+ // Compute velocity within the last 1000ms
+ mVelocityTracker.addMovement(ev);
+ mVelocityTracker.computeCurrentVelocity(1000);
+
+ final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
+ .getYVelocity();
+
+ // If the velocity is greater than minVelocity, call
+ // listener
+ if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
+ mListener.onFling(mLastTouchX, mLastTouchY, -vX,
+ -vY);
+ }
+ }
+ }
+
+ // Recycle Velocity Tracker
+ if (null != mVelocityTracker) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ final int pointerIndex = Util.getPointerIndex(ev.getAction());
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ mLastTouchX = ev.getX(newPointerIndex);
+ mLastTouchY = ev.getY(newPointerIndex);
+ }
+ break;
+ }
+
+ mActivePointerIndex = ev
+ .findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
+ : 0);
+ return true;
+ }
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnGestureListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnGestureListener.java
new file mode 100644
index 0000000..f7722af
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnGestureListener.java
@@ -0,0 +1,27 @@
+/*
+ Copyright 2011, 2012 Chris Banes.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.github.chrisbanes.photoview;
+
+interface OnGestureListener {
+
+ void onDrag(float dx, float dy);
+
+ void onFling(float startX, float startY, float velocityX,
+ float velocityY);
+
+ void onScale(float scaleFactor, float focusX, float focusY);
+
+} \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnMatrixChangedListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnMatrixChangedListener.java
new file mode 100644
index 0000000..f3031d6
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnMatrixChangedListener.java
@@ -0,0 +1,18 @@
+package com.github.chrisbanes.photoview;
+
+import android.graphics.RectF;
+
+/**
+ * Interface definition for a callback to be invoked when the internal Matrix has changed for
+ * this View.
+ */
+public interface OnMatrixChangedListener {
+
+ /**
+ * Callback for when the Matrix displaying the Drawable has changed. This could be because
+ * the View's bounds have changed, or the user has zoomed.
+ *
+ * @param rect - Rectangle displaying the Drawable's new bounds.
+ */
+ void onMatrixChanged(RectF rect);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnOutsidePhotoTapListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnOutsidePhotoTapListener.java
new file mode 100644
index 0000000..99fc7b4
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnOutsidePhotoTapListener.java
@@ -0,0 +1,14 @@
+package com.github.chrisbanes.photoview;
+
+import android.widget.ImageView;
+
+/**
+ * Callback when the user tapped outside of the photo
+ */
+public interface OnOutsidePhotoTapListener {
+
+ /**
+ * The outside of the photo has been tapped
+ */
+ void onOutsidePhotoTap(ImageView imageView);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnPhotoTapListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnPhotoTapListener.java
new file mode 100644
index 0000000..5f6f070
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnPhotoTapListener.java
@@ -0,0 +1,22 @@
+package com.github.chrisbanes.photoview;
+
+import android.widget.ImageView;
+
+/**
+ * A callback to be invoked when the Photo is tapped with a single
+ * tap.
+ */
+public interface OnPhotoTapListener {
+
+ /**
+ * A callback to receive where the user taps on a photo. You will only receive a callback if
+ * the user taps on the actual photo, tapping on 'whitespace' will be ignored.
+ *
+ * @param view ImageView the user tapped.
+ * @param x where the user tapped from the of the Drawable, as percentage of the
+ * Drawable width.
+ * @param y where the user tapped from the top of the Drawable, as percentage of the
+ * Drawable height.
+ */
+ void onPhotoTap(ImageView view, float x, float y);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnScaleChangedListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnScaleChangedListener.java
new file mode 100644
index 0000000..c6bb7a6
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnScaleChangedListener.java
@@ -0,0 +1,17 @@
+package com.github.chrisbanes.photoview;
+
+
+/**
+ * Interface definition for callback to be invoked when attached ImageView scale changes
+ */
+public interface OnScaleChangedListener {
+
+ /**
+ * Callback for when the scale changes
+ *
+ * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in)
+ * @param focusX focal point X position
+ * @param focusY focal point Y position
+ */
+ void onScaleChange(float scaleFactor, float focusX, float focusY);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnSingleFlingListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnSingleFlingListener.java
new file mode 100644
index 0000000..f5dab92
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnSingleFlingListener.java
@@ -0,0 +1,21 @@
+package com.github.chrisbanes.photoview;
+
+import android.view.MotionEvent;
+
+/**
+ * A callback to be invoked when the ImageView is flung with a single
+ * touch
+ */
+public interface OnSingleFlingListener {
+
+ /**
+ * A callback to receive where the user flings on a ImageView. You will receive a callback if
+ * the user flings anywhere on the view.
+ *
+ * @param e1 MotionEvent the user first touch.
+ * @param e2 MotionEvent the user last touch.
+ * @param velocityX distance of user's horizontal fling.
+ * @param velocityY distance of user's vertical fling.
+ */
+ boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewDragListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewDragListener.java
new file mode 100644
index 0000000..66999a5
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewDragListener.java
@@ -0,0 +1,16 @@
+package com.github.chrisbanes.photoview;
+
+/**
+ * Interface definition for a callback to be invoked when the photo is experiencing a drag event
+ */
+public interface OnViewDragListener {
+
+ /**
+ * Callback for when the photo is experiencing a drag event. This cannot be invoked when the
+ * user is scaling.
+ *
+ * @param dx The change of the coordinates in the x-direction
+ * @param dy The change of the coordinates in the y-direction
+ */
+ void onDrag(float dx, float dy);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewTapListener.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewTapListener.java
new file mode 100644
index 0000000..6856255
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/OnViewTapListener.java
@@ -0,0 +1,16 @@
+package com.github.chrisbanes.photoview;
+
+import android.view.View;
+
+public interface OnViewTapListener {
+
+ /**
+ * A callback to receive where the user taps on a ImageView. You will receive a callback if
+ * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored.
+ *
+ * @param view - View the user tapped.
+ * @param x - where the user tapped from the left of the View.
+ * @param y - where the user tapped from the top of the View.
+ */
+ void onViewTap(View view, float x, float y);
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoView.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoView.java
new file mode 100644
index 0000000..8a8ba0a
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoView.java
@@ -0,0 +1,256 @@
+/*
+ Copyright 2011, 2012 Chris Banes.
+ <p>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ <p>
+ http://www.apache.org/licenses/LICENSE-2.0
+ <p>
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.github.chrisbanes.photoview;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+/**
+ * A zoomable ImageView. See {@link PhotoViewAttacher} for most of the details on how the zooming
+ * is accomplished
+ */
+@SuppressWarnings("unused")
+public class PhotoView extends AppCompatImageView {
+
+ private PhotoViewAttacher attacher;
+ private ScaleType pendingScaleType;
+
+ public PhotoView(Context context) {
+ this(context, null);
+ }
+
+ public PhotoView(Context context, AttributeSet attr) {
+ this(context, attr, 0);
+ }
+
+ public PhotoView(Context context, AttributeSet attr, int defStyle) {
+ super(context, attr, defStyle);
+ init();
+ }
+
+ private void init() {
+ attacher = new PhotoViewAttacher(this);
+ //We always pose as a Matrix scale type, though we can change to another scale type
+ //via the attacher
+ super.setScaleType(ScaleType.MATRIX);
+ //apply the previously applied scale type
+ if (pendingScaleType != null) {
+ setScaleType(pendingScaleType);
+ pendingScaleType = null;
+ }
+ }
+
+ /**
+ * Get the current {@link PhotoViewAttacher} for this view. Be wary of holding on to references
+ * to this attacher, as it has a reference to this view, which, if a reference is held in the
+ * wrong place, can cause memory leaks.
+ *
+ * @return the attacher.
+ */
+ public PhotoViewAttacher getAttacher() {
+ return attacher;
+ }
+
+ @Override
+ public ScaleType getScaleType() {
+ return attacher.getScaleType();
+ }
+
+ @Override
+ public Matrix getImageMatrix() {
+ return attacher.getImageMatrix();
+ }
+
+ @Override
+ public void setOnLongClickListener(OnLongClickListener l) {
+ attacher.setOnLongClickListener(l);
+ }
+
+ @Override
+ public void setOnClickListener(OnClickListener l) {
+ attacher.setOnClickListener(l);
+ }
+
+ @Override
+ public void setScaleType(ScaleType scaleType) {
+ if (attacher == null) {
+ pendingScaleType = scaleType;
+ } else {
+ attacher.setScaleType(scaleType);
+ }
+ }
+
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+ super.setImageDrawable(drawable);
+ // setImageBitmap calls through to this method
+ if (attacher != null) {
+ attacher.update();
+ }
+ }
+
+ @Override
+ public void setImageResource(int resId) {
+ super.setImageResource(resId);
+ if (attacher != null) {
+ attacher.update();
+ }
+ }
+
+ @Override
+ public void setImageURI(Uri uri) {
+ super.setImageURI(uri);
+ if (attacher != null) {
+ attacher.update();
+ }
+ }
+
+ @Override
+ protected boolean setFrame(int l, int t, int r, int b) {
+ boolean changed = super.setFrame(l, t, r, b);
+ if (changed) {
+ attacher.update();
+ }
+ return changed;
+ }
+
+ public void setRotationTo(float rotationDegree) {
+ attacher.setRotationTo(rotationDegree);
+ }
+
+ public void setRotationBy(float rotationDegree) {
+ attacher.setRotationBy(rotationDegree);
+ }
+
+ public boolean isZoomable() {
+ return attacher.isZoomable();
+ }
+
+ public void setZoomable(boolean zoomable) {
+ attacher.setZoomable(zoomable);
+ }
+
+ public RectF getDisplayRect() {
+ return attacher.getDisplayRect();
+ }
+
+ public void getDisplayMatrix(Matrix matrix) {
+ attacher.getDisplayMatrix(matrix);
+ }
+
+ @SuppressWarnings("UnusedReturnValue") public boolean setDisplayMatrix(Matrix finalRectangle) {
+ return attacher.setDisplayMatrix(finalRectangle);
+ }
+
+ public void getSuppMatrix(Matrix matrix) {
+ attacher.getSuppMatrix(matrix);
+ }
+
+ public boolean setSuppMatrix(Matrix matrix) {
+ return attacher.setDisplayMatrix(matrix);
+ }
+
+ public float getMinimumScale() {
+ return attacher.getMinimumScale();
+ }
+
+ public float getMediumScale() {
+ return attacher.getMediumScale();
+ }
+
+ public float getMaximumScale() {
+ return attacher.getMaximumScale();
+ }
+
+ public float getScale() {
+ return attacher.getScale();
+ }
+
+ public void setAllowParentInterceptOnEdge(boolean allow) {
+ attacher.setAllowParentInterceptOnEdge(allow);
+ }
+
+ public void setMinimumScale(float minimumScale) {
+ attacher.setMinimumScale(minimumScale);
+ }
+
+ public void setMediumScale(float mediumScale) {
+ attacher.setMediumScale(mediumScale);
+ }
+
+ public void setMaximumScale(float maximumScale) {
+ attacher.setMaximumScale(maximumScale);
+ }
+
+ public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) {
+ attacher.setScaleLevels(minimumScale, mediumScale, maximumScale);
+ }
+
+ public void setOnMatrixChangeListener(OnMatrixChangedListener listener) {
+ attacher.setOnMatrixChangeListener(listener);
+ }
+
+ public void setOnPhotoTapListener(OnPhotoTapListener listener) {
+ attacher.setOnPhotoTapListener(listener);
+ }
+
+ public void setOnOutsidePhotoTapListener(OnOutsidePhotoTapListener listener) {
+ attacher.setOnOutsidePhotoTapListener(listener);
+ }
+
+ public void setOnViewTapListener(OnViewTapListener listener) {
+ attacher.setOnViewTapListener(listener);
+ }
+
+ public void setOnViewDragListener(OnViewDragListener listener) {
+ attacher.setOnViewDragListener(listener);
+ }
+
+ public void setScale(float scale) {
+ attacher.setScale(scale);
+ }
+
+ public void setScale(float scale, boolean animate) {
+ attacher.setScale(scale, animate);
+ }
+
+ public void setScale(float scale, float focalX, float focalY, boolean animate) {
+ attacher.setScale(scale, focalX, focalY, animate);
+ }
+
+ public void setZoomTransitionDuration(int milliseconds) {
+ attacher.setZoomTransitionDuration(milliseconds);
+ }
+
+ public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener onDoubleTapListener) {
+ attacher.setOnDoubleTapListener(onDoubleTapListener);
+ }
+
+ public void setOnScaleChangeListener(OnScaleChangedListener onScaleChangedListener) {
+ attacher.setOnScaleChangeListener(onScaleChangedListener);
+ }
+
+ public void setOnSingleFlingListener(OnSingleFlingListener onSingleFlingListener) {
+ attacher.setOnSingleFlingListener(onSingleFlingListener);
+ }
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoViewAttacher.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoViewAttacher.java
new file mode 100755
index 0000000..faf3491
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/PhotoViewAttacher.java
@@ -0,0 +1,822 @@
+/*
+ Copyright 2011, 2012 Chris Banes.
+ <p>
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ <p>
+ http://www.apache.org/licenses/LICENSE-2.0
+ <p>
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.github.chrisbanes.photoview;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Matrix.ScaleToFit;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+import android.view.ViewParent;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+import android.widget.OverScroller;
+
+/**
+ * The component of {@link PhotoView} which does the work allowing for zooming, scaling, panning, etc.
+ * It is made public in case you need to subclass something other than AppCompatImageView and still
+ * gain the functionality that {@link PhotoView} offers
+ */
+public class PhotoViewAttacher implements View.OnTouchListener,
+ View.OnLayoutChangeListener {
+
+ private static float DEFAULT_MAX_SCALE = 3.0f;
+ private static float DEFAULT_MID_SCALE = 1.75f;
+ private static float DEFAULT_MIN_SCALE = 1.0f;
+ private static int DEFAULT_ZOOM_DURATION = 200;
+
+ private static final int HORIZONTAL_EDGE_NONE = -1;
+ private static final int HORIZONTAL_EDGE_LEFT = 0;
+ private static final int HORIZONTAL_EDGE_RIGHT = 1;
+ private static final int HORIZONTAL_EDGE_BOTH = 2;
+ private static final int VERTICAL_EDGE_NONE = -1;
+ private static final int VERTICAL_EDGE_TOP = 0;
+ private static final int VERTICAL_EDGE_BOTTOM = 1;
+ private static final int VERTICAL_EDGE_BOTH = 2;
+ private static int SINGLE_TOUCH = 1;
+
+ private Interpolator mInterpolator = new AccelerateDecelerateInterpolator();
+ private int mZoomDuration = DEFAULT_ZOOM_DURATION;
+ private float mMinScale = DEFAULT_MIN_SCALE;
+ private float mMidScale = DEFAULT_MID_SCALE;
+ private float mMaxScale = DEFAULT_MAX_SCALE;
+
+ private boolean mAllowParentInterceptOnEdge = true;
+ private boolean mBlockParentIntercept = false;
+
+ private ImageView mImageView;
+
+ // Gesture Detectors
+ private GestureDetector mGestureDetector;
+ private CustomGestureDetector mScaleDragDetector;
+
+ // These are set so we don't keep allocating them on the heap
+ private final Matrix mBaseMatrix = new Matrix();
+ private final Matrix mDrawMatrix = new Matrix();
+ private final Matrix mSuppMatrix = new Matrix();
+ private final RectF mDisplayRect = new RectF();
+ private final float[] mMatrixValues = new float[9];
+
+ // Listeners
+ private OnMatrixChangedListener mMatrixChangeListener;
+ private OnPhotoTapListener mPhotoTapListener;
+ private OnOutsidePhotoTapListener mOutsidePhotoTapListener;
+ private OnViewTapListener mViewTapListener;
+ private View.OnClickListener mOnClickListener;
+ private OnLongClickListener mLongClickListener;
+ private OnScaleChangedListener mScaleChangeListener;
+ private OnSingleFlingListener mSingleFlingListener;
+ private OnViewDragListener mOnViewDragListener;
+
+ private FlingRunnable mCurrentFlingRunnable;
+ private int mHorizontalScrollEdge = HORIZONTAL_EDGE_BOTH;
+ private int mVerticalScrollEdge = VERTICAL_EDGE_BOTH;
+ private float mBaseRotation;
+
+ private boolean mZoomEnabled = true;
+ private ScaleType mScaleType = ScaleType.FIT_CENTER;
+
+ private OnGestureListener onGestureListener = new OnGestureListener() {
+ @Override
+ public void onDrag(float dx, float dy) {
+ if (mScaleDragDetector.isScaling()) {
+ return; // Do not drag if we are already scaling
+ }
+ if (mOnViewDragListener != null) {
+ mOnViewDragListener.onDrag(dx, dy);
+ }
+ mSuppMatrix.postTranslate(dx, dy);
+ checkAndDisplayMatrix();
+
+ /*
+ * Here we decide whether to let the ImageView's parent to start taking
+ * over the touch event.
+ *
+ * First we check whether this function is enabled. We never want the
+ * parent to take over if we're scaling. We then check the edge we're
+ * on, and the direction of the scroll (i.e. if we're pulling against
+ * the edge, aka 'overscrolling', let the parent take over).
+ */
+ ViewParent parent = mImageView.getParent();
+ if (mAllowParentInterceptOnEdge && !mScaleDragDetector.isScaling() && !mBlockParentIntercept) {
+ if (mHorizontalScrollEdge == HORIZONTAL_EDGE_BOTH
+ || (mHorizontalScrollEdge == HORIZONTAL_EDGE_LEFT && dx >= 1f)
+ || (mHorizontalScrollEdge == HORIZONTAL_EDGE_RIGHT && dx <= -1f)
+ || (mVerticalScrollEdge == VERTICAL_EDGE_TOP && dy >= 1f)
+ || (mVerticalScrollEdge == VERTICAL_EDGE_BOTTOM && dy <= -1f)) {
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(false);
+ }
+ }
+ } else {
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ }
+ }
+
+ @Override
+ public void onFling(float startX, float startY, float velocityX, float velocityY) {
+ mCurrentFlingRunnable = new FlingRunnable(mImageView.getContext());
+ mCurrentFlingRunnable.fling(getImageViewWidth(mImageView),
+ getImageViewHeight(mImageView), (int) velocityX, (int) velocityY);
+ mImageView.post(mCurrentFlingRunnable);
+ }
+
+ @Override
+ public void onScale(float scaleFactor, float focusX, float focusY) {
+ if (getScale() < mMaxScale || scaleFactor < 1f) {
+ if (mScaleChangeListener != null) {
+ mScaleChangeListener.onScaleChange(scaleFactor, focusX, focusY);
+ }
+ mSuppMatrix.postScale(scaleFactor, scaleFactor, focusX, focusY);
+ checkAndDisplayMatrix();
+ }
+ }
+ };
+
+ public PhotoViewAttacher(ImageView imageView) {
+ mImageView = imageView;
+ imageView.setOnTouchListener(this);
+ imageView.addOnLayoutChangeListener(this);
+ if (imageView.isInEditMode()) {
+ return;
+ }
+ mBaseRotation = 0.0f;
+ // Create Gesture Detectors...
+ mScaleDragDetector = new CustomGestureDetector(imageView.getContext(), onGestureListener);
+ mGestureDetector = new GestureDetector(imageView.getContext(), new GestureDetector.SimpleOnGestureListener() {
+
+ // forward long click listener
+ @Override
+ public void onLongPress(MotionEvent e) {
+ if (mLongClickListener != null) {
+ mLongClickListener.onLongClick(mImageView);
+ }
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2,
+ float velocityX, float velocityY) {
+ if (mSingleFlingListener != null) {
+ if (getScale() > DEFAULT_MIN_SCALE) {
+ return false;
+ }
+ if (e1.getPointerCount() > SINGLE_TOUCH
+ || e2.getPointerCount() > SINGLE_TOUCH) {
+ return false;
+ }
+ return mSingleFlingListener.onFling(e1, e2, velocityX, velocityY);
+ }
+ return false;
+ }
+ });
+ mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ if (mOnClickListener != null) {
+ mOnClickListener.onClick(mImageView);
+ }
+ final RectF displayRect = getDisplayRect();
+ final float x = e.getX(), y = e.getY();
+ if (mViewTapListener != null) {
+ mViewTapListener.onViewTap(mImageView, x, y);
+ }
+ if (displayRect != null) {
+ // Check to see if the user tapped on the photo
+ if (displayRect.contains(x, y)) {
+ float xResult = (x - displayRect.left)
+ / displayRect.width();
+ float yResult = (y - displayRect.top)
+ / displayRect.height();
+ if (mPhotoTapListener != null) {
+ mPhotoTapListener.onPhotoTap(mImageView, xResult, yResult);
+ }
+ return true;
+ } else {
+ if (mOutsidePhotoTapListener != null) {
+ mOutsidePhotoTapListener.onOutsidePhotoTap(mImageView);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent ev) {
+ try {
+ float scale = getScale();
+ float x = ev.getX();
+ float y = ev.getY();
+ if (scale < getMediumScale()) {
+ setScale(getMediumScale(), x, y, true);
+ } else if (scale >= getMediumScale() && scale < getMaximumScale()) {
+ setScale(getMaximumScale(), x, y, true);
+ } else {
+ setScale(getMinimumScale(), x, y, true);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Can sometimes happen when getX() and getY() is called
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent e) {
+ // Wait for the confirmed onDoubleTap() instead
+ return false;
+ }
+ });
+ }
+
+ public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener) {
+ this.mGestureDetector.setOnDoubleTapListener(newOnDoubleTapListener);
+ }
+
+ public void setOnScaleChangeListener(OnScaleChangedListener onScaleChangeListener) {
+ this.mScaleChangeListener = onScaleChangeListener;
+ }
+
+ public void setOnSingleFlingListener(OnSingleFlingListener onSingleFlingListener) {
+ this.mSingleFlingListener = onSingleFlingListener;
+ }
+
+ @Deprecated
+ public boolean isZoomEnabled() {
+ return mZoomEnabled;
+ }
+
+ public RectF getDisplayRect() {
+ checkMatrixBounds();
+ return getDisplayRect(getDrawMatrix());
+ }
+
+ public boolean setDisplayMatrix(Matrix finalMatrix) {
+ if (finalMatrix == null) {
+ throw new IllegalArgumentException("Matrix cannot be null");
+ }
+ if (mImageView.getDrawable() == null) {
+ return false;
+ }
+ mSuppMatrix.set(finalMatrix);
+ checkAndDisplayMatrix();
+ return true;
+ }
+
+ public void setBaseRotation(final float degrees) {
+ mBaseRotation = degrees % 360;
+ update();
+ setRotationBy(mBaseRotation);
+ checkAndDisplayMatrix();
+ }
+
+ public void setRotationTo(float degrees) {
+ mSuppMatrix.setRotate(degrees % 360);
+ checkAndDisplayMatrix();
+ }
+
+ public void setRotationBy(float degrees) {
+ mSuppMatrix.postRotate(degrees % 360);
+ checkAndDisplayMatrix();
+ }
+
+ public float getMinimumScale() {
+ return mMinScale;
+ }
+
+ public float getMediumScale() {
+ return mMidScale;
+ }
+
+ public float getMaximumScale() {
+ return mMaxScale;
+ }
+
+ public float getScale() {
+ return (float) Math.sqrt((float) Math.pow(getValue(mSuppMatrix, Matrix.MSCALE_X), 2) + (float) Math.pow
+ (getValue(mSuppMatrix, Matrix.MSKEW_Y), 2));
+ }
+
+ public ScaleType getScaleType() {
+ return mScaleType;
+ }
+
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int
+ oldRight, int oldBottom) {
+ // Update our base matrix, as the bounds have changed
+ if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
+ updateBaseMatrix(mImageView.getDrawable());
+ }
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent ev) {
+ boolean handled = false;
+ if (mZoomEnabled && Util.hasDrawable((ImageView) v)) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ ViewParent parent = v.getParent();
+ // First, disable the Parent from intercepting the touch
+ // event
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ // If we're flinging, and the user presses down, cancel
+ // fling
+ cancelFling();
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ // If the user has zoomed less than min scale, zoom back
+ // to min scale
+ if (getScale() < mMinScale) {
+ RectF rect = getDisplayRect();
+ if (rect != null) {
+ v.post(new AnimatedZoomRunnable(getScale(), mMinScale,
+ rect.centerX(), rect.centerY()));
+ handled = true;
+ }
+ } else if (getScale() > mMaxScale) {
+ RectF rect = getDisplayRect();
+ if (rect != null) {
+ v.post(new AnimatedZoomRunnable(getScale(), mMaxScale,
+ rect.centerX(), rect.centerY()));
+ handled = true;
+ }
+ }
+ break;
+ }
+ // Try the Scale/Drag detector
+ if (mScaleDragDetector != null) {
+ boolean wasScaling = mScaleDragDetector.isScaling();
+ boolean wasDragging = mScaleDragDetector.isDragging();
+ handled = mScaleDragDetector.onTouchEvent(ev);
+ boolean didntScale = !wasScaling && !mScaleDragDetector.isScaling();
+ boolean didntDrag = !wasDragging && !mScaleDragDetector.isDragging();
+ mBlockParentIntercept = didntScale && didntDrag;
+ }
+ // Check to see if the user double tapped
+ if (mGestureDetector != null && mGestureDetector.onTouchEvent(ev)) {
+ handled = true;
+ }
+
+ }
+ return handled;
+ }
+
+ public void setAllowParentInterceptOnEdge(boolean allow) {
+ mAllowParentInterceptOnEdge = allow;
+ }
+
+ public void setMinimumScale(float minimumScale) {
+ Util.checkZoomLevels(minimumScale, mMidScale, mMaxScale);
+ mMinScale = minimumScale;
+ }
+
+ public void setMediumScale(float mediumScale) {
+ Util.checkZoomLevels(mMinScale, mediumScale, mMaxScale);
+ mMidScale = mediumScale;
+ }
+
+ public void setMaximumScale(float maximumScale) {
+ Util.checkZoomLevels(mMinScale, mMidScale, maximumScale);
+ mMaxScale = maximumScale;
+ }
+
+ public void setScaleLevels(float minimumScale, float mediumScale, float maximumScale) {
+ Util.checkZoomLevels(minimumScale, mediumScale, maximumScale);
+ mMinScale = minimumScale;
+ mMidScale = mediumScale;
+ mMaxScale = maximumScale;
+ }
+
+ public void setOnLongClickListener(OnLongClickListener listener) {
+ mLongClickListener = listener;
+ }
+
+ public void setOnClickListener(View.OnClickListener listener) {
+ mOnClickListener = listener;
+ }
+
+ public void setOnMatrixChangeListener(OnMatrixChangedListener listener) {
+ mMatrixChangeListener = listener;
+ }
+
+ public void setOnPhotoTapListener(OnPhotoTapListener listener) {
+ mPhotoTapListener = listener;
+ }
+
+ public void setOnOutsidePhotoTapListener(OnOutsidePhotoTapListener mOutsidePhotoTapListener) {
+ this.mOutsidePhotoTapListener = mOutsidePhotoTapListener;
+ }
+
+ public void setOnViewTapListener(OnViewTapListener listener) {
+ mViewTapListener = listener;
+ }
+
+ public void setOnViewDragListener(OnViewDragListener listener) {
+ mOnViewDragListener = listener;
+ }
+
+ public void setScale(float scale) {
+ setScale(scale, false);
+ }
+
+ public void setScale(float scale, boolean animate) {
+ setScale(scale,
+ (mImageView.getRight()) / 2,
+ (mImageView.getBottom()) / 2,
+ animate);
+ }
+
+ public void setScale(float scale, float focalX, float focalY,
+ boolean animate) {
+ // Check to see if the scale is within bounds
+ if (scale < mMinScale || scale > mMaxScale) {
+ throw new IllegalArgumentException("Scale must be within the range of minScale and maxScale");
+ }
+ if (animate) {
+ mImageView.post(new AnimatedZoomRunnable(getScale(), scale,
+ focalX, focalY));
+ } else {
+ mSuppMatrix.setScale(scale, scale, focalX, focalY);
+ checkAndDisplayMatrix();
+ }
+ }
+
+ /**
+ * Set the zoom interpolator
+ *
+ * @param interpolator the zoom interpolator
+ */
+ public void setZoomInterpolator(Interpolator interpolator) {
+ mInterpolator = interpolator;
+ }
+
+ public void setScaleType(ScaleType scaleType) {
+ if (Util.isSupportedScaleType(scaleType) && scaleType != mScaleType) {
+ mScaleType = scaleType;
+ update();
+ }
+ }
+
+ public boolean isZoomable() {
+ return mZoomEnabled;
+ }
+
+ public void setZoomable(boolean zoomable) {
+ mZoomEnabled = zoomable;
+ update();
+ }
+
+ public void update() {
+ if (mZoomEnabled) {
+ // Update the base matrix using the current drawable
+ updateBaseMatrix(mImageView.getDrawable());
+ } else {
+ // Reset the Matrix...
+ resetMatrix();
+ }
+ }
+
+ /**
+ * Get the display matrix
+ *
+ * @param matrix target matrix to copy to
+ */
+ public void getDisplayMatrix(Matrix matrix) {
+ matrix.set(getDrawMatrix());
+ }
+
+ /**
+ * Get the current support matrix
+ */
+ public void getSuppMatrix(Matrix matrix) {
+ matrix.set(mSuppMatrix);
+ }
+
+ private Matrix getDrawMatrix() {
+ mDrawMatrix.set(mBaseMatrix);
+ mDrawMatrix.postConcat(mSuppMatrix);
+ return mDrawMatrix;
+ }
+
+ public Matrix getImageMatrix() {
+ return mDrawMatrix;
+ }
+
+ public void setZoomTransitionDuration(int milliseconds) {
+ this.mZoomDuration = milliseconds;
+ }
+
+ /**
+ * Helper method that 'unpacks' a Matrix and returns the required value
+ *
+ * @param matrix Matrix to unpack
+ * @param whichValue Which value from Matrix.M* to return
+ * @return returned value
+ */
+ private float getValue(Matrix matrix, int whichValue) {
+ matrix.getValues(mMatrixValues);
+ return mMatrixValues[whichValue];
+ }
+
+ /**
+ * Resets the Matrix back to FIT_CENTER, and then displays its contents
+ */
+ private void resetMatrix() {
+ mSuppMatrix.reset();
+ setRotationBy(mBaseRotation);
+ setImageViewMatrix(getDrawMatrix());
+ checkMatrixBounds();
+ }
+
+ private void setImageViewMatrix(Matrix matrix) {
+ mImageView.setImageMatrix(matrix);
+ // Call MatrixChangedListener if needed
+ if (mMatrixChangeListener != null) {
+ RectF displayRect = getDisplayRect(matrix);
+ if (displayRect != null) {
+ mMatrixChangeListener.onMatrixChanged(displayRect);
+ }
+ }
+ }
+
+ /**
+ * Helper method that simply checks the Matrix, and then displays the result
+ */
+ private void checkAndDisplayMatrix() {
+ if (checkMatrixBounds()) {
+ setImageViewMatrix(getDrawMatrix());
+ }
+ }
+
+ /**
+ * Helper method that maps the supplied Matrix to the current Drawable
+ *
+ * @param matrix - Matrix to map Drawable against
+ * @return RectF - Displayed Rectangle
+ */
+ private RectF getDisplayRect(Matrix matrix) {
+ Drawable d = mImageView.getDrawable();
+ if (d != null) {
+ mDisplayRect.set(0, 0, d.getIntrinsicWidth(),
+ d.getIntrinsicHeight());
+ matrix.mapRect(mDisplayRect);
+ return mDisplayRect;
+ }
+ return null;
+ }
+
+ /**
+ * Calculate Matrix for FIT_CENTER
+ *
+ * @param drawable - Drawable being displayed
+ */
+ private void updateBaseMatrix(Drawable drawable) {
+ if (drawable == null) {
+ return;
+ }
+ final float viewWidth = getImageViewWidth(mImageView);
+ final float viewHeight = getImageViewHeight(mImageView);
+ final int drawableWidth = drawable.getIntrinsicWidth();
+ final int drawableHeight = drawable.getIntrinsicHeight();
+ mBaseMatrix.reset();
+ final float widthScale = viewWidth / drawableWidth;
+ final float heightScale = viewHeight / drawableHeight;
+ if (mScaleType == ScaleType.CENTER) {
+ mBaseMatrix.postTranslate((viewWidth - drawableWidth) / 2F,
+ (viewHeight - drawableHeight) / 2F);
+
+ } else if (mScaleType == ScaleType.CENTER_CROP) {
+ float scale = Math.max(widthScale, heightScale);
+ mBaseMatrix.postScale(scale, scale);
+
+ /*mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
+ (viewHeight - drawableHeight * scale) / 2F);*/
+
+ // FOX: make CENTER_CROP act like TOP_CROP
+ mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
+ 0);
+
+ } else if (mScaleType == ScaleType.CENTER_INSIDE) {
+ float scale = Math.min(1.0f, Math.min(widthScale, heightScale));
+ mBaseMatrix.postScale(scale, scale);
+ mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
+ (viewHeight - drawableHeight * scale) / 2F);
+
+ } else {
+ RectF mTempSrc = new RectF(0, 0, drawableWidth, drawableHeight);
+ RectF mTempDst = new RectF(0, 0, viewWidth, viewHeight);
+ if ((int) mBaseRotation % 180 != 0) {
+ mTempSrc = new RectF(0, 0, drawableHeight, drawableWidth);
+ }
+ switch (mScaleType) {
+ case FIT_CENTER:
+ mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.CENTER);
+ break;
+ case FIT_START:
+ mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.START);
+ break;
+ case FIT_END:
+ mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.END);
+ break;
+ case FIT_XY:
+ mBaseMatrix.setRectToRect(mTempSrc, mTempDst, ScaleToFit.FILL);
+ break;
+ default:
+ break;
+ }
+ }
+ resetMatrix();
+ }
+
+ private boolean checkMatrixBounds() {
+ final RectF rect = getDisplayRect(getDrawMatrix());
+ if (rect == null) {
+ return false;
+ }
+ final float height = rect.height(), width = rect.width();
+ float deltaX = 0, deltaY = 0;
+ final int viewHeight = getImageViewHeight(mImageView);
+ if (height <= viewHeight) {
+ switch (mScaleType) {
+ case FIT_START:
+ deltaY = -rect.top;
+ break;
+ case FIT_END:
+ deltaY = viewHeight - height - rect.top;
+ break;
+ default:
+ deltaY = (viewHeight - height) / 2 - rect.top;
+ break;
+ }
+ mVerticalScrollEdge = VERTICAL_EDGE_BOTH;
+ } else if (rect.top > 0) {
+ mVerticalScrollEdge = VERTICAL_EDGE_TOP;
+ deltaY = -rect.top;
+ } else if (rect.bottom < viewHeight) {
+ mVerticalScrollEdge = VERTICAL_EDGE_BOTTOM;
+ deltaY = viewHeight - rect.bottom;
+ } else {
+ mVerticalScrollEdge = VERTICAL_EDGE_NONE;
+ }
+ final int viewWidth = getImageViewWidth(mImageView);
+ if (width <= viewWidth) {
+ switch (mScaleType) {
+ case FIT_START:
+ deltaX = -rect.left;
+ break;
+ case FIT_END:
+ deltaX = viewWidth - width - rect.left;
+ break;
+ default:
+ deltaX = (viewWidth - width) / 2 - rect.left;
+ break;
+ }
+ mHorizontalScrollEdge = HORIZONTAL_EDGE_BOTH;
+ } else if (rect.left > 0) {
+ mHorizontalScrollEdge = HORIZONTAL_EDGE_LEFT;
+ deltaX = -rect.left;
+ } else if (rect.right < viewWidth) {
+ deltaX = viewWidth - rect.right;
+ mHorizontalScrollEdge = HORIZONTAL_EDGE_RIGHT;
+ } else {
+ mHorizontalScrollEdge = HORIZONTAL_EDGE_NONE;
+ }
+ // Finally actually translate the matrix
+ mSuppMatrix.postTranslate(deltaX, deltaY);
+ return true;
+ }
+
+ private int getImageViewWidth(ImageView imageView) {
+ return imageView.getWidth() - imageView.getPaddingLeft() - imageView.getPaddingRight();
+ }
+
+ private int getImageViewHeight(ImageView imageView) {
+ return imageView.getHeight() - imageView.getPaddingTop() - imageView.getPaddingBottom();
+ }
+
+ private void cancelFling() {
+ if (mCurrentFlingRunnable != null) {
+ mCurrentFlingRunnable.cancelFling();
+ mCurrentFlingRunnable = null;
+ }
+ }
+
+ private class AnimatedZoomRunnable implements Runnable {
+
+ private final float mFocalX, mFocalY;
+ private final long mStartTime;
+ private final float mZoomStart, mZoomEnd;
+
+ public AnimatedZoomRunnable(final float currentZoom, final float targetZoom,
+ final float focalX, final float focalY) {
+ mFocalX = focalX;
+ mFocalY = focalY;
+ mStartTime = System.currentTimeMillis();
+ mZoomStart = currentZoom;
+ mZoomEnd = targetZoom;
+ }
+
+ @Override
+ public void run() {
+ float t = interpolate();
+ float scale = mZoomStart + t * (mZoomEnd - mZoomStart);
+ float deltaScale = scale / getScale();
+ onGestureListener.onScale(deltaScale, mFocalX, mFocalY);
+ // We haven't hit our target scale yet, so post ourselves again
+ if (t < 1f) {
+ Compat.postOnAnimation(mImageView, this);
+ }
+ }
+
+ private float interpolate() {
+ float t = 1f * (System.currentTimeMillis() - mStartTime) / mZoomDuration;
+ t = Math.min(1f, t);
+ t = mInterpolator.getInterpolation(t);
+ return t;
+ }
+ }
+
+ private class FlingRunnable implements Runnable {
+
+ private final OverScroller mScroller;
+ private int mCurrentX, mCurrentY;
+
+ public FlingRunnable(Context context) {
+ mScroller = new OverScroller(context);
+ }
+
+ public void cancelFling() {
+ mScroller.forceFinished(true);
+ }
+
+ public void fling(int viewWidth, int viewHeight, int velocityX,
+ int velocityY) {
+ final RectF rect = getDisplayRect();
+ if (rect == null) {
+ return;
+ }
+ final int startX = Math.round(-rect.left);
+ final int minX, maxX, minY, maxY;
+ if (viewWidth < rect.width()) {
+ minX = 0;
+ maxX = Math.round(rect.width() - viewWidth);
+ } else {
+ minX = maxX = startX;
+ }
+ final int startY = Math.round(-rect.top);
+ if (viewHeight < rect.height()) {
+ minY = 0;
+ maxY = Math.round(rect.height() - viewHeight);
+ } else {
+ minY = maxY = startY;
+ }
+ mCurrentX = startX;
+ mCurrentY = startY;
+ // If we actually can move, fling the scroller
+ if (startX != maxX || startY != maxY) {
+ mScroller.fling(startX, startY, velocityX, velocityY, minX,
+ maxX, minY, maxY, 0, 0);
+ }
+ }
+
+ @Override
+ public void run() {
+ if (mScroller.isFinished()) {
+ return; // remaining post that should not be handled
+ }
+ if (mScroller.computeScrollOffset()) {
+ final int newX = mScroller.getCurrX();
+ final int newY = mScroller.getCurrY();
+ mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY);
+ checkAndDisplayMatrix();
+ mCurrentX = newX;
+ mCurrentY = newY;
+ // Post On animation
+ Compat.postOnAnimation(mImageView, this);
+ }
+ }
+ }
+}
diff --git a/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Util.java b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Util.java
new file mode 100644
index 0000000..2e3e5ad
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/com/github/chrisbanes/photoview/Util.java
@@ -0,0 +1,37 @@
+package com.github.chrisbanes.photoview;
+
+import android.view.MotionEvent;
+import android.widget.ImageView;
+
+class Util {
+
+ static void checkZoomLevels(float minZoom, float midZoom,
+ float maxZoom) {
+ if (minZoom >= midZoom) {
+ throw new IllegalArgumentException(
+ "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value");
+ } else if (midZoom >= maxZoom) {
+ throw new IllegalArgumentException(
+ "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value");
+ }
+ }
+
+ static boolean hasDrawable(ImageView imageView) {
+ return imageView.getDrawable() != null;
+ }
+
+ static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) {
+ if (scaleType == null) {
+ return false;
+ }
+ switch (scaleType) {
+ case MATRIX:
+ throw new IllegalStateException("Matrix scale type is not supported");
+ }
+ return true;
+ }
+
+ static int getPointerIndex(int action) {
+ return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ }
+}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouch.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouch.java
deleted file mode 100644
index 73392b1..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouch.java
+++ /dev/null
@@ -1,268 +0,0 @@
-package it.sephiroth.android.library.imagezoom;
-
-import android.content.Context;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.GestureDetector.OnGestureListener;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.ScaleGestureDetector.OnScaleGestureListener;
-import android.view.ViewConfiguration;
-
-public class ImageViewTouch extends ImageViewTouchBase {
-
- private static final float SCROLL_DELTA_THRESHOLD = 1.0f;
- static final float MIN_ZOOM = 0.9f;
- protected ScaleGestureDetector mScaleDetector;
- protected GestureDetector mGestureDetector;
- protected int mTouchSlop;
- protected float mCurrentScaleFactor;
- protected float mScaleFactor;
- protected int mDoubleTapDirection;
- protected OnGestureListener mGestureListener;
- protected OnScaleGestureListener mScaleListener;
- protected boolean mDoubleTapToZoomEnabled = true;
- protected boolean mScaleEnabled = true;
- protected boolean mScrollEnabled = true;
-
- private OnImageViewTouchDoubleTapListener doubleTapListener;
-
- public interface OnScaleChangedListener {
- public void onScaleChanged(float scale);
- }
-
- protected OnScaleChangedListener mScaleChangedListener;
-
- public ImageViewTouch( Context context, AttributeSet attrs ) {
- super( context, attrs );
- }
-
- @Override
- protected void init() {
- super.init();
- mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- mGestureListener = getGestureListener();
- mScaleListener = getScaleListener();
-
- mScaleDetector = new ScaleGestureDetector( getContext(), mScaleListener );
- mGestureDetector = new GestureDetector( getContext(), mGestureListener, null, true );
-
- mCurrentScaleFactor = 1f;
- mDoubleTapDirection = 1;
- }
-
- public void setDoubleTapListener( OnImageViewTouchDoubleTapListener doubleTapListener ){
- this.doubleTapListener = doubleTapListener;
- }
-
- public void setDoubleTapToZoomEnabled( boolean value ) {
- mDoubleTapToZoomEnabled = value;
- }
-
- public void setScaleEnabled( boolean value ) {
- mScaleEnabled = value;
- }
-
- public void setScrollEnabled( boolean value ) {
- mScrollEnabled = value;
- }
-
- public boolean getDoubleTapEnabled() {
- return mDoubleTapToZoomEnabled;
- }
-
- protected OnGestureListener getGestureListener() {
- return new GestureListener();
- }
-
- protected OnScaleGestureListener getScaleListener() {
- return new ScaleListener();
- }
-
- @Override
- protected void onBitmapChanged( Drawable drawable ) {
- super.onBitmapChanged( drawable );
-
- float v[] = new float[9];
- mSuppMatrix.getValues( v );
- mCurrentScaleFactor = v[Matrix.MSCALE_X];
- }
-
- @Override
- protected void _setImageDrawable( final Drawable drawable, final boolean reset, final Matrix initial_matrix, final float maxZoom ) {
- super._setImageDrawable( drawable, reset, initial_matrix, maxZoom );
- mScaleFactor = getMaxZoom() / 3;
- }
-
- @Override
- public boolean onTouchEvent( MotionEvent event ) {
- mScaleDetector.onTouchEvent( event );
- if ( !mScaleDetector.isInProgress() ) mGestureDetector.onTouchEvent( event );
- int action = event.getAction();
- switch ( action & MotionEvent.ACTION_MASK ) {
- case MotionEvent.ACTION_UP:
- if ( getScale() < 1f ) {
- zoomTo( 1f, 50 );
- }
- break;
- }
- return true;
- }
-
- @Override
- protected void onZoom( float scale ) {
- super.onZoom( scale );
- if ( !mScaleDetector.isInProgress() ) mCurrentScaleFactor = scale;
-
- if (mScaleChangedListener != null) {
- mScaleChangedListener.onScaleChanged(mCurrentScaleFactor);
- }
- }
-
- protected float onDoubleTapPost( float scale, float maxZoom ) {
- if ( mDoubleTapDirection == 1 ) {
- if (mCurrentScaleFactor - 1.0f < 0.01) { //( scale + ( mScaleFactor * 2 ) ) <= maxZoom
-
- float scaleFactor = mScaleFactor;
-
- RectF bitmapRect = getBitmapRect();
-
- float w = bitmapRect.right - bitmapRect.left;
- float h = bitmapRect.bottom - bitmapRect.top;
-
- if (w < getWidth()) {
- scaleFactor = (float)getWidth() / w - scale;
- } else if (h < getHeight()) {
- scaleFactor = (float)getHeight() / h - scale;
- }
-
- return scale + scaleFactor;
- } else {
- mDoubleTapDirection = -1;
- return maxZoom;
- }
- } else {
- mDoubleTapDirection = 1;
- return 1f;
- }
- }
-
- /**
- * Determines whether this ImageViewTouch can be scrolled.
- * @param direction
- * - positive direction value means scroll from right to left,
- * negative value means scroll from left to right
- *
- * @return true if there is some more place to scroll, false - otherwise.
- */
- public boolean canScroll(int direction) {
- RectF bitmapRect = getBitmapRect();
- updateRect(bitmapRect, mScrollRect);
- Rect imageViewRect = new Rect();
- getGlobalVisibleRect(imageViewRect);
-
- if (bitmapRect.right >= imageViewRect.right) {
- if (direction < 0) {
- return Math.abs(bitmapRect.right - imageViewRect.right) > SCROLL_DELTA_THRESHOLD;
- }
- }
-
- double bitmapScrollRectDelta = Math.abs(bitmapRect.left - mScrollRect.left);
- return bitmapScrollRectDelta > SCROLL_DELTA_THRESHOLD;
- }
-
- public class GestureListener extends GestureDetector.SimpleOnGestureListener {
-
- @Override
- public boolean onDoubleTap( MotionEvent e ) {
- Log.i( LOG_TAG, "onDoubleTap. double tap enabled? " + mDoubleTapToZoomEnabled);
- if (mDoubleTapToZoomEnabled) {
- float scale = getScale();
- float targetScale = scale;
- targetScale = onDoubleTapPost( scale, getMaxZoom() );
- targetScale = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
- mCurrentScaleFactor = targetScale;
- zoomTo( targetScale, e.getX(), e.getY(), 200 );
- invalidate();
- }
-
- if( null != doubleTapListener ){
- doubleTapListener.onDoubleTap();
- }
-
- return super.onDoubleTap( e );
- }
-
- @Override
- public void onLongPress( MotionEvent e ) {
- if ( isLongClickable() ) {
- if ( !mScaleDetector.isInProgress() ) {
- setPressed( true );
- performLongClick();
- }
- }
- }
-
- @Override
- public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY ) {
- if ( !mScrollEnabled ) return false;
-
- if ( e1 == null || e2 == null ) return false;
- if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
- if ( mScaleDetector.isInProgress() ) return false;
- if ( getScale() == 1f ) return false;
- scrollBy( -distanceX, -distanceY );
- invalidate();
- return super.onScroll( e1, e2, distanceX, distanceY );
- }
-
- @Override
- public boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY ) {
- if ( !mScrollEnabled ) return false;
-
- if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
- if ( mScaleDetector.isInProgress() ) return false;
-
- float diffX = e2.getX() - e1.getX();
- float diffY = e2.getY() - e1.getY();
-
- if ( Math.abs( velocityX ) > 800 || Math.abs( velocityY ) > 800 ) {
- scrollBy( diffX / 2, diffY / 2, 300 );
- invalidate();
- }
- return super.onFling( e1, e2, velocityX, velocityY );
- }
- }
-
- public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
-
- @SuppressWarnings("unused")
- @Override
- public boolean onScale( ScaleGestureDetector detector ) {
- float span = detector.getCurrentSpan() - detector.getPreviousSpan();
- float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
- if ( mScaleEnabled ) {
- targetScale = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
- zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
- mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
- mDoubleTapDirection = 1;
- invalidate();
- return true;
- }
- return false;
- }
- }
-
- public interface OnImageViewTouchDoubleTapListener {
- void onDoubleTap();
- }
-
- public void setOnScaleChangedListener(OnScaleChangedListener listener) {
- mScaleChangedListener = listener;
- }
-}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java
deleted file mode 100755
index 8ba5b28..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/ImageViewTouchBase.java
+++ /dev/null
@@ -1,512 +0,0 @@
-package it.sephiroth.android.library.imagezoom;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.ImageView;
-
-import it.sephiroth.android.library.imagezoom.easing.Cubic;
-import it.sephiroth.android.library.imagezoom.easing.Easing;
-import it.sephiroth.android.library.imagezoom.graphics.FastBitmapDrawable;
-import it.sephiroth.android.library.imagezoom.utils.IDisposable;
-
-/**
- * Base View to manage image zoom/scrool/pinch operations
- *
- * @author alessandro
- *
- */
-public class ImageViewTouchBase extends ImageView implements IDisposable {
-
- public interface OnBitmapChangedListener {
-
- void onBitmapChanged( Drawable drawable );
- }
-
- public static final String LOG_TAG = "image";
-
- protected Easing mEasing = new Cubic();
- protected Matrix mBaseMatrix = new Matrix();
- protected Matrix mSuppMatrix = new Matrix();
- protected Handler mHandler = new Handler();
- protected Runnable mOnLayoutRunnable = null;
- protected float mMaxZoom;
- protected final Matrix mDisplayMatrix = new Matrix();
- protected final float[] mMatrixValues = new float[9];
- protected int mThisWidth = -1, mThisHeight = -1;
- protected boolean mFitToScreen = false;
- protected boolean mFitToWidth = false;
- final protected float MAX_ZOOM = 5.0f;
-
- protected RectF mBitmapRect = new RectF();
- protected RectF mCenterRect = new RectF();
- protected RectF mScrollRect = new RectF();
-
- private OnBitmapChangedListener mListener;
-
- public ImageViewTouchBase( Context context ) {
- super( context );
- init();
- }
-
- public ImageViewTouchBase( Context context, AttributeSet attrs ) {
- super( context, attrs );
- init();
- }
-
- public void setOnBitmapChangedListener( OnBitmapChangedListener listener ) {
- mListener = listener;
- }
-
- protected void init() {
- setScaleType( ImageView.ScaleType.MATRIX );
- }
-
- public void clear() {
- setImageBitmap( null, true );
- }
-
- public void setFitToScreen( boolean value ) {
- if ( value != mFitToScreen ) {
- mFitToScreen = value;
- requestLayout();
- }
- }
-
- public void setFitToWidth( boolean value ) {
- if ( value != mFitToWidth ) {
- mFitToWidth = value;
- requestLayout();
- }
- }
-
- @Override
- protected void onLayout( boolean changed, int left, int top, int right, int bottom ) {
- super.onLayout( changed, left, top, right, bottom );
- mThisWidth = right - left;
- mThisHeight = bottom - top;
- Runnable r = mOnLayoutRunnable;
- if ( r != null ) {
- mOnLayoutRunnable = null;
- r.run();
- }
- if ( getDrawable() != null ) {
- if (mFitToWidth) {
- zoomToWidth();
- } else {
- if (mFitToScreen)
- getProperBaseMatrix2(getDrawable(), mBaseMatrix);
- else
- getProperBaseMatrix(getDrawable(), mBaseMatrix);
- setImageMatrix(getImageViewMatrix());
- }
- }
- }
-
- @Override
- public void setImageBitmap( Bitmap bm ) {
- setImageBitmap( bm, true );
- }
-
- @Override
- public void setImageResource( int resId ) {
- setImageDrawable( getContext().getResources().getDrawable( resId ) );
- }
-
- /**
- * Set the new image to display and reset the internal matrix.
- *
- * @param bitmap
- * - the {@link Bitmap} to display
- * @param reset
- * - if true the image bounds will be recreated, otherwise the old {@link Matrix} is used to display the new bitmap
- * @see #setImageBitmap(Bitmap)
- */
- public void setImageBitmap( final Bitmap bitmap, final boolean reset ) {
- setImageBitmap( bitmap, reset, null );
- }
-
- /**
- * Similar to {@link #setImageBitmap(Bitmap, boolean)} but an optional view {@link Matrix} can be passed to determine the new
- * bitmap view matrix.<br />
- * This method is useful if you need to restore a Bitmap with the same zoom/pan values from a previous state
- *
- * @param bitmap
- * - the {@link Bitmap} to display
- * @param reset
- * @param matrix
- * - the {@link Matrix} to be used to display the new bitmap
- *
- * @see #setImageBitmap(Bitmap, boolean)
- * @see #setImageBitmap(Bitmap)
- * @see #getImageViewMatrix()
- * @see #getDisplayMatrix()
- */
- public void setImageBitmap( final Bitmap bitmap, final boolean reset, Matrix matrix ) {
- setImageBitmap( bitmap, reset, matrix, -1 );
- }
-
- /**
- *
- * @param bitmap
- * @param reset
- * @param matrix
- * @param maxZoom
- * - maximum zoom allowd during zoom gestures
- *
- * @see #setImageBitmap(Bitmap, boolean, Matrix)
- */
- public void setImageBitmap( final Bitmap bitmap, final boolean reset, Matrix matrix, float maxZoom ) {
-
- Log.i( LOG_TAG, "setImageBitmap: " + bitmap );
-
- if ( bitmap != null )
- setImageDrawable( new FastBitmapDrawable( bitmap ), reset, matrix, maxZoom );
- else
- setImageDrawable( null, reset, matrix, maxZoom );
- }
-
- @Override
- public void setImageDrawable( Drawable drawable ) {
- setImageDrawable( drawable, true, null, -1 );
- }
-
- public void setImageDrawable( final Drawable drawable, final boolean reset, final Matrix initial_matrix, final float maxZoom ) {
-
- final int viewWidth = getWidth();
-
- if ( viewWidth <= 0 ) {
- mOnLayoutRunnable = new Runnable() {
-
- @Override
- public void run() {
- setImageDrawable( drawable, reset, initial_matrix, maxZoom );
- }
- };
- return;
- }
-
- _setImageDrawable( drawable, reset, initial_matrix, maxZoom );
- }
-
- protected void _setImageDrawable( final Drawable drawable, final boolean reset, final Matrix initial_matrix, final float maxZoom ) {
-
- if ( drawable != null ) {
- if ( mFitToScreen )
- getProperBaseMatrix2( drawable, mBaseMatrix );
- else
- getProperBaseMatrix( drawable, mBaseMatrix );
- super.setImageDrawable( drawable );
-
- if (mFitToWidth) zoomToWidth();
-
- } else {
- mBaseMatrix.reset();
- super.setImageDrawable( null );
- }
-
- if ( reset ) {
- mSuppMatrix.reset();
- if ( initial_matrix != null ) {
- mSuppMatrix = new Matrix( initial_matrix );
- }
- }
-
- setImageMatrix( getImageViewMatrix() );
-
- if ( maxZoom < 1 )
- mMaxZoom = maxZoom();
- else
- mMaxZoom = maxZoom;
-
- onBitmapChanged( drawable );
- }
-
- protected void onBitmapChanged( final Drawable bitmap ) {
- if ( mListener != null ) {
- mListener.onBitmapChanged( bitmap );
- }
- }
-
- protected float maxZoom() {
- final Drawable drawable = getDrawable();
-
- if ( drawable == null ) {
- return 1F;
- }
-
- float fw = (float) drawable.getIntrinsicWidth() / (float) mThisWidth;
- float fh = (float) drawable.getIntrinsicHeight() / (float) mThisHeight;
- float max = Math.max( fw, fh ) * 4;
- return max;
- }
-
- public float getMaxZoom() {
- return mMaxZoom;
- }
-
- public Matrix getImageViewMatrix() {
- mDisplayMatrix.set( mBaseMatrix );
- mDisplayMatrix.postConcat( mSuppMatrix );
- return mDisplayMatrix;
- }
-
- /**
- * Returns the current image display matrix. This matrix can be used in the next call to the
- * {@link #setImageBitmap(Bitmap, boolean, Matrix)} to restore the same view state of the previous {@link Bitmap}
- *
- * @return
- */
- public Matrix getDisplayMatrix() {
- return new Matrix( mSuppMatrix );
- }
-
- /**
- * Setup the base matrix so that the image is centered and scaled properly.
- *
- * @param bitmap
- * @param matrix
- */
- protected void getProperBaseMatrix( Drawable drawable, Matrix matrix ) {
- float viewWidth = getWidth();
- float viewHeight = getHeight();
- float w = drawable.getIntrinsicWidth();
- float h = drawable.getIntrinsicHeight();
- matrix.reset();
-
- if ( w > viewWidth || h > viewHeight ) {
- float widthScale = Math.min( viewWidth / w, 2.0f );
- float heightScale = Math.min( viewHeight / h, 2.0f );
- float scale = Math.min( widthScale, heightScale );
- matrix.postScale( scale, scale );
- float tw = ( viewWidth - w * scale ) / 2.0f;
- float th = ( viewHeight - h * scale ) / 2.0f;
- matrix.postTranslate( tw, th );
- } else {
- float tw = ( viewWidth - w ) / 2.0f;
- float th = ( viewHeight - h ) / 2.0f;
- matrix.postTranslate( tw, th );
- }
- }
-
- /**
- * Setup the base matrix so that the image is centered and scaled properly.
- *
- * @param bitmap
- * @param matrix
- */
- protected void getProperBaseMatrix2( Drawable bitmap, Matrix matrix ) {
- float viewWidth = getWidth();
- float viewHeight = getHeight();
- float w = bitmap.getIntrinsicWidth();
- float h = bitmap.getIntrinsicHeight();
- matrix.reset();
- float widthScale = Math.min( viewWidth / w, MAX_ZOOM );
- float heightScale = Math.min( viewHeight / h, MAX_ZOOM );
- float scale = Math.min( widthScale, heightScale );
- matrix.postScale( scale, scale );
- matrix.postTranslate( ( viewWidth - w * scale ) / 2.0f, ( viewHeight - h * scale ) / 2.0f );
- }
-
- protected float getValue( Matrix matrix, int whichValue ) {
- matrix.getValues( mMatrixValues );
- return mMatrixValues[whichValue];
- }
-
- protected RectF getBitmapRect() {
- final Drawable drawable = getDrawable();
-
- if ( drawable == null ) return null;
- Matrix m = getImageViewMatrix();
- mBitmapRect.set( 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight() );
- m.mapRect( mBitmapRect );
- return mBitmapRect;
- }
-
- protected float getScale( Matrix matrix ) {
- return getValue( matrix, Matrix.MSCALE_X );
- }
-
- public float getRotation() {
- return 0;
- }
-
- public float getScale() {
- return getScale( mSuppMatrix );
- }
-
- protected void center( boolean horizontal, boolean vertical ) {
- // Log.i(LOG_TAG, "center");
- final Drawable drawable = getDrawable();
-
- if ( drawable == null ) return;
- RectF rect = getCenter( horizontal, vertical );
- if ( rect.left != 0 || rect.top != 0 ) {
- postTranslate( rect.left, rect.top );
- }
- }
-
- protected RectF getCenter( boolean horizontal, boolean vertical ) {
- final Drawable drawable = getDrawable();
-
- if ( drawable == null ) return new RectF( 0, 0, 0, 0 );
-
- RectF rect = getBitmapRect();
- float height = rect.height();
- float width = rect.width();
- float deltaX = 0, deltaY = 0;
- if ( vertical ) {
- int viewHeight = getHeight();
- if ( height < viewHeight ) {
- deltaY = ( viewHeight - height ) / 2 - rect.top;
- } else if ( rect.top > 0 ) {
- deltaY = -rect.top;
- } else if ( rect.bottom < viewHeight ) {
- deltaY = getHeight() - rect.bottom;
- }
- }
- if ( horizontal ) {
- int viewWidth = getWidth();
- if ( width < viewWidth ) {
- deltaX = ( viewWidth - width ) / 2 - rect.left;
- } else if ( rect.left > 0 ) {
- deltaX = -rect.left;
- } else if ( rect.right < viewWidth ) {
- deltaX = viewWidth - rect.right;
- }
- }
- mCenterRect.set( deltaX, deltaY, 0, 0 );
- return mCenterRect;
- }
-
- protected void postTranslate( float deltaX, float deltaY ) {
- mSuppMatrix.postTranslate( deltaX, deltaY );
- setImageMatrix( getImageViewMatrix() );
- }
-
- protected void postScale( float scale, float centerX, float centerY ) {
- mSuppMatrix.postScale( scale, scale, centerX, centerY );
- setImageMatrix( getImageViewMatrix() );
- }
-
- protected void zoomTo( float scale ) {
- float cx = getWidth() / 2F;
- float cy = getHeight() / 2F;
- zoomTo( scale, cx, cy );
- }
-
- public void zoomTo( float scale, float durationMs ) {
- float cx = getWidth() / 2F;
- float cy = getHeight() / 2F;
- zoomTo( scale, cx, cy, durationMs );
- }
-
- protected void zoomTo( float scale, float centerX, float centerY ) {
- if ( scale > mMaxZoom ) scale = mMaxZoom;
- float oldScale = getScale();
- float deltaScale = scale / oldScale;
- postScale( deltaScale, centerX, centerY );
- onZoom( getScale() );
- center( true, true );
- }
-
- protected void onZoom( float scale ) {}
-
- public void scrollBy( float x, float y ) {
- panBy( x, y );
- }
-
- protected void panBy( double dx, double dy ) {
- RectF rect = getBitmapRect();
- mScrollRect.set( (float) dx, (float) dy, 0, 0 );
- updateRect( rect, mScrollRect );
- postTranslate( mScrollRect.left, mScrollRect.top );
- center( true, true );
- }
-
- protected void updateRect( RectF bitmapRect, RectF scrollRect ) {
- float width = getWidth();
- float height = getHeight();
-
- if ( bitmapRect.top >= 0 && bitmapRect.bottom <= height ) scrollRect.top = 0;
- if ( bitmapRect.left >= 0 && bitmapRect.right <= width ) scrollRect.left = 0;
- if ( bitmapRect.top + scrollRect.top >= 0 && bitmapRect.bottom > height ) scrollRect.top = (int) ( 0 - bitmapRect.top );
- if ( bitmapRect.bottom + scrollRect.top <= ( height - 0 ) && bitmapRect.top < 0 )
- scrollRect.top = (int) ( ( height - 0 ) - bitmapRect.bottom );
- if ( bitmapRect.left + scrollRect.left >= 0 ) scrollRect.left = (int) ( 0 - bitmapRect.left );
- if ( bitmapRect.right + scrollRect.left <= ( width - 0 ) ) scrollRect.left = (int) ( ( width - 0 ) - bitmapRect.right );
- // Log.d( LOG_TAG, "scrollRect(2): " + scrollRect.toString() );
- }
-
- protected void scrollBy( float distanceX, float distanceY, final double durationMs ) {
- final double dx = distanceX;
- final double dy = distanceY;
- final long startTime = System.currentTimeMillis();
- mHandler.post( new Runnable() {
-
- double old_x = 0;
- double old_y = 0;
-
- @Override
- public void run() {
- long now = System.currentTimeMillis();
- double currentMs = Math.min( durationMs, now - startTime );
- double x = mEasing.easeOut( currentMs, 0, dx, durationMs );
- double y = mEasing.easeOut( currentMs, 0, dy, durationMs );
- panBy( ( x - old_x ), ( y - old_y ) );
- old_x = x;
- old_y = y;
- if ( currentMs < durationMs ) {
- mHandler.post( this );
- } else {
- RectF centerRect = getCenter( true, true );
- if ( centerRect.left != 0 || centerRect.top != 0 ) scrollBy( centerRect.left, centerRect.top );
- }
- }
- } );
- }
-
- protected void zoomTo( float scale, final float centerX, final float centerY, final float durationMs ) {
- // Log.i( LOG_TAG, "zoomTo: " + scale + ", " + centerX + ": " + centerY );
- final long startTime = System.currentTimeMillis();
- final float incrementPerMs = ( scale - getScale() ) / durationMs;
- final float oldScale = getScale();
- mHandler.post( new Runnable() {
-
- @Override
- public void run() {
- long now = System.currentTimeMillis();
- float currentMs = Math.min( durationMs, now - startTime );
- float target = oldScale + ( incrementPerMs * currentMs );
- zoomTo( target, centerX, centerY );
- if ( currentMs < durationMs ) {
- mHandler.post( this );
- } else {
- // if ( getScale() < 1f ) {}
- }
- }
- } );
- }
-
- @Override
- public void dispose() {
- clear();
- }
-
- protected void zoomToWidth() {
- RectF bitmapRect = getBitmapRect();
-
- float w = bitmapRect.right - bitmapRect.left;
-
- if (w < getWidth()) {
- float scale = (float)getWidth() / w;
-
- zoomTo(scale, 0f, 0f);
- }
- }
-}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Cubic.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Cubic.java
deleted file mode 100644
index 6f7e87d..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Cubic.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package it.sephiroth.android.library.imagezoom.easing;
-
-public class Cubic implements Easing {
-
- @Override
- public double easeOut( double time, double start, double end, double duration ) {
- return end * ( ( time = time / duration - 1.0 ) * time * time + 1.0 ) + start;
- }
-
- @Override
- public double easeIn( double time, double start, double end, double duration ) {
- return end * ( time /= duration ) * time * time + start;
- }
-
- @Override
- public double easeInOut( double time, double start, double end, double duration ) {
- if ( ( time /= duration / 2.0 ) < 1.0 ) return end / 2.0 * time * time * time + start;
- return end / 2.0 * ( ( time -= 2.0 ) * time * time + 2.0 ) + start;
- }
-}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Easing.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Easing.java
deleted file mode 100644
index 202e9d9..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/easing/Easing.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package it.sephiroth.android.library.imagezoom.easing;
-
-public interface Easing {
-
- double easeOut( double time, double start, double end, double duration );
-
- double easeIn( double time, double start, double end, double duration );
-
- double easeInOut( double time, double start, double end, double duration );
-}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/FastBitmapDrawable.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/FastBitmapDrawable.java
deleted file mode 100644
index 8afc38e..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/FastBitmapDrawable.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package it.sephiroth.android.library.imagezoom.graphics;
-
-import java.io.InputStream;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Drawable;
-
-/**
- * Fast bitmap drawable. Does not support states. it only
- * support alpha and colormatrix
- * @author alessandro
- *
- */
-public class FastBitmapDrawable extends Drawable implements IBitmapDrawable {
-
- protected Bitmap mBitmap;
- protected Paint mPaint;
-
- public FastBitmapDrawable( Bitmap b ) {
- mBitmap = b;
- mPaint = new Paint();
- mPaint.setDither( true );
- mPaint.setFilterBitmap( true );
- }
-
- public FastBitmapDrawable( Resources res, InputStream is ){
- this(BitmapFactory.decodeStream(is));
- }
-
- @Override
- public void draw( Canvas canvas ) {
- canvas.drawBitmap( mBitmap, 0.0f, 0.0f, mPaint );
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public void setAlpha( int alpha ) {
- mPaint.setAlpha( alpha );
- }
-
- @Override
- public void setColorFilter( ColorFilter cf ) {
- mPaint.setColorFilter( cf );
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mBitmap.getWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mBitmap.getHeight();
- }
-
- @Override
- public int getMinimumWidth() {
- return mBitmap.getWidth();
- }
-
- @Override
- public int getMinimumHeight() {
- return mBitmap.getHeight();
- }
-
- public void setAntiAlias( boolean value ){
- mPaint.setAntiAlias( value );
- invalidateSelf();
- }
-
- @Override
- public Bitmap getBitmap() {
- return mBitmap;
- }
-} \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/IBitmapDrawable.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/IBitmapDrawable.java
deleted file mode 100644
index 5a2892a..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/graphics/IBitmapDrawable.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package it.sephiroth.android.library.imagezoom.graphics;
-
-import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;
-import android.graphics.Bitmap;
-
-/**
- * Base interface used in the {@link ImageViewTouchBase} view
- * @author alessandro
- *
- */
-public interface IBitmapDrawable {
-
- Bitmap getBitmap();
-}
diff --git a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/utils/IDisposable.java b/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/utils/IDisposable.java
deleted file mode 100644
index da991a7..0000000
--- a/org.fox.ttcomics/src/main/java/it/sephiroth/android/library/imagezoom/utils/IDisposable.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package it.sephiroth.android.library.imagezoom.utils;
-
-public interface IDisposable {
-
- void dispose();
-}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/Application.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/Application.java
index 848600f..4095886 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/Application.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/Application.java
@@ -1,8 +1,6 @@
package org.fox.ttcomics2;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import com.livefront.bridge.Bridge;
import com.livefront.bridge.SavedStateHandler;
@@ -11,6 +9,8 @@ import org.acra.ACRA;
import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import icepick.Icepick;
@ReportsCrashes(mode = ReportingInteractionMode.SILENT,
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicFragment.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicFragment.java
index a21e749..ded84f2 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicFragment.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicFragment.java
@@ -5,22 +5,22 @@ import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.v7.app.ActionBar;
-import android.view.GestureDetector;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.github.chrisbanes.photoview.OnViewTapListener;
+import com.github.chrisbanes.photoview.PhotoView;
import org.fox.ttcomics2.archive.ComicArchive;
import java.io.IOException;
+import androidx.appcompat.app.ActionBar;
import icepick.State;
-import it.sephiroth.android.library.imagezoom.ImageViewTouch;
public class ComicFragment extends StateSavedFragment {
private final String TAG = this.getClass().getSimpleName();
@@ -28,9 +28,8 @@ public class ComicFragment extends StateSavedFragment {
private SharedPreferences m_prefs;
@State protected int m_page;
private ViewComicActivity m_activity;
- private GestureDetector m_detector;
- @State protected boolean m_thumbnail = false;
@State protected ComicArchive m_archive;
+ private PhotoView m_image;
public ComicFragment() {
super();
@@ -45,147 +44,37 @@ public class ComicFragment extends StateSavedFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_comic, container, false);
-
- final ImageViewTouch image = view.findViewById(R.id.comic_image);
- if (m_prefs.getBoolean("fit_to_width", false)) {
- image.setFitToWidth(true);
- } else {
- image.setFitToScreen(true);
- }
+ m_image = view.findViewById(R.id.comic_image);
try {
- Glide.with(ComicFragment.this)
+ Glide.with(getContext())
.load(m_archive.getByteArray(m_page))
.dontAnimate()
+ .dontTransform()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
- .into(image);
+ .into(m_image);
} catch (IOException e) {
- image.setImageResource(R.drawable.badimage);
+ m_image.setImageResource(R.drawable.badimage);
e.printStackTrace();
}
- image.setOnScaleChangedListener(new ImageViewTouch.OnScaleChangedListener() {
- @Override
- public void onScaleChanged(float scale) {
- // TODO: shared scale change?
- }
- });
-
- image.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent event) {
- return m_detector.onTouchEvent(event);
- }
- });
-
- //}
-
- return view;
-
- }
-
- private void onLeftSideTapped() {
- ImageViewTouch image = getView().findViewById(R.id.comic_image);
-
- if (image != null) {
- boolean atLeftEdge = !image.canScroll(1);
-
- if (atLeftEdge) {
- m_activity.selectPreviousComic();
- }
- }
- }
-
- private void onRightSideTapped() {
- ImageViewTouch image = getView().findViewById(R.id.comic_image);
-
- if (image != null) {
- boolean atRightEdge = !image.canScroll(-1);
-
- if (atRightEdge) {
- m_activity.selectNextComic();
- }
+ if (m_prefs.getBoolean("fit_to_width", false)) {
+ m_image.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
- }
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
-
- //setThumbnail(!isVisibleToUser); disabled
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- m_prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
- m_activity = (ViewComicActivity) activity;
-
- m_detector = new GestureDetector(m_activity, new GestureDetector.OnGestureListener() {
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- int width = getView().getWidth();
- int x = Math.round(e.getX());
-
- if (x <= width/10) {
- onLeftSideTapped();
-
- return true;
- } else if (x >= width-(width/10)) {
- onRightSideTapped();
-
- return true;
- }
-
- return false;
- }
-
+ m_image.setOnViewTapListener(new OnViewTapListener() {
@Override
- public void onShowPress(MotionEvent e) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
- float distanceY) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean onDown(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- });
-
- m_detector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
-
- int width = getView().getWidth();
- int x = Math.round(e.getX());
+ public void onViewTap(View view, float x, float y) {
+ int width = view.getWidth();
boolean fullScreenMode = m_prefs.getBoolean("use_full_screen", false);
- if (x > width/10 && x < width-(width/10)) {
+ if (x <= width / 10) {
+ m_activity.selectPreviousComic();
+ } else if (x > width-(width/10)) {
+ m_activity.selectNextComic();
+ } else {
ActionBar bar = m_activity.getSupportActionBar();
if (bar.isShowing()) {
@@ -205,24 +94,25 @@ public class ComicFragment extends StateSavedFragment {
bar.show();
}
-
- return true;
}
-
- return false;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- return false;
- }
-
- @Override
- public boolean onDoubleTapEvent(MotionEvent e) {
- return false;
}
});
+ return view;
+
+ }
+
+ @Override
+ public void setUserVisibleHint(boolean isVisibleToUser) {
+ super.setUserVisibleHint(isVisibleToUser);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
+ m_activity = (ViewComicActivity) activity;
}
}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
index 96ddf78..f94b14a 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
@@ -4,12 +4,9 @@ import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
-import android.support.v4.widget.SimpleCursorAdapter;
-import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -18,7 +15,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
@@ -34,6 +30,8 @@ import com.nhaarman.listviewanimations.appearance.simple.ScaleInAnimationAdapter
import java.io.File;
+import androidx.cursoradapter.widget.SimpleCursorAdapter;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import icepick.State;
import jp.co.recruit_mp.android.widget.HeaderFooterGridView;
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
index 08c52ce..738d810 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
@@ -6,10 +6,6 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v7.app.ActionBar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,10 +17,14 @@ import com.ToxicBakery.viewpager.transforms.DepthPageTransformer;
import org.fox.ttcomics2.archive.CbrComicArchive;
import org.fox.ttcomics2.archive.CbzComicArchive;
import org.fox.ttcomics2.archive.ComicArchive;
-import org.fox.ttcomics2.utils.IVTViewPager;
import java.io.IOException;
+import androidx.appcompat.app.ActionBar;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.viewpager.widget.ViewPager;
import icepick.State;
public class ComicPager extends StateSavedFragment {
@@ -84,7 +84,7 @@ public class ComicPager extends StateSavedFragment {
}
public int getPosition() {
- IVTViewPager pager = getView().findViewById(R.id.comics_pager);
+ ViewPager pager = getView().findViewById(R.id.comics_pager);
if (pager != null) {
return pager.getCurrentItem();
@@ -94,7 +94,7 @@ public class ComicPager extends StateSavedFragment {
}
public void setCurrentItem(int item) {
- IVTViewPager pager = getView().findViewById(R.id.comics_pager);
+ ViewPager pager = getView().findViewById(R.id.comics_pager);
if (pager != null) {
try {
@@ -120,7 +120,7 @@ public class ComicPager extends StateSavedFragment {
m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager());
- final IVTViewPager pager = view.findViewById(R.id.comics_pager);
+ final ViewPager pager = view.findViewById(R.id.comics_pager);
try {
if (m_fileName.toLowerCase().matches(".*\\.(cbz|zip)")) {
@@ -187,7 +187,8 @@ public class ComicPager extends StateSavedFragment {
e.printStackTrace();
}
- pager.setOnPageChangeListener(new IVTViewPager.OnPageChangeListener() {
+ pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
public void onPageSelected(int position) {
m_activity.onComicSelected(m_fileName, position);
@@ -200,11 +201,13 @@ public class ComicPager extends StateSavedFragment {
hideReadingUI(true);
}
-
+
+ @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
-
+
+ @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
index f4bbcd8..ede3cd0 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
@@ -7,13 +7,11 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.JobIntentService;
-import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
+import com.google.android.material.snackbar.Snackbar;
import com.livefront.bridge.Bridge;
import org.fox.ttcomics2.sync.SyncClient;
@@ -23,6 +21,9 @@ import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.JobIntentService;
+
public class CommonActivity extends AppCompatActivity {
private final String TAG = this.getClass().getSimpleName();
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
index 6a19b63..6a62406 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
@@ -15,13 +15,6 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.view.ViewPager;
-import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -37,6 +30,13 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.viewpager.widget.ViewPager;
import icepick.State;
public class MainActivity extends CommonActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PreferencesActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PreferencesActivity.java
index d65ec9a..300e369 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PreferencesActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PreferencesActivity.java
@@ -5,12 +5,13 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
-import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import net.rdrei.android.dirchooser.DirectoryChooserActivity;
import net.rdrei.android.dirchooser.DirectoryChooserConfig;
+import androidx.appcompat.widget.Toolbar;
+
public class PreferencesActivity extends CommonActivity {
@Override
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/StateSavedFragment.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/StateSavedFragment.java
index 023c3dc..840aaf5 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/StateSavedFragment.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/StateSavedFragment.java
@@ -1,10 +1,11 @@
package org.fox.ttcomics2;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import com.livefront.bridge.Bridge;
+import androidx.fragment.app.Fragment;
+
public class StateSavedFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
index 058e091..4733b3f 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
@@ -13,9 +13,6 @@ import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v4.content.FileProvider;
-import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -31,6 +28,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.content.FileProvider;
+import androidx.fragment.app.FragmentTransaction;
import icepick.State;
public class ViewComicActivity extends CommonActivity {
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CacheCleanupService.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CacheCleanupService.java
index d68e039..871b026 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CacheCleanupService.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CacheCleanupService.java
@@ -2,7 +2,6 @@ package org.fox.ttcomics2.utils;
import android.content.Intent;
import android.os.Environment;
-import android.support.v4.app.JobIntentService;
import android.util.Log;
import org.fox.ttcomics2.CommonActivity;
@@ -12,6 +11,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import androidx.core.app.JobIntentService;
+
public class CacheCleanupService extends JobIntentService {
private final String TAG = this.getClass().getSimpleName();
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CompatListActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CompatListActivity.java
deleted file mode 100644
index 2e04b2a..0000000
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/CompatListActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.fox.ttcomics2.utils;
-
-import android.support.v7.app.AppCompatActivity;
-import android.widget.HeaderViewListAdapter;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-
-// http://stackoverflow.com/questions/18403647/actionbaractivity-of-android-support-v7-appcompat-and-listactivity-in-same-act
-
-public abstract class CompatListActivity extends AppCompatActivity {
-
- private ListView mListView;
-
- protected ListView getListView() {
- if (mListView == null) {
- mListView = (ListView) findViewById(android.R.id.list);
- }
- return mListView;
- }
-
- protected void setListAdapter(ListAdapter adapter) {
- getListView().setAdapter(adapter);
- }
-
- protected ListAdapter getListAdapter() {
- ListAdapter adapter = getListView().getAdapter();
- if (adapter instanceof HeaderViewListAdapter) {
- return ((HeaderViewListAdapter)adapter).getWrappedAdapter();
- } else {
- return adapter;
- }
- }
-}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/IVTViewPager.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/IVTViewPager.java
deleted file mode 100644
index 814c4f2..0000000
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/utils/IVTViewPager.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.fox.ttcomics2.utils;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import it.sephiroth.android.library.imagezoom.ImageViewTouch;
-
-public class IVTViewPager extends android.support.v4.view.ViewPager {
- public IVTViewPager(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
- if (v instanceof ImageViewTouch) {
- ImageViewTouch ivt = (ImageViewTouch) v;
- try {
- return ivt.canScroll(dx);
- } catch (NullPointerException e) {
- // bad image, etc
- return false;
- }
- } else {
- return super.canScroll(v, checkV, dx, x, y);
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- return super.onTouchEvent(event);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return super.onInterceptTouchEvent(event);
- }
-} \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/res/layout/activity_main.xml b/org.fox.ttcomics/src/main/res/layout/activity_main.xml
index ad62a46..6a6ddb2 100755
--- a/org.fox.ttcomics/src/main/res/layout/activity_main.xml
+++ b/org.fox.ttcomics/src/main/res/layout/activity_main.xml
@@ -11,12 +11,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <android.support.v4.view.ViewPager
+ <androidx.viewpager.widget.ViewPager
android:id="@+id/comics_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <android.support.v4.view.PagerTitleStrip
+ <androidx.viewpager.widget.PagerTitleStrip
android:id="@+id/comics_pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -26,7 +26,7 @@
android:paddingTop="4dp"
android:textColor="@android:color/white" />
- </android.support.v4.view.ViewPager>
+ </androidx.viewpager.widget.ViewPager>
<com.shamanland.fab.FloatingActionButton
android:id="@+id/fab"
diff --git a/org.fox.ttcomics/src/main/res/layout/comics_grid_row.xml b/org.fox.ttcomics/src/main/res/layout/comics_grid_row.xml
index d030731..66edd74 100755
--- a/org.fox.ttcomics/src/main/res/layout/comics_grid_row.xml
+++ b/org.fox.ttcomics/src/main/res/layout/comics_grid_row.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.CardView
+<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
@@ -83,4 +83,4 @@
</FrameLayout>
</FrameLayout>
- </android.support.v7.widget.CardView> \ No newline at end of file
+ </androidx.cardview.widget.CardView> \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/res/layout/fragment_comic.xml b/org.fox.ttcomics/src/main/res/layout/fragment_comic.xml
index 55c8513..8364fbd 100644..100755
--- a/org.fox.ttcomics/src/main/res/layout/fragment_comic.xml
+++ b/org.fox.ttcomics/src/main/res/layout/fragment_comic.xml
@@ -1,8 +1,9 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/comic_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
- <it.sephiroth.android.library.imagezoom.ImageViewTouch
+ <com.github.chrisbanes.photoview.PhotoView
android:id="@+id/comic_image"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/org.fox.ttcomics/src/main/res/layout/fragment_comics_grid.xml b/org.fox.ttcomics/src/main/res/layout/fragment_comics_grid.xml
index 59d985c..7e34169 100644..100755
--- a/org.fox.ttcomics/src/main/res/layout/fragment_comics_grid.xml
+++ b/org.fox.ttcomics/src/main/res/layout/fragment_comics_grid.xml
@@ -2,7 +2,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent">
- <android.support.v4.widget.SwipeRefreshLayout
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/comics_swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
@@ -13,5 +13,5 @@
android:layout_height="match_parent"
android:columnWidth="160dp"
android:numColumns="auto_fit" />
- </android.support.v4.widget.SwipeRefreshLayout>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout> \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/res/layout/fragment_comics_pager.xml b/org.fox.ttcomics/src/main/res/layout/fragment_comics_pager.xml
index 2feda8b..0730abc 100755
--- a/org.fox.ttcomics/src/main/res/layout/fragment_comics_pager.xml
+++ b/org.fox.ttcomics/src/main/res/layout/fragment_comics_pager.xml
@@ -6,7 +6,7 @@
android:animateLayoutChanges="true"
android:layout_height="fill_parent" >
- <org.fox.ttcomics2.utils.IVTViewPager
+ <androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
diff --git a/org.fox.ttcomics/src/main/res/layout/toolbar.xml b/org.fox.ttcomics/src/main/res/layout/toolbar.xml
index 3f24ba4..8f9ea00 100644..100755
--- a/org.fox.ttcomics/src/main/res/layout/toolbar.xml
+++ b/org.fox.ttcomics/src/main/res/layout/toolbar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.Toolbar
+<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"