├── .gitignore ├── LICENSE ├── PRIVACY.md ├── README.md ├── app ├── .gitignore ├── assets │ ├── butterfly.jpg │ ├── card.png │ ├── kingfisher.jpg │ ├── sanmartino.jpg │ └── swissroad.jpg ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── davemorrissey │ │ └── labs │ │ └── subscaleview │ │ └── sample │ │ ├── AbstractFragmentsFragment.kt │ │ ├── AbstractPagesFragment.kt │ │ ├── MainActivity.kt │ │ ├── Page.kt │ │ ├── animation │ │ └── AnimationFragment.kt │ │ ├── basicfeatures │ │ └── BasicFeaturesFragment.kt │ │ ├── configuration │ │ └── ConfigurationFragment.kt │ │ ├── eventhandling │ │ └── EventHandlingFragment.kt │ │ ├── eventhandlingadvanced │ │ └── AdvancedEventHandlingFragment.kt │ │ ├── extension │ │ ├── ExtensionCircleFragment.kt │ │ ├── ExtensionFragment.kt │ │ ├── ExtensionFreehandFragment.kt │ │ ├── ExtensionPinFragment.kt │ │ └── views │ │ │ ├── CircleView.kt │ │ │ ├── FreehandView.kt │ │ │ └── PinView.kt │ │ ├── imagedisplay │ │ ├── ImageDisplayFragment.kt │ │ ├── ImageDisplayLargeFragment.kt │ │ ├── ImageDisplayRegionFragment.kt │ │ └── ImageDisplayRotateFragment.kt │ │ └── viewpager │ │ ├── VerticalViewPager.kt │ │ ├── ViewPagerFragment.kt │ │ └── ViewPagersFragment.kt │ └── res │ ├── color │ └── menu_text.xml │ ├── drawable-hdpi │ ├── ic_apps_black_24dp.png │ ├── ic_crop_rotate_black_24dp.png │ ├── ic_face_black_24dp.png │ ├── ic_layers_black_24dp.png │ ├── ic_navigate_before_white_36dp.png │ ├── ic_navigate_next_white_36dp.png │ ├── ic_play_arrow_white_36dp.png │ ├── ic_play_circle_outline_black_24dp.png │ ├── ic_rotate_right_white_36dp.png │ ├── ic_settings_backup_restore_white_36dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_terrain_black_24dp.png │ └── ic_touch_app_black_24dp.png │ ├── drawable-mdpi │ ├── ic_apps_black_24dp.png │ ├── ic_crop_rotate_black_24dp.png │ ├── ic_face_black_24dp.png │ ├── ic_layers_black_24dp.png │ ├── ic_navigate_before_white_36dp.png │ ├── ic_navigate_next_white_36dp.png │ ├── ic_play_arrow_white_36dp.png │ ├── ic_play_circle_outline_black_24dp.png │ ├── ic_rotate_right_white_36dp.png │ ├── ic_settings_backup_restore_white_36dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_terrain_black_24dp.png │ └── ic_touch_app_black_24dp.png │ ├── drawable-nodpi │ └── pushpin_green.png │ ├── drawable-xhdpi │ ├── ic_apps_black_24dp.png │ ├── ic_crop_rotate_black_24dp.png │ ├── ic_face_black_24dp.png │ ├── ic_layers_black_24dp.png │ ├── ic_navigate_before_white_36dp.png │ ├── ic_navigate_next_white_36dp.png │ ├── ic_play_arrow_white_36dp.png │ ├── ic_play_circle_outline_black_24dp.png │ ├── ic_rotate_right_white_36dp.png │ ├── ic_settings_backup_restore_white_36dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_terrain_black_24dp.png │ └── ic_touch_app_black_24dp.png │ ├── drawable-xxhdpi │ ├── ic_apps_black_24dp.png │ ├── ic_crop_rotate_black_24dp.png │ ├── ic_face_black_24dp.png │ ├── ic_layers_black_24dp.png │ ├── ic_navigate_before_white_36dp.png │ ├── ic_navigate_next_white_36dp.png │ ├── ic_play_arrow_white_36dp.png │ ├── ic_play_circle_outline_black_24dp.png │ ├── ic_rotate_right_white_36dp.png │ ├── ic_settings_backup_restore_white_36dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_terrain_black_24dp.png │ └── ic_touch_app_black_24dp.png │ ├── drawable-xxxhdpi │ ├── github_black.png │ ├── ic_apps_black_24dp.png │ ├── ic_crop_rotate_black_24dp.png │ ├── ic_face_black_24dp.png │ ├── ic_layers_black_24dp.png │ ├── ic_navigate_before_white_36dp.png │ ├── ic_navigate_next_white_36dp.png │ ├── ic_play_arrow_white_36dp.png │ ├── ic_play_circle_outline_black_24dp.png │ ├── ic_rotate_right_white_36dp.png │ ├── ic_settings_backup_restore_white_36dp.png │ ├── ic_settings_black_24dp.png │ ├── ic_terrain_black_24dp.png │ ├── ic_touch_app_black_24dp.png │ └── launcher_hires.png │ ├── layout │ ├── animation_activity.xml │ ├── extension_circle_fragment.xml │ ├── extension_freehand_fragment.xml │ ├── extension_pin_fragment.xml │ ├── fragments_activity.xml │ ├── imagedisplay_large_fragment.xml │ ├── imagedisplay_region_fragment.xml │ ├── imagedisplay_rotate_fragment.xml │ ├── main.xml │ ├── main_nav_header.xml │ ├── pages_activity.xml │ ├── view_pager.xml │ └── view_pager_page.xml │ ├── menu │ └── navigation.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── docs └── images │ ├── google_play.png │ ├── screenshot1.png │ └── screenshot2.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle files 2 | .gradle/ 3 | build/ 4 | 5 | # Local configuration file (sdk path, etc) 6 | local.properties 7 | 8 | # Android Studio generated folders 9 | .navigation/ 10 | captures/ 11 | .externalNativeBuild 12 | 13 | # IntelliJ project files 14 | *.iml 15 | .idea/ 16 | 17 | # Misc 18 | .DS_Store 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | Scale Image View Demo Privacy Policy 2 | ==================================== 3 | 4 | This is the privacy policy for [Scale Image View Demo in the Google Play Store](https://play.google.com/store/apps/details?id=com.davemorrissey.labs.subscaleview.sample). 5 | 6 | This app does not include any adverts, tracking code, or analytics libraries. It does not send any 7 | information of any kind to the developer or any third party. 8 | 9 | Google and your phone manufacturer may collect information about your use of the app for their own 10 | purposes; what they collect and what they do with this information is not under the developer's 11 | control. Further information may be found in their privacy policies. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Subsampling Scale Image View Sample App 2 | ======================================= 3 | 4 | This is a fork of the sample app for [Subsampling Scale Image View](https://github.com/davemorrissey/subsampling-scale-image-view/), 5 | rewritten in Kotlin. 6 | 7 | I have separated this app from the main repository so it can be used to build a public facing Google Play 8 | app with simple demos, while the main repository version evolves into a demonstration of more complex 9 | setups and serves as a test app. 10 | 11 | Kotlin is used as a learning exercise, and I may make incompatible changes or update to unstable or 12 | pre-release versions of Android build tools so I can experiment with new features. 13 | 14 | ## Download from Google Play 15 | 16 | [![Get it on Google Play](docs/images/google_play.png)](https://play.google.com/store/apps/details?id=com.davemorrissey.labs.subscaleview.sample) 17 | 18 | ## Screenshots 19 | 20 | ![Screenshot 1](docs/images/screenshot1.png) 21 | ![Screenshot 2](docs/images/screenshot2.png) 22 | 23 | ## About 24 | 25 | Copyright 2018 David Morrissey, and licensed under the Apache License, Version 2.0. 26 | 27 | ## Photo credits 28 | 29 | * Kingfisher by Vincent van Zalinge, via [unsplash.com](https://unsplash.com/photos/vUNQaTtZeOo) 30 | * San Martino by Luca Bravo, via [unsplash.com](https://unsplash.com/photos/lWAOc0UuJ-A) 31 | * Swiss Road by Ludovic Fremondiere, via [unsplash.com](https://unsplash.com/photos/3XN-BNRDUyY) 32 | * Butterfly by Boris Smokrovic, via [unsplash.com](https://unsplash.com/photos/BtoUjLUtPnQ) 33 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/assets/butterfly.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/assets/butterfly.jpg -------------------------------------------------------------------------------- /app/assets/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/assets/card.png -------------------------------------------------------------------------------- /app/assets/kingfisher.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/assets/kingfisher.jpg -------------------------------------------------------------------------------- /app/assets/sanmartino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/assets/sanmartino.jpg -------------------------------------------------------------------------------- /app/assets/swissroad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/assets/swissroad.jpg -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 27 7 | defaultConfig { 8 | applicationId "com.davemorrissey.labs.subscaleview.sample" 9 | minSdkVersion 21 10 | targetSdkVersion 27 11 | versionCode 5 12 | versionName "4.0" 13 | } 14 | buildTypes { 15 | release { 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | sourceSets { 20 | main { 21 | assets.srcDirs = ['assets'] 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 29 | implementation "com.android.support:support-compat:$support_version" 30 | implementation "com.android.support:appcompat-v7:$support_version" 31 | implementation "com.android.support:design:$support_version" 32 | implementation "com.android.support:support-v13:$support_version" 33 | implementation "com.android.support:exifinterface:$support_version" 34 | implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' 35 | } 36 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 12 | 15 | 16 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/AbstractFragmentsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample 2 | 3 | import android.app.Fragment 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | abstract class AbstractFragmentsFragment protected constructor(private val title: Int, private val layout: Int, private val notes: List) : Fragment() { 10 | 11 | private var page: Int = 0 12 | 13 | protected abstract fun onPageChanged(page: Int) 14 | 15 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View { 16 | return inflater.inflate(layout, container, false) 17 | } 18 | 19 | override fun onResume() { 20 | super.onResume() 21 | updateNotes() 22 | } 23 | 24 | override fun onViewStateRestored(savedInstanceState: Bundle?) { 25 | super.onViewStateRestored(savedInstanceState) 26 | if (savedInstanceState?.containsKey(BUNDLE_PAGE) == true) { 27 | page = savedInstanceState.getInt(BUNDLE_PAGE) 28 | } 29 | } 30 | 31 | override fun onSaveInstanceState(outState: Bundle?) { 32 | super.onSaveInstanceState(outState) 33 | outState?.putInt(BUNDLE_PAGE, page) 34 | } 35 | 36 | fun next() { 37 | page++ 38 | updateNotes() 39 | } 40 | 41 | fun previous() { 42 | page-- 43 | updateNotes() 44 | } 45 | 46 | private fun updateNotes() { 47 | if (page > notes.size - 1) { 48 | return 49 | } 50 | (activity as MainActivity).setToolbarTitle(title) 51 | (activity as MainActivity).setToolbarSubtitle(notes[page].subtitle) 52 | onPageChanged(page) 53 | } 54 | 55 | companion object { 56 | private const val BUNDLE_PAGE = "page" 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/AbstractPagesFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample 2 | 3 | import android.app.Fragment 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | import kotlinx.android.synthetic.main.pages_activity.next 10 | import kotlinx.android.synthetic.main.pages_activity.previous 11 | import kotlinx.android.synthetic.main.pages_activity.note 12 | 13 | abstract class AbstractPagesFragment protected constructor(private val title: Int, private val layout: Int, private val notes: List) : Fragment() { 14 | 15 | protected var page: Int = 0 16 | private set 17 | 18 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View { 19 | return inflater.inflate(layout, container, false) 20 | } 21 | 22 | override fun onResume() { 23 | super.onResume() 24 | next.setOnClickListener { next() } 25 | previous.setOnClickListener { previous() } 26 | updateNotes() 27 | } 28 | 29 | override fun onViewStateRestored(savedInstanceState: Bundle?) { 30 | super.onViewStateRestored(savedInstanceState) 31 | if (savedInstanceState?.containsKey(BUNDLE_PAGE) == true) { 32 | page = savedInstanceState.getInt(BUNDLE_PAGE) 33 | } 34 | } 35 | 36 | override fun onSaveInstanceState(outState: Bundle?) { 37 | super.onSaveInstanceState(outState) 38 | outState?.putInt(BUNDLE_PAGE, page) 39 | } 40 | 41 | private operator fun next() { 42 | page++ 43 | updateNotes() 44 | } 45 | 46 | private fun previous() { 47 | page-- 48 | updateNotes() 49 | } 50 | 51 | private fun updateNotes() { 52 | if (page > notes.size - 1) { 53 | return 54 | } 55 | (activity as MainActivity).setToolbarTitle(title) 56 | (activity as MainActivity).setToolbarSubtitle(notes[page].subtitle) 57 | note.setText(notes[page].text) 58 | next.visibility = if (page >= notes.size - 1) View.INVISIBLE else View.VISIBLE 59 | previous.visibility = if (page <= 0) View.INVISIBLE else View.VISIBLE 60 | onPageChanged(page) 61 | } 62 | 63 | protected open fun onPageChanged(page: Int) { 64 | 65 | } 66 | 67 | companion object { 68 | private const val BUNDLE_PAGE = "page" 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample 2 | 3 | import android.content.Intent 4 | import android.net.Uri 5 | import android.os.Bundle 6 | 7 | import com.davemorrissey.labs.subscaleview.sample.animation.AnimationFragment 8 | import com.davemorrissey.labs.subscaleview.sample.configuration.ConfigurationFragment 9 | import com.davemorrissey.labs.subscaleview.sample.eventhandling.EventHandlingFragment 10 | import com.davemorrissey.labs.subscaleview.sample.eventhandlingadvanced.AdvancedEventHandlingFragment 11 | import com.davemorrissey.labs.subscaleview.sample.extension.ExtensionFragment 12 | import com.davemorrissey.labs.subscaleview.sample.imagedisplay.ImageDisplayFragment 13 | import com.davemorrissey.labs.subscaleview.sample.viewpager.ViewPagersFragment 14 | 15 | import kotlinx.android.synthetic.main.main.* 16 | import android.support.v7.app.ActionBarDrawerToggle 17 | import android.support.v7.app.AppCompatActivity 18 | import com.davemorrissey.labs.subscaleview.sample.basicfeatures.BasicFeaturesFragment 19 | 20 | class MainActivity : AppCompatActivity() { 21 | 22 | private var fragmentId: Int = R.id.basicFeatures 23 | 24 | override fun onCreate(savedInstanceState: Bundle?) { 25 | super.onCreate(savedInstanceState) 26 | setContentView(R.layout.main) 27 | setSupportActionBar(toolbar) 28 | initNavigationDrawer() 29 | if (savedInstanceState?.containsKey(BUNDLE_FRAGMENT) == true) { 30 | fragmentId = savedInstanceState.getInt(BUNDLE_FRAGMENT) 31 | } 32 | setFragment(fragmentId) 33 | } 34 | 35 | override fun onSaveInstanceState(outState: Bundle?) { 36 | super.onSaveInstanceState(outState) 37 | outState?.putInt(BUNDLE_FRAGMENT, fragmentId) 38 | } 39 | 40 | fun setToolbarTitle(title: Int) { 41 | toolbar?.setTitle(title) 42 | } 43 | 44 | fun setToolbarSubtitle(subtitle: Int) { 45 | toolbar?.setSubtitle(subtitle) 46 | } 47 | 48 | private fun initNavigationDrawer() { 49 | navigationView.setCheckedItem(R.id.basicFeatures) 50 | navigationView.setNavigationItemSelectedListener { menuItem -> 51 | drawerLayout.closeDrawers() 52 | when (menuItem.itemId) { 53 | R.id.basicFeatures, 54 | R.id.imageDisplay, 55 | R.id.eventHandling, 56 | R.id.advancedEventHandling, 57 | R.id.viewPagerGalleries, 58 | R.id.animation, 59 | R.id.extension, 60 | R.id.configuration -> setFragment(menuItem.itemId) 61 | R.id.github -> openGitHub() 62 | R.id.self -> openSelf() 63 | } 64 | true 65 | } 66 | val actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) 67 | drawerLayout.addDrawerListener(actionBarDrawerToggle) 68 | actionBarDrawerToggle.syncState() 69 | } 70 | 71 | private fun setFragment(id: Int) { 72 | fragmentId = id 73 | val fragmentClass = when(id) { 74 | R.id.basicFeatures -> BasicFeaturesFragment::class.java 75 | R.id.imageDisplay -> ImageDisplayFragment::class.java 76 | R.id.eventHandling -> EventHandlingFragment::class.java 77 | R.id.advancedEventHandling -> AdvancedEventHandlingFragment::class.java 78 | R.id.viewPagerGalleries -> ViewPagersFragment::class.java 79 | R.id.animation -> AnimationFragment::class.java 80 | R.id.configuration -> ConfigurationFragment::class.java 81 | R.id.extension -> ExtensionFragment::class.java 82 | else -> BasicFeaturesFragment::class.java 83 | } 84 | val existingFragment = fragmentManager.findFragmentByTag("ROOT") 85 | if (existingFragment?.javaClass != fragmentClass) { 86 | fragmentManager.beginTransaction() 87 | .replace(R.id.content, fragmentClass.newInstance(), "ROOT") 88 | .commit() 89 | } 90 | } 91 | 92 | private fun openGitHub() { 93 | val i = Intent(Intent.ACTION_VIEW) 94 | i.data = Uri.parse("https://github.com/davemorrissey/subsampling-scale-image-view") 95 | startActivity(i) 96 | } 97 | 98 | private fun openSelf() { 99 | val i = Intent(Intent.ACTION_VIEW) 100 | i.data = Uri.parse("http://www.davemorrissey.com") 101 | startActivity(i) 102 | } 103 | 104 | override fun onBackPressed() { 105 | moveTaskToBack(true) 106 | } 107 | 108 | companion object { 109 | private const val BUNDLE_FRAGMENT = "FRAGMENT" 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/Page.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample 2 | 3 | class Page(val subtitle: Int, val text: Int) 4 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/animation/AnimationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.animation 2 | 3 | import android.graphics.PointF 4 | import android.os.Bundle 5 | import android.view.View 6 | 7 | import com.davemorrissey.labs.subscaleview.ImageSource 8 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 9 | import com.davemorrissey.labs.subscaleview.sample.Page 10 | 11 | import java.util.Arrays 12 | import java.util.Random 13 | 14 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.* 15 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 16 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 17 | 18 | import kotlinx.android.synthetic.main.animation_activity.play 19 | import kotlinx.android.synthetic.main.animation_activity.imageView 20 | 21 | class AnimationFragment : AbstractPagesFragment(animation_title, animation_activity, Arrays.asList( 22 | Page(animation_p1_subtitle, animation_p1_text), 23 | Page(animation_p2_subtitle, animation_p2_text), 24 | Page(animation_p3_subtitle, animation_p3_text), 25 | Page(animation_p4_subtitle, animation_p4_text) 26 | )) { 27 | 28 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 29 | super.onViewCreated(view, savedInstanceState) 30 | play.setOnClickListener { play() } 31 | imageView.setImage(ImageSource.asset("kingfisher.jpg")) 32 | } 33 | 34 | override fun onPageChanged(page: Int) { 35 | imageView.setPanLimit(if (page == 2) PAN_LIMIT_CENTER else PAN_LIMIT_INSIDE) 36 | } 37 | 38 | private fun play() { 39 | val random = Random() 40 | if (imageView.isReady) { 41 | val maxScale = imageView.maxScale 42 | val minScale = imageView.minScale 43 | val scale = random.nextFloat() * (maxScale - minScale) + minScale 44 | val center = PointF(random.nextInt(imageView.sWidth).toFloat(), random.nextInt(imageView.sHeight).toFloat()) 45 | imageView.setPin(center) 46 | imageView.animateScaleAndCenter(scale, center)?.apply { 47 | if (page == 3) { 48 | withDuration(2000) 49 | withEasing(EASE_OUT_QUAD) 50 | withInterruptible(false) 51 | } else { 52 | withDuration(750) 53 | } 54 | start() 55 | } 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/basicfeatures/BasicFeaturesFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.basicfeatures 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | 6 | import com.davemorrissey.labs.subscaleview.ImageSource 7 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 8 | import com.davemorrissey.labs.subscaleview.sample.Page 9 | 10 | import java.util.Arrays 11 | 12 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 13 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 14 | 15 | import kotlinx.android.synthetic.main.pages_activity.imageView 16 | 17 | class BasicFeaturesFragment : AbstractPagesFragment(basic_title, pages_activity, Arrays.asList( 18 | Page(basic_p1_subtitle, basic_p1_text), 19 | Page(basic_p2_subtitle, basic_p2_text), 20 | Page(basic_p3_subtitle, basic_p3_text), 21 | Page(basic_p4_subtitle, basic_p4_text), 22 | Page(basic_p5_subtitle, basic_p5_text) 23 | )) { 24 | 25 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | imageView.setImage(ImageSource.asset("kingfisher.jpg")) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/configuration/ConfigurationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.configuration 2 | 3 | import android.graphics.PointF 4 | import android.os.Bundle 5 | import android.view.View 6 | 7 | import com.davemorrissey.labs.subscaleview.ImageSource 8 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.* 9 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 10 | import com.davemorrissey.labs.subscaleview.sample.Page 11 | 12 | import java.util.Arrays 13 | 14 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 15 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 16 | 17 | import kotlinx.android.synthetic.main.pages_activity.imageView 18 | 19 | class ConfigurationFragment : AbstractPagesFragment(configuration_title, pages_activity, Arrays.asList( 20 | Page(configuration_p1_subtitle, configuration_p1_text), 21 | Page(configuration_p2_subtitle, configuration_p2_text), 22 | Page(configuration_p3_subtitle, configuration_p3_text), 23 | Page(configuration_p4_subtitle, configuration_p4_text), 24 | Page(configuration_p5_subtitle, configuration_p5_text), 25 | Page(configuration_p6_subtitle, configuration_p6_text), 26 | Page(configuration_p7_subtitle, configuration_p7_text), 27 | Page(configuration_p8_subtitle, configuration_p8_text), 28 | Page(configuration_p9_subtitle, configuration_p9_text), 29 | Page(configuration_p10_subtitle, configuration_p10_text) 30 | )) { 31 | 32 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 33 | super.onCreate(savedInstanceState) 34 | imageView.setImage(ImageSource.asset("sanmartino.jpg")) 35 | } 36 | 37 | override fun onPageChanged(page: Int) { 38 | imageView.apply { 39 | when (page) { 40 | 0 -> setMinimumDpi(50) 41 | else -> maxScale = 2f 42 | } 43 | setMinimumTileDpi(when (page) { 44 | 1 -> 50 45 | else -> 500 46 | }) 47 | setDoubleTapZoomStyle(when (page) { 48 | 4 -> ZOOM_FOCUS_CENTER 49 | 5 -> ZOOM_FOCUS_CENTER_IMMEDIATE 50 | else -> ZOOM_FOCUS_FIXED 51 | }) 52 | when (page) { 53 | 6 -> setDoubleTapZoomDpi(240) 54 | else -> setDoubleTapZoomScale(1f) 55 | } 56 | setPanLimit(when (page) { 57 | 7 -> PAN_LIMIT_CENTER 58 | 8 -> PAN_LIMIT_OUTSIDE 59 | else -> PAN_LIMIT_INSIDE 60 | }) 61 | setDebug(page == 9) 62 | isPanEnabled = page != 2 63 | isZoomEnabled = page != 3 64 | if (page == 2) { 65 | setScaleAndCenter(0f, PointF(2456f, 1632f)) 66 | } else if (page == 3) { 67 | setScaleAndCenter(1f, PointF(2456f, 1632f)) 68 | } 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/eventhandling/EventHandlingFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.eventhandling 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import android.widget.Toast 6 | 7 | import com.davemorrissey.labs.subscaleview.ImageSource 8 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 9 | import com.davemorrissey.labs.subscaleview.sample.Page 10 | 11 | import java.util.Arrays 12 | 13 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 14 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 15 | 16 | import kotlinx.android.synthetic.main.pages_activity.imageView 17 | 18 | class EventHandlingFragment : AbstractPagesFragment(event_title, pages_activity, Arrays.asList( 19 | Page(event_p1_subtitle, event_p1_text), 20 | Page(event_p2_subtitle, event_p2_text), 21 | Page(event_p3_subtitle, event_p3_text) 22 | )) { 23 | 24 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 25 | super.onCreate(savedInstanceState) 26 | imageView.setImage(ImageSource.asset("swissroad.jpg")) 27 | imageView.setOnClickListener { v -> Toast.makeText(v.context, "Clicked", Toast.LENGTH_SHORT).show() } 28 | imageView.setOnLongClickListener { v -> 29 | Toast.makeText(v.context, "Long clicked", Toast.LENGTH_SHORT).show() 30 | true 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/eventhandlingadvanced/AdvancedEventHandlingFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.eventhandlingadvanced 2 | 3 | import android.os.Bundle 4 | import android.view.GestureDetector 5 | import android.view.MotionEvent 6 | import android.view.View 7 | import android.widget.Toast 8 | 9 | import com.davemorrissey.labs.subscaleview.ImageSource 10 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 11 | import com.davemorrissey.labs.subscaleview.sample.Page 12 | 13 | import java.util.Arrays 14 | 15 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 16 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 17 | 18 | import kotlinx.android.synthetic.main.pages_activity.imageView 19 | 20 | class AdvancedEventHandlingFragment : AbstractPagesFragment(advancedevent_title, pages_activity, Arrays.asList( 21 | Page(advancedevent_p1_subtitle, advancedevent_p1_text), 22 | Page(advancedevent_p2_subtitle, advancedevent_p2_text), 23 | Page(advancedevent_p3_subtitle, advancedevent_p3_text), 24 | Page(advancedevent_p4_subtitle, advancedevent_p4_text), 25 | Page(advancedevent_p5_subtitle, advancedevent_p5_text) 26 | )) { 27 | 28 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 29 | super.onCreate(savedInstanceState) 30 | val gestureDetector = GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() { 31 | override fun onSingleTapConfirmed(e: MotionEvent): Boolean { 32 | imageView.viewToSourceCoord(e.x, e.y)?.let { 33 | toast("Single tap: ${it.x.toInt()}, ${it.y.toInt()}") 34 | } ?: run { 35 | toast("Single tap: Image not ready") 36 | } 37 | return true 38 | } 39 | 40 | override fun onLongPress(e: MotionEvent) { 41 | imageView.viewToSourceCoord(e.x, e.y)?.let { 42 | toast("Long press: ${it.x.toInt()}, ${it.y.toInt()}") 43 | } ?: run { 44 | toast("Long press: Image not ready") 45 | } 46 | } 47 | 48 | override fun onDoubleTap(e: MotionEvent): Boolean { 49 | imageView.viewToSourceCoord(e.x, e.y)?.let { 50 | toast("Double tap: ${it.x.toInt()}, ${it.y.toInt()}") 51 | } ?: run { 52 | toast("Double tap: Image not ready") 53 | } 54 | return true 55 | } 56 | }) 57 | 58 | imageView.setImage(ImageSource.asset("butterfly.jpg")) 59 | imageView.setOnTouchListener { _, motionEvent -> gestureDetector.onTouchEvent(motionEvent) } 60 | } 61 | 62 | private fun toast(text: String) { 63 | Toast.makeText(activity, text, Toast.LENGTH_SHORT).show() 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/ExtensionCircleFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension 2 | 3 | import android.os.Bundle 4 | import android.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | import com.davemorrissey.labs.subscaleview.ImageSource 10 | import com.davemorrissey.labs.subscaleview.sample.R.layout 11 | 12 | import kotlinx.android.synthetic.main.extension_circle_fragment.next 13 | import kotlinx.android.synthetic.main.extension_circle_fragment.previous 14 | import kotlinx.android.synthetic.main.extension_circle_fragment.imageView 15 | 16 | class ExtensionCircleFragment : Fragment() { 17 | 18 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 19 | return inflater!!.inflate(layout.extension_circle_fragment, container, false) 20 | } 21 | 22 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 23 | super.onViewCreated(view, savedInstanceState) 24 | next.setOnClickListener { (parentFragment as ExtensionFragment).next() } 25 | previous.setOnClickListener { (parentFragment as ExtensionFragment).previous() } 26 | imageView.setImage(ImageSource.asset("sanmartino.jpg")) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/ExtensionFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension 2 | 3 | import android.util.Log 4 | 5 | import com.davemorrissey.labs.subscaleview.sample.AbstractFragmentsFragment 6 | import com.davemorrissey.labs.subscaleview.sample.Page 7 | import com.davemorrissey.labs.subscaleview.sample.R 8 | import com.davemorrissey.labs.subscaleview.sample.imagedisplay.ImageDisplayFragment 9 | 10 | import java.util.Arrays 11 | 12 | import com.davemorrissey.labs.subscaleview.sample.R.layout.fragments_activity 13 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p1_subtitle 14 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p1_text 15 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p2_subtitle 16 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p2_text 17 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p3_subtitle 18 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_p3_text 19 | import com.davemorrissey.labs.subscaleview.sample.R.string.extension_title 20 | 21 | class ExtensionFragment : AbstractFragmentsFragment(extension_title, fragments_activity, Arrays.asList( 22 | Page(extension_p1_subtitle, extension_p1_text), 23 | Page(extension_p2_subtitle, extension_p2_text), 24 | Page(extension_p3_subtitle, extension_p3_text) 25 | )) { 26 | 27 | override fun onPageChanged(page: Int) { 28 | try { 29 | childFragmentManager 30 | .beginTransaction() 31 | .replace(R.id.frame, FRAGMENTS[page].newInstance(), "CHILD") 32 | .commit() 33 | } catch (e: Exception) { 34 | Log.e(ImageDisplayFragment::class.java.name, "Failed to load fragment", e) 35 | } 36 | } 37 | 38 | companion object { 39 | private val FRAGMENTS = Arrays.asList( 40 | ExtensionPinFragment::class.java, 41 | ExtensionCircleFragment::class.java, 42 | ExtensionFreehandFragment::class.java 43 | ) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/ExtensionFreehandFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension 2 | 3 | import android.os.Bundle 4 | import android.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | import com.davemorrissey.labs.subscaleview.ImageSource 10 | import com.davemorrissey.labs.subscaleview.sample.R.layout 11 | 12 | import kotlinx.android.synthetic.main.extension_freehand_fragment.previous 13 | import kotlinx.android.synthetic.main.extension_freehand_fragment.reset 14 | import kotlinx.android.synthetic.main.extension_freehand_fragment.imageView 15 | 16 | class ExtensionFreehandFragment : Fragment() { 17 | 18 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 19 | return inflater!!.inflate(layout.extension_freehand_fragment, container, false) 20 | } 21 | 22 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 23 | super.onViewCreated(view, savedInstanceState) 24 | previous.setOnClickListener { (parentFragment as ExtensionFragment).previous() } 25 | imageView.setImage(ImageSource.asset("butterfly.jpg")) 26 | reset.setOnClickListener { imageView.reset() } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/ExtensionPinFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension 2 | 3 | import android.graphics.PointF 4 | import android.os.Bundle 5 | import android.app.Fragment 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | 10 | import com.davemorrissey.labs.subscaleview.ImageSource 11 | import com.davemorrissey.labs.subscaleview.sample.R.layout 12 | 13 | import kotlinx.android.synthetic.main.extension_pin_fragment.next 14 | import kotlinx.android.synthetic.main.extension_pin_fragment.imageView 15 | 16 | class ExtensionPinFragment : Fragment() { 17 | 18 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 19 | return inflater!!.inflate(layout.extension_pin_fragment, container, false) 20 | } 21 | 22 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 23 | super.onViewCreated(view, savedInstanceState) 24 | next.setOnClickListener { (parentFragment as ExtensionFragment).next() } 25 | imageView.setImage(ImageSource.asset("kingfisher.jpg")) 26 | imageView.setPin(PointF(565f, 1465f)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/views/CircleView.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension.views 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.graphics.Paint.Cap 6 | import android.graphics.Paint.Style 7 | import android.util.AttributeSet 8 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView 9 | 10 | class CircleView @JvmOverloads constructor(context: Context, attr: AttributeSet? = null) : SubsamplingScaleImageView(context, attr) { 11 | 12 | private var strokeWidth: Int = 0 13 | 14 | private val sCenter = PointF() 15 | private val vCenter = PointF() 16 | private val paint = Paint() 17 | 18 | init { 19 | initialise() 20 | } 21 | 22 | private fun initialise() { 23 | val density = resources.displayMetrics.densityDpi.toFloat() 24 | strokeWidth = (density / 60f).toInt() 25 | } 26 | 27 | override fun onDraw(canvas: Canvas) { 28 | super.onDraw(canvas) 29 | 30 | // Don't draw pin before image is ready so it doesn't move around during setup. 31 | if (!isReady) return 32 | 33 | sCenter.set((sWidth / 2).toFloat(), (sHeight / 2).toFloat()) 34 | sourceToViewCoord(sCenter, vCenter) 35 | val radius = scale * sWidth * 0.25f 36 | 37 | paint.isAntiAlias = true 38 | paint.style = Style.STROKE 39 | paint.strokeCap = Cap.ROUND 40 | paint.strokeWidth = (strokeWidth * 2).toFloat() 41 | paint.color = Color.BLACK 42 | canvas.drawCircle(vCenter.x, vCenter.y, radius, paint) 43 | paint.strokeWidth = strokeWidth.toFloat() 44 | paint.color = Color.argb(255, 38, 166, 154) 45 | canvas.drawCircle(vCenter.x, vCenter.y, radius, paint) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/views/FreehandView.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension.views 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.graphics.Paint.Cap 6 | import android.graphics.Paint.Style 7 | import android.util.AttributeSet 8 | import android.view.MotionEvent 9 | import android.view.View 10 | import android.view.View.OnTouchListener 11 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView 12 | 13 | class FreehandView @JvmOverloads constructor(context: Context, attr: AttributeSet? = null) : SubsamplingScaleImageView(context, attr), OnTouchListener { 14 | 15 | private val paint = Paint() 16 | private val vPath = Path() 17 | private val vPoint = PointF() 18 | private var vPrev = PointF() 19 | private var vPrevious: PointF? = null 20 | private var sStart: PointF? = null 21 | private var drawing = false 22 | 23 | private var strokeWidth: Int = 0 24 | 25 | private val sPoints: MutableList = mutableListOf() 26 | 27 | init { 28 | initialise() 29 | } 30 | 31 | private fun initialise() { 32 | setOnTouchListener(this) 33 | val density = resources.displayMetrics.densityDpi.toFloat() 34 | strokeWidth = (density / 60f).toInt() 35 | } 36 | 37 | override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { 38 | return false 39 | } 40 | 41 | override fun onTouchEvent(event: MotionEvent): Boolean { 42 | if (sPoints.isNotEmpty() && !drawing) { 43 | return super.onTouchEvent(event) 44 | } 45 | var consumed = false 46 | val touchCount = event.pointerCount 47 | when (event.actionMasked) { 48 | MotionEvent.ACTION_DOWN -> if (event.actionIndex == 0) { 49 | sStart = viewToSourceCoord(event.x, event.y) 50 | vPrevious = PointF(event.x, event.y) 51 | } else { 52 | sStart = null 53 | vPrevious = null 54 | } 55 | MotionEvent.ACTION_MOVE -> { 56 | val sCurrentF = viewToSourceCoord(event.x, event.y) 57 | if (sCurrentF != null) { 58 | val sCurrent = PointF(sCurrentF.x, sCurrentF.y) 59 | 60 | val sStart = this.sStart 61 | val vPrevious = this.vPrevious 62 | if (touchCount == 1 && sStart != null && vPrevious != null) { 63 | val vDX = Math.abs(event.x - vPrevious.x) 64 | val vDY = Math.abs(event.y - vPrevious.y) 65 | if (vDX >= strokeWidth || vDY >= strokeWidth) { 66 | if (sPoints.isEmpty()) { 67 | sPoints.add(sStart) 68 | } 69 | sPoints.add(sCurrent) 70 | vPrevious.x = event.x 71 | vPrevious.y = event.y 72 | drawing = true 73 | } 74 | consumed = true 75 | invalidate() 76 | } else if (touchCount == 1) { 77 | // Consume all one touch drags to prevent odd panning effects handled by the superclass. 78 | consumed = true 79 | } 80 | } 81 | } 82 | MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> { 83 | invalidate() 84 | drawing = false 85 | vPrevious = null 86 | sStart = null 87 | } 88 | } 89 | // Use parent to handle pinch and two-finger pan. 90 | return consumed || super.onTouchEvent(event) 91 | } 92 | 93 | override fun onDraw(canvas: Canvas) { 94 | super.onDraw(canvas) 95 | 96 | // Don't draw anything before image is ready. 97 | if (!isReady) { 98 | return 99 | } 100 | 101 | paint.isAntiAlias = true 102 | 103 | if (sPoints.size >= 2) { 104 | vPath.reset() 105 | sourceToViewCoord(sPoints[0].x, sPoints[0].y, vPrev) 106 | vPath.moveTo(vPrev.x, vPrev.y) 107 | for (i in 1 until sPoints.size) { 108 | sourceToViewCoord(sPoints[i].x, sPoints[i].y, vPoint) 109 | vPath.quadTo(vPrev.x, vPrev.y, (vPoint.x + vPrev.x) / 2, (vPoint.y + vPrev.y) / 2) 110 | vPrev = vPoint 111 | } 112 | paint.style = Style.STROKE 113 | paint.strokeCap = Cap.ROUND 114 | paint.strokeWidth = (strokeWidth * 2).toFloat() 115 | paint.color = Color.BLACK 116 | canvas.drawPath(vPath, paint) 117 | paint.strokeWidth = strokeWidth.toFloat() 118 | paint.color = Color.argb(255, 38, 166, 154) 119 | canvas.drawPath(vPath, paint) 120 | } 121 | 122 | } 123 | 124 | fun reset() { 125 | this.sPoints.clear() 126 | invalidate() 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/extension/views/PinView.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.extension.views 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.util.AttributeSet 6 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView 7 | import com.davemorrissey.labs.subscaleview.sample.R.drawable 8 | 9 | 10 | class PinView @JvmOverloads constructor(context: Context, attr: AttributeSet? = null) : SubsamplingScaleImageView(context, attr) { 11 | 12 | private val paint = Paint() 13 | private val vPin = PointF() 14 | private var sPin: PointF? = null 15 | private var pin: Bitmap 16 | 17 | init { 18 | val density = resources.displayMetrics.densityDpi.toFloat() 19 | val bitmap = BitmapFactory.decodeResource(this.resources, drawable.pushpin_green) 20 | val w = density / 420f * bitmap.width 21 | val h = density / 420f * bitmap.height 22 | pin = Bitmap.createScaledBitmap(bitmap, w.toInt(), h.toInt(), true) 23 | } 24 | 25 | fun setPin(sPin: PointF) { 26 | this.sPin = sPin 27 | invalidate() 28 | } 29 | 30 | override fun onDraw(canvas: Canvas) { 31 | super.onDraw(canvas) 32 | 33 | // Don't draw pin before image is ready so it doesn't move around during setup. 34 | if (!isReady) return 35 | 36 | paint.isAntiAlias = true 37 | 38 | if (sPin != null) { 39 | sourceToViewCoord(sPin, vPin) 40 | val vX = vPin.x - pin.width / 2 41 | val vY = vPin.y - pin.height 42 | canvas.drawBitmap(pin, vX, vY, paint) 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.imagedisplay 2 | 3 | import android.util.Log 4 | 5 | import com.davemorrissey.labs.subscaleview.sample.AbstractFragmentsFragment 6 | import com.davemorrissey.labs.subscaleview.sample.Page 7 | import com.davemorrissey.labs.subscaleview.sample.R 8 | 9 | import java.util.Arrays 10 | 11 | import com.davemorrissey.labs.subscaleview.sample.R.string.* 12 | import com.davemorrissey.labs.subscaleview.sample.R.layout.* 13 | 14 | class ImageDisplayFragment : AbstractFragmentsFragment(display_title, fragments_activity, Arrays.asList( 15 | Page(display_p1_subtitle, display_p1_text), 16 | Page(display_p2_subtitle, display_p2_text), 17 | Page(display_p3_subtitle, display_p3_text) 18 | )) { 19 | 20 | override fun onPageChanged(page: Int) { 21 | try { 22 | childFragmentManager 23 | .beginTransaction() 24 | .replace(R.id.frame, FRAGMENTS[page].newInstance()) 25 | .commit() 26 | } catch (e: Exception) { 27 | Log.e(ImageDisplayFragment::class.java.name, "Failed to load fragment", e) 28 | } 29 | } 30 | 31 | companion object { 32 | private val FRAGMENTS = Arrays.asList( 33 | ImageDisplayLargeFragment::class.java, 34 | ImageDisplayRotateFragment::class.java, 35 | ImageDisplayRegionFragment::class.java 36 | ) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayLargeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.imagedisplay 2 | 3 | import android.app.Fragment 4 | import android.graphics.Bitmap 5 | import android.os.Bundle 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | 10 | import com.davemorrissey.labs.subscaleview.ImageSource 11 | import com.davemorrissey.labs.subscaleview.decoder.CompatDecoderFactory 12 | import com.davemorrissey.labs.subscaleview.decoder.SkiaImageDecoder 13 | import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder 14 | import com.davemorrissey.labs.subscaleview.sample.R.layout 15 | 16 | import kotlinx.android.synthetic.main.imagedisplay_large_fragment.next 17 | import kotlinx.android.synthetic.main.imagedisplay_large_fragment.imageView 18 | 19 | class ImageDisplayLargeFragment : Fragment() { 20 | 21 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 22 | return inflater!!.inflate(layout.imagedisplay_large_fragment, container, false) 23 | } 24 | 25 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 26 | super.onViewCreated(view, savedInstanceState) 27 | next.setOnClickListener { (parentFragment as ImageDisplayFragment).next() } 28 | imageView.setBitmapDecoderFactory(CompatDecoderFactory(SkiaImageDecoder::class.java, Bitmap.Config.ARGB_8888)) 29 | imageView.setRegionDecoderFactory(CompatDecoderFactory(SkiaPooledImageRegionDecoder::class.java, Bitmap.Config.ARGB_8888)) 30 | imageView.setImage(ImageSource.asset("card.png")) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRegionFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.imagedisplay 2 | 3 | import android.graphics.Rect 4 | import android.os.Bundle 5 | import android.app.Fragment 6 | import android.graphics.Bitmap 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | 11 | import com.davemorrissey.labs.subscaleview.ImageSource 12 | import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView 13 | import com.davemorrissey.labs.subscaleview.decoder.CompatDecoderFactory 14 | import com.davemorrissey.labs.subscaleview.decoder.SkiaImageDecoder 15 | import com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder 16 | import com.davemorrissey.labs.subscaleview.sample.R.layout 17 | 18 | import kotlinx.android.synthetic.main.imagedisplay_region_fragment.previous 19 | import kotlinx.android.synthetic.main.imagedisplay_region_fragment.rotate 20 | import kotlinx.android.synthetic.main.imagedisplay_region_fragment.imageView 21 | 22 | class ImageDisplayRegionFragment : Fragment() { 23 | 24 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 25 | return inflater!!.inflate(layout.imagedisplay_region_fragment, container, false) 26 | } 27 | 28 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 29 | super.onViewCreated(view, savedInstanceState) 30 | imageView.setBitmapDecoderFactory(CompatDecoderFactory(SkiaImageDecoder::class.java, Bitmap.Config.ARGB_8888)) 31 | imageView.setRegionDecoderFactory(CompatDecoderFactory(SkiaPooledImageRegionDecoder::class.java, Bitmap.Config.ARGB_8888)) 32 | imageView.orientation = SubsamplingScaleImageView.ORIENTATION_90 33 | imageView.setImage(ImageSource.asset("card.png").region(Rect(5200, 651, 8200, 3250))) 34 | previous.setOnClickListener { (parentFragment as ImageDisplayFragment).previous() } 35 | rotate.setOnClickListener { imageView.orientation = (imageView.orientation + 90) % 360 } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/imagedisplay/ImageDisplayRotateFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.imagedisplay 2 | 3 | import android.os.Bundle 4 | import android.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | import com.davemorrissey.labs.subscaleview.ImageSource 10 | import com.davemorrissey.labs.subscaleview.sample.R.layout 11 | 12 | import kotlinx.android.synthetic.main.imagedisplay_rotate_fragment.next 13 | import kotlinx.android.synthetic.main.imagedisplay_rotate_fragment.previous 14 | import kotlinx.android.synthetic.main.imagedisplay_rotate_fragment.rotate 15 | import kotlinx.android.synthetic.main.imagedisplay_rotate_fragment.imageView 16 | 17 | class ImageDisplayRotateFragment : Fragment() { 18 | 19 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 20 | return inflater!!.inflate(layout.imagedisplay_rotate_fragment, container, false) 21 | } 22 | 23 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 24 | super.onViewCreated(view, savedInstanceState) 25 | imageView.setImage(ImageSource.asset("swissroad.jpg")) 26 | imageView.orientation = 90 27 | previous.setOnClickListener { (parentFragment as ImageDisplayFragment).previous() } 28 | next.setOnClickListener { (parentFragment as ImageDisplayFragment).next() } 29 | rotate.setOnClickListener { imageView.orientation = (imageView.orientation + 90) % 360 } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/viewpager/VerticalViewPager.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.viewpager 2 | 3 | import android.content.Context 4 | import android.support.v4.view.ViewPager 5 | import android.util.AttributeSet 6 | import android.view.MotionEvent 7 | import android.view.View 8 | 9 | /** 10 | * From http://stackoverflow.com/a/22797619/2719186 11 | */ 12 | class VerticalViewPager : ViewPager { 13 | 14 | constructor(context: Context) : super(context) { 15 | init() 16 | } 17 | 18 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 19 | init() 20 | } 21 | 22 | private fun init() { 23 | setPageTransformer(true, VerticalPageTransformer()) 24 | overScrollMode = View.OVER_SCROLL_NEVER 25 | } 26 | 27 | private inner class VerticalPageTransformer : ViewPager.PageTransformer { 28 | 29 | override fun transformPage(view: View, position: Float) { 30 | when { 31 | position < -1 -> view.alpha = 0f 32 | position <= 1 -> { 33 | view.alpha = 1f 34 | view.translationX = view.width * -position 35 | val yPosition = position * view.height 36 | view.translationY = yPosition 37 | } 38 | else -> view.alpha = 0f 39 | } 40 | } 41 | } 42 | 43 | private fun swapXY(ev: MotionEvent): MotionEvent { 44 | val width = width.toFloat() 45 | val height = height.toFloat() 46 | val newX = ev.y / height * width 47 | val newY = ev.x / width * height 48 | ev.setLocation(newX, newY) 49 | return ev 50 | } 51 | 52 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { 53 | val intercepted = super.onInterceptTouchEvent(swapXY(ev)) 54 | swapXY(ev) 55 | return intercepted 56 | } 57 | 58 | override fun onTouchEvent(ev: MotionEvent): Boolean { 59 | return super.onTouchEvent(swapXY(ev)) 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/viewpager/ViewPagerFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.viewpager 2 | 3 | import android.os.Bundle 4 | import android.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | 9 | import com.davemorrissey.labs.subscaleview.ImageSource 10 | import com.davemorrissey.labs.subscaleview.sample.R.layout 11 | 12 | import kotlinx.android.synthetic.main.view_pager_page.imageView 13 | 14 | class ViewPagerFragment : Fragment() { 15 | 16 | private var asset: String? = null 17 | 18 | fun setAsset(asset: String) { 19 | this.asset = asset 20 | } 21 | 22 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 23 | return inflater!!.inflate(layout.view_pager_page, container, false) 24 | } 25 | 26 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 27 | super.onViewCreated(view, savedInstanceState) 28 | if (asset == null && savedInstanceState?.containsKey(BUNDLE_ASSET) == true) { 29 | asset = savedInstanceState.getString(BUNDLE_ASSET) 30 | } 31 | asset?.let { 32 | imageView.setImage(ImageSource.asset(it)) 33 | } 34 | } 35 | 36 | override fun onSaveInstanceState(outState: Bundle?) { 37 | super.onSaveInstanceState(outState) 38 | val rootView = view 39 | if (rootView != null) { 40 | outState?.putString(BUNDLE_ASSET, asset) 41 | } 42 | } 43 | 44 | companion object { 45 | private const val BUNDLE_ASSET = "asset" 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/davemorrissey/labs/subscaleview/sample/viewpager/ViewPagersFragment.kt: -------------------------------------------------------------------------------- 1 | package com.davemorrissey.labs.subscaleview.sample.viewpager 2 | 3 | import android.app.Fragment 4 | import android.app.FragmentManager 5 | import android.support.v13.app.FragmentPagerAdapter 6 | import android.view.View 7 | 8 | import com.davemorrissey.labs.subscaleview.sample.AbstractPagesFragment 9 | import com.davemorrissey.labs.subscaleview.sample.Page 10 | 11 | import java.util.Arrays 12 | 13 | import com.davemorrissey.labs.subscaleview.sample.R.layout.view_pager 14 | import com.davemorrissey.labs.subscaleview.sample.R.string.pager_p1_subtitle 15 | import com.davemorrissey.labs.subscaleview.sample.R.string.pager_p1_text 16 | import com.davemorrissey.labs.subscaleview.sample.R.string.pager_p2_subtitle 17 | import com.davemorrissey.labs.subscaleview.sample.R.string.pager_p2_text 18 | import com.davemorrissey.labs.subscaleview.sample.R.string.pager_title 19 | 20 | import kotlinx.android.synthetic.main.view_pager.horizontal_pager as horizontalPager 21 | import kotlinx.android.synthetic.main.view_pager.vertical_pager as verticalPager 22 | 23 | class ViewPagersFragment : AbstractPagesFragment(pager_title, view_pager, Arrays.asList( 24 | Page(pager_p1_subtitle, pager_p1_text), 25 | Page(pager_p2_subtitle, pager_p2_text) 26 | )) { 27 | 28 | override fun onResume() { 29 | super.onResume() 30 | horizontalPager.adapter = ScreenSlidePagerAdapter(childFragmentManager) 31 | verticalPager.adapter = ScreenSlidePagerAdapter(childFragmentManager) 32 | } 33 | 34 | override fun onPageChanged(page: Int) { 35 | if (page == 0) { 36 | horizontalPager.visibility = View.VISIBLE 37 | verticalPager.visibility = View.GONE 38 | } else { 39 | horizontalPager.visibility = View.GONE 40 | verticalPager.visibility = View.VISIBLE 41 | } 42 | } 43 | 44 | private inner class ScreenSlidePagerAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) { 45 | 46 | override fun getItem(position: Int): Fragment { 47 | val fragment = ViewPagerFragment() 48 | fragment.setAsset(IMAGES[position]) 49 | return fragment 50 | } 51 | 52 | override fun getCount(): Int { 53 | return IMAGES.size 54 | } 55 | } 56 | 57 | companion object { 58 | 59 | private val IMAGES = arrayOf("butterfly.jpg", "kingfisher.jpg", "swissroad.jpg", "sanmartino.jpg") 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/res/color/menu_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_apps_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_apps_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_crop_rotate_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_crop_rotate_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_face_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_face_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_layers_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_layers_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_navigate_before_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_navigate_before_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_navigate_next_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_navigate_next_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play_arrow_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_play_arrow_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_play_circle_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_play_circle_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_rotate_right_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_rotate_right_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_backup_restore_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_settings_backup_restore_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_terrain_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_terrain_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-hdpi/ic_touch_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_apps_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_apps_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_crop_rotate_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_crop_rotate_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_face_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_face_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_layers_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_layers_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_navigate_before_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_navigate_before_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_navigate_next_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_navigate_next_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play_arrow_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_play_arrow_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_play_circle_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_play_circle_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_rotate_right_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_rotate_right_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_backup_restore_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_settings_backup_restore_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_terrain_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_terrain_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-mdpi/ic_touch_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/pushpin_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-nodpi/pushpin_green.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_apps_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_apps_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_crop_rotate_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_crop_rotate_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_face_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_face_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_layers_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_layers_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_navigate_before_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_navigate_before_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_navigate_next_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_navigate_next_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play_arrow_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_play_arrow_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_play_circle_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_play_circle_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_rotate_right_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_rotate_right_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_backup_restore_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_settings_backup_restore_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_terrain_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_terrain_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xhdpi/ic_touch_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_apps_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_crop_rotate_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_crop_rotate_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_face_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_face_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_layers_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_layers_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_navigate_before_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_navigate_before_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_navigate_next_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_navigate_next_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_play_arrow_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_play_circle_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_rotate_right_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_rotate_right_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_backup_restore_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_settings_backup_restore_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_terrain_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_terrain_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxhdpi/ic_touch_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/github_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/github_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_apps_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_face_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_face_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_layers_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_layers_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_navigate_before_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_navigate_before_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_navigate_next_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_navigate_next_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_play_arrow_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_play_circle_outline_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_play_circle_outline_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_rotate_right_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_rotate_right_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_backup_restore_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_settings_backup_restore_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_settings_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_terrain_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_terrain_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_touch_app_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/ic_touch_app_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/launcher_hires.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/drawable-xxxhdpi/launcher_hires.png -------------------------------------------------------------------------------- /app/src/main/res/layout/animation_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/layout/extension_circle_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/extension_freehand_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/extension_pin_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragments_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/imagedisplay_large_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/imagedisplay_region_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/imagedisplay_rotate_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 22 | 23 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_nav_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 18 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/pages_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_pager_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 37 | 38 | 42 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #00695C 4 | #004D40 5 | #212121 6 | #00695C 7 | #000000 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scale Image View Demo 4 | 5 | Subsampling Scale Image View 6 | 7 | View on GitHub 8 | Dave Morrissey 9 | 10 | Open 11 | Close 12 | 13 | Animate 14 | Next 15 | Previous 16 | Rotate 17 | Reset 18 | 19 | Basic features 20 | Basic features 21 | Pinch to zoom 22 | 23 | Use a two finger pinch to zoom in and out. The zoom is centred on the pinch gesture, and you can pan at the same time. 24 | 25 | Quick scale 26 | 27 | Double tap and swipe up or down to zoom in or out. The zoom is centred where you tapped. 28 | 29 | Drag 30 | Use one finger to drag the image around. 31 | Fling 32 | 33 | If you drag quickly and let go, fling momentum keeps the image moving. 34 | 35 | Double tap 36 | 37 | Double tap the image to zoom in to that spot. Double tap again to zoom out. 38 | 39 | 40 | Image display 41 | Image display 42 | Large images 43 | 44 | This image is 7,800 x 6,240 pixels. On most devices it will be subsampled, and higher quality tiles are loaded as you zoom in. 45 | 46 | Rotation 47 | 48 | This image has been rotated 90 degrees. Tap the button to rotate it. EXIF rotation is supported for external files. 49 | 50 | Display region 51 | Set the region to display instead of the whole image. 52 | 53 | Event handling 54 | Event handling 55 | Simple events 56 | 57 | Touch handling by the image view doesn\'t prevent normal events from working. 58 | 59 | OnClickListener 60 | 61 | This view has an OnClickListener. Tap once to activate the click. 62 | 63 | OnLongClickListener 64 | 65 | This view has an OnLongClickListener. Press and hold to activate it. 66 | 67 | 68 | Advanced event handling 69 | Advanced event handling 70 | Overriding gestures 71 | Some gestures can be overridden with your own 72 | GestureDetector without affecting the image view. This allows you to get the coordinates of 73 | the event. 74 | 75 | onSingleTapConfirmed 76 | onSingleTapConfirmed has been overridden. Tap the image to 77 | see coordinates. 78 | 79 | onDoubleTap 80 | onDoubleTap has been overridden. Tap the image to see 81 | coordinates. This overrides the default zoom in behaviour. 82 | 83 | onLongPress 84 | onLongPress has been overridden. Press and hold the image 85 | to see coordinates. 86 | 87 | Other events 88 | You can override any event you want, but customising swipe, 89 | fling and zoom gestures will stop the view working normally. 90 | 91 | 92 | 93 | View pager galleries 94 | View pager gallery 95 | Horizontal 96 | 97 | This gallery has four images in a ViewPager. Swipe to move to the 98 | next image. If you\'re zoomed in on an image, you need to pan to the right of it, then swipe 99 | again to activate the pager. 100 | 101 | Vertical 102 | 103 | Vertical view pagers are also supported. Swipe up to move to the 104 | next image. If you\'re zoomed in on an image, you need to pan to the bottom of it, then 105 | swipe again to activate the pager. 106 | 107 | 108 | Animation 109 | Animation 110 | A demo 111 | 112 | Tap the play button. The image will scale and zoom to a random point, shown by a marker. 113 | 114 | Limited pan 115 | 116 | If the target point is near the edge of the image, it will be moved as near to the center as possible. 117 | 118 | Unlimited pan 119 | 120 | With unlimited or center-limited pan, the target point can always be animated to the center. 121 | 122 | Customisation 123 | 124 | Duration and easing are configurable. You can also make animations non-interruptible. 125 | 126 | 127 | Extension 128 | Extension 129 | Location pin 130 | 131 | This view class extends the image view, and adds a pin anchored to a point on the image. 132 | 133 | Overlaid circle 134 | 135 | A slightly more advanced example, this shows a circle that will 136 | move and scale with the image. (Due to a limitation in Android, this circle may disappear 137 | when it\'s larger than 2048px.) 138 | 139 | Freehand drawing 140 | 141 | This subclass adds event detection. Draw a freehand line; it 142 | will move with the image. (Due to a limitation in Android, your drawing may disappear when 143 | it\'s larger than 2048px.) 144 | 145 | 146 | Configuration 147 | Configuration 148 | Maximum scale 149 | 150 | The maximum scale has been set to 50dpi. You can zoom in until the image is very pixellated. 151 | 152 | Minimum tile DPI 153 | 154 | The minimum tile DPI has been set to 50dpi, to reduce 155 | memory usage. The next layer of tiles will not be loaded until the image is very pixellated. 156 | 157 | Pan disabled 158 | 159 | Dragging has been disabled. You can only zoom in to the centre point. 160 | 161 | Zoom disabled 162 | 163 | Zooming has been disabled. You can drag the image around. 164 | 165 | Double tap style 166 | 167 | On double tap, the tapped point is now zoomed to the center of the screen instead of remaining in the same place. 168 | 169 | Double tap style 170 | On double tap, the zoom now happens immediately. 171 | Double tap scale 172 | The double tap zoom scale has been set to 240dpi. 173 | Pan limit center 174 | 175 | The pan limit has been changed to PAN_LIMIT_CENTER. Panning stops when a corner reaches the centre of the screen. 176 | 177 | Pan limit outside 178 | 179 | The pan limit has been changed to PAN_LIMIT_OUTSIDE. Panning stops when the image is just off screen. 180 | 181 | Debug 182 | 183 | Debug has been enabled. This shows the tile boundaries and sizes. 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 16 | 17 | 24 | 25 | 32 | 33 | 41 | 42 | 48 | 49 | 53 | 54 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.30' 3 | ext.support_version = '27.1.0' 4 | repositories { 5 | google() 6 | jcenter() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.0.1' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | mavenCentral() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/images/google_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/docs/images/google_play.png -------------------------------------------------------------------------------- /docs/images/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/docs/images/screenshot1.png -------------------------------------------------------------------------------- /docs/images/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/docs/images/screenshot2.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davemorrissey/ssiv-kotlin-sample/53e3c2343cf62c114d53c814898d98e8edf602b7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Nov 02 13:22:47 GMT 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------