├── .gitignore ├── .gradle └── 1.6 │ └── taskArtifacts │ ├── cache.properties │ ├── cache.properties.lock │ ├── fileHashes.bin │ ├── fileSnapshots.bin │ ├── outputFileStates.bin │ └── taskArtifacts.bin ├── ImageMap ├── build.gradle ├── build │ ├── apk │ │ └── ImageMap-debug-unaligned.apk │ ├── incremental │ │ ├── aidl │ │ │ └── debug │ │ │ │ ├── dependency.store │ │ │ │ ├── inputs.data │ │ │ │ └── outputs.data │ │ ├── dex │ │ │ └── debug │ │ │ │ ├── inputs.data │ │ │ │ └── outputs.data │ │ ├── mergeAssets │ │ │ └── debug │ │ │ │ ├── inputs.data │ │ │ │ ├── merger.xml │ │ │ │ └── outputs.data │ │ └── mergeResources │ │ │ └── debug │ │ │ ├── inputs.data │ │ │ ├── merger.xml │ │ │ └── outputs.data │ ├── manifests │ │ └── debug │ │ │ └── AndroidManifest.xml │ ├── res │ │ └── all │ │ │ └── debug │ │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── drawable-nodpi │ │ │ └── pink_girl.jpg │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── values-v14 │ │ │ └── values.xml │ │ │ └── values │ │ │ └── values.xml │ └── source │ │ ├── buildConfig │ │ └── debug │ │ │ └── net │ │ │ └── yoojia │ │ │ └── imagemap │ │ │ └── BuildConfig.java │ │ └── r │ │ └── debug │ │ └── net │ │ └── yoojia │ │ └── imagemap │ │ └── R.java ├── libs │ └── android-support-v4.jar └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── net │ │ └── yoojia │ │ └── imagemap │ │ ├── HighlightImageView.java │ │ ├── ImageMap.java │ │ ├── MainActivity.java │ │ ├── TouchImageView.java │ │ └── support │ │ ├── Bubble.java │ │ ├── CircleShape.java │ │ ├── PolyShape.java │ │ ├── RectShape.java │ │ ├── ScaleUtility.java │ │ ├── Shape.java │ │ └── ShapeExtension.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-nodpi │ └── pink_girl.jpg │ ├── layout │ └── activity_main.xml │ ├── values-v14 │ └── styles.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.ap_ 3 | 4 | # files for the dex VM 5 | *.dex 6 | 7 | # Java class files 8 | *.class 9 | 10 | # generated files 11 | bin/ 12 | out/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Intellij project files 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # MacOS 32 | .DS_Store -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Mon May 20 16:02:30 CST 2013 2 | -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/.gradle/1.6/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/.gradle/1.6/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/.gradle/1.6/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /.gradle/1.6/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/.gradle/1.6/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /ImageMap/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'http://repo1.maven.org/maven2' } 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:0.4' 7 | } 8 | } 9 | apply plugin: 'android' 10 | 11 | dependencies { 12 | compile files('libs/android-support-v4.jar') 13 | } 14 | 15 | android { 16 | compileSdkVersion 17 17 | buildToolsVersion "17" 18 | 19 | defaultConfig { 20 | minSdkVersion 7 21 | targetSdkVersion 16 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ImageMap/build/apk/ImageMap-debug-unaligned.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/build/apk/ImageMap-debug-unaligned.apk -------------------------------------------------------------------------------- /ImageMap/build/incremental/aidl/debug/dependency.store: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /ImageMap/build/incremental/aidl/debug/inputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/aidl/debug/outputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/dex/debug/inputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | 1369108733000 4093 d61a72d24440590515af5425c0fb526fb01ec311 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/ImageMap.class 5 | 1369108733000 3304 23cb05e9e687428512bff09d4d4d0459d6efde34 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/MainActivity.class 6 | 1369102299000 8074 224cd617e8024205df89a66640ccba93b978980c /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/TouchImageView.class 7 | 1369037883000 306 b52b8cb55db8539fbfa10b4867923d984bae8990 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/Bubble$BubbleDisplayer.class 8 | 1369036951000 347 ab06aec65d84d19865a024cebe7a8721d7994e1c /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/BuildConfig.class 9 | 1369037883000 860 c1df049577c1c209fb4efd9c3888e4364d3806c2 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/ScaleUtility.class 10 | 1369103885000 2222 02fa7501dee77e4a9db84e51cde6c6a06a6564b7 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/RectShape.class 11 | 1369038579000 389 af026cdab6e3e884778ca6fef14cd62d92831b47 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$id.class 12 | 1369038579000 434 a473dc045b1a48491ff6d1c35768b94b7c90e2f7 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$style.class 13 | 1369102299000 3098 eb18a7a19e890f7e21e0199aefe2bb897f473a7c /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/TouchImageView$ScaleListener.class 14 | 1369108733000 4256 daa1085a0f4437644765f9844e60e2f1716bead0 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/HighlightImageView.class 15 | 1369037883000 487 12a8f83cd462b7ff371953306a500f1dec77ba56 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/ShapeExtension.class 16 | 1369102299000 2542 e8546b99ea692cc1186efde89cd778e63c0640e9 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/Shape.class 17 | 1369103885000 2644 a4e4b1cac295365c692b51f1753f4fc7db0f67ac /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/CircleShape.class 18 | 1369036951000 343 a2cfb7608e39b8863133d5028e08130e374de5c5 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$attr.class 19 | 1369036951000 464 b3e2a22a44575f9fa12354917f342892b25e0a21 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$dimen.class 20 | 1369036925000 393154 307c1cc532eabbf1d135b43e5c983c9da700449d /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/libs/android-support-v4.jar 21 | 1369108733000 326 b19c0d50f9b53be7449fa732188d04e92ea8abd7 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/ShapeExtension$OnShapeClickListener.class 22 | 1369104795000 4513 eaf24f7a056a8c849ae6007e8ab8effffcea06e2 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/PolyShape.class 23 | 1369038579000 640 ab18157163342d297ab06187be4434fa11079dbd /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R.class 24 | 1369107108000 443 f2cbff082d6fddc42dde82386df761d53e72f580 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$drawable.class 25 | 1369038579000 475 1e2085b2990f544ff9df7af4d9551f7810f384ba /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$string.class 26 | 1369037883000 2965 e5403cdbc799c5663e153f03f73644ff153875fc /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/support/Bubble.class 27 | 1369041247000 3092 9790e001900d54358349b163c57cf4c18a2153a7 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/TouchImageView$1.class 28 | 1369038579000 406 c3e3c09bde939127e2cfe41b0b70077852cf0d75 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/classes/debug/net/yoojia/imagemap/R$layout.class 29 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/dex/debug/outputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeAssets/debug/inputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeAssets/debug/merger.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeAssets/debug/outputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeResources/debug/inputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | 1369036924000 680 c76f4caaa7a8dfe9727fa93001b3aee3b22d6716 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/values/styles.xml 5 | 1369038121000 427 fb0ef6a397aa4ca6b0075e1b87af3bc784ab5765 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/layout/activity_main.xml 6 | 1369036995000 221 2ed1b7ac411d768e4789a2cee7f5076913426fb1 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/values/strings.xml 7 | 1369036924000 381 b129b276e01126de5b3b753572ac67cbfc19454c /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/values-v14/styles.xml 8 | 1369036924000 4302 c6fdbcf708e9d112d63458e3bc1a9c8bad955c9b /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/drawable-hdpi/ic_launcher.png 9 | 1369036925000 211 4e1904afba59d31e5cd6133f6a4c360fa9a5913f /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/values/dimens.xml 10 | 1369105378000 216462 a024e3d5475d0bfc60fe7ae929619e187a0dc06a /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/src/main/res/drawable-nodpi/pink_girl.jpg 11 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeResources/debug/merger.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 16 | 21 | 26 | 31 | 36 | 39 | 16dp 40 | 41 | 16dp 42 | 43 | 44 | 47 | Settings 48 | 49 | ImageMap 50 | 51 | Hello world! 52 | 53 | 54 | 57 | 58 | 68 | 69 | 75 | 76 | 79 | 82 | 128dp 83 | 84 | 85 | 88 | 89 | 95 | 96 | 99 | 100 | 106 | 107 | 112 | 117 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /ImageMap/build/incremental/mergeResources/debug/outputs.data: -------------------------------------------------------------------------------- 1 | # incremental data. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | 1369036951000 786 44559f3bab036165a0fc152cee505d483c649ac0 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/res/all/debug/values/values.xml 5 | 1369036951000 4302 c6fdbcf708e9d112d63458e3bc1a9c8bad955c9b /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/res/all/debug/drawable-hdpi/ic_launcher.png 6 | 1369036951000 217 f02e000d05a079992d2dba18039216c1e6b8784f /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/res/all/debug/values-v14/values.xml 7 | 1369038140000 427 fb0ef6a397aa4ca6b0075e1b87af3bc784ab5765 /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/res/all/debug/layout/activity_main.xml 8 | 1369107107000 216462 a024e3d5475d0bfc60fe7ae929619e187a0dc06a /Users/ilovedeals/Documents/android-workspace/ImageMap/ImageMap/build/res/all/debug/drawable-nodpi/pink_girl.jpg 9 | -------------------------------------------------------------------------------- /ImageMap/build/manifests/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ImageMap/build/res/all/debug/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/build/res/all/debug/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImageMap/build/res/all/debug/drawable-nodpi/pink_girl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/build/res/all/debug/drawable-nodpi/pink_girl.jpg -------------------------------------------------------------------------------- /ImageMap/build/res/all/debug/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ImageMap/build/res/all/debug/values-v14/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ImageMap/build/res/all/debug/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | Settings 8 | ImageMap 9 | Hello world! 10 | 11 | 18 | 19 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ImageMap/build/source/buildConfig/debug/net/yoojia/imagemap/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** Automatically generated file. DO NOT MODIFY */ 2 | package net.yoojia.imagemap; 3 | 4 | public final class BuildConfig { 5 | public final static boolean DEBUG = true; 6 | 7 | } -------------------------------------------------------------------------------- /ImageMap/build/source/r/debug/net/yoojia/imagemap/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package net.yoojia.imagemap; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class dimen { 14 | public static final int activity_horizontal_margin=0x7f040000; 15 | public static final int activity_vertical_margin=0x7f040001; 16 | } 17 | public static final class drawable { 18 | public static final int ic_launcher=0x7f020000; 19 | public static final int pink_girl=0x7f020001; 20 | } 21 | public static final class id { 22 | public static final int imagemap=0x7f070000; 23 | } 24 | public static final class layout { 25 | public static final int activity_main=0x7f030000; 26 | } 27 | public static final class string { 28 | public static final int action_settings=0x7f050000; 29 | public static final int app_name=0x7f050001; 30 | public static final int hello_world=0x7f050002; 31 | } 32 | public static final class style { 33 | /** 34 | Theme customizations available in newer API levels can go in 35 | res/values-vXX/styles.xml, while customizations related to 36 | backward-compatibility can go here. 37 | 38 | API 14 theme customizations can go here. 39 | */ 40 | public static final int AppBaseTheme=0x7f060000; 41 | /** All customizations that are NOT specific to a particular API-level can go here. 42 | */ 43 | public static final int AppTheme=0x7f060001; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ImageMap/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/libs/android-support-v4.jar -------------------------------------------------------------------------------- /ImageMap/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ImageMap/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/HighlightImageView.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.util.AttributeSet; 6 | import net.yoojia.imagemap.support.Shape; 7 | import net.yoojia.imagemap.support.ShapeExtension; 8 | 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | public class HighlightImageView extends TouchImageView implements ShapeExtension { 15 | 16 | public HighlightImageView(Context context) { 17 | this(context,null); 18 | } 19 | 20 | public HighlightImageView(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | } 23 | 24 | private Map shapesCache = new HashMap(); 25 | 26 | private int savedShapesCount = 0; 27 | 28 | private OnShapeClickListener onShapeClickListener; 29 | 30 | public void setOnShapeClickListener(OnShapeClickListener onShapeClickListener){ 31 | this.onShapeClickListener = onShapeClickListener; 32 | } 33 | 34 | @Override 35 | public void addShape(Shape shape){ 36 | shapesCache.put(shape.tag, shape); 37 | postInvalidate(); 38 | } 39 | 40 | @Override 41 | public void addShapes(List shapes){ 42 | for(Shape shape : shapes){ 43 | shapesCache.put(shape.tag, shape); 44 | } 45 | postInvalidate(); 46 | } 47 | 48 | @Override 49 | public void removeShape(Object tag){ 50 | if(shapesCache.containsKey(tag)){ 51 | shapesCache.remove(tag); 52 | postInvalidate(); 53 | } 54 | } 55 | 56 | public List getShapes(){ 57 | return new ArrayList(shapesCache.values()); 58 | } 59 | 60 | @Override 61 | protected void onDraw(Canvas canvas) { 62 | super.onDraw(canvas); 63 | canvas.save(); 64 | for(Shape shape : shapesCache.values()){ 65 | shape.draw(canvas); 66 | } 67 | onDrawWithCanvas(canvas); 68 | canvas.restore(); 69 | } 70 | 71 | protected void onDrawWithCanvas(Canvas canvas){} 72 | 73 | @Override 74 | protected void onClick(float xOnView, float yOnView) { 75 | if(onShapeClickListener == null) return; 76 | for(Shape shape : shapesCache.values()){ 77 | if(shape.inArea(xOnView,yOnView)){ 78 | onShapeClickListener.onShapeClick(shape,xOnView,yOnView); 79 | // only one shape could be clicked 80 | break; 81 | } 82 | } 83 | } 84 | 85 | @Override 86 | protected void postScale(float scaleFactor, float scaleCenterX,float scaleCenterY) { 87 | super.postScale(scaleFactor, scaleCenterX, scaleCenterY); 88 | if(scaleFactor != 0){ 89 | for(Shape shape : shapesCache.values()){ 90 | if(scaleFactor != 0){ 91 | shape.scale(scaleFactor,scaleCenterX,scaleCenterY); 92 | } 93 | } 94 | } 95 | } 96 | 97 | @Override 98 | protected void postTranslate(float deltaX, float deltaY) { 99 | super.postTranslate(deltaX, deltaY); 100 | if( !(deltaX == 0 && deltaY == 0)){ 101 | for(Shape shape : shapesCache.values()){ 102 | shape.translate(deltaX,deltaY); 103 | } 104 | // onShapeClickListener.onMoving(deltaX,deltaY); 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/ImageMap.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | import android.widget.FrameLayout; 8 | import net.yoojia.imagemap.support.Bubble; 9 | import net.yoojia.imagemap.support.Shape; 10 | import net.yoojia.imagemap.support.ShapeExtension; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * author : chenyoca@gmail.com 16 | * date : 2013-5-19 17 | * An HTML map like widget in an Android view 18 | */ 19 | public class ImageMap extends FrameLayout implements ShapeExtension,ShapeExtension.OnShapeClickListener{ 20 | 21 | private OnShapeClickListener onShapeClickListener; 22 | 23 | private HighlightImageView highlightImageView; 24 | private Bubble bubble; 25 | 26 | public ImageMap(Context context) { 27 | this(context,null); 28 | } 29 | 30 | public ImageMap(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | initialImageView(context); 33 | } 34 | 35 | public ImageMap(Context context, AttributeSet attrs, int defStyle) { 36 | super(context, attrs, defStyle); 37 | initialImageView(context); 38 | } 39 | 40 | private void initialImageView(Context context){ 41 | highlightImageView = new HighlightImageView(context); 42 | highlightImageView.setOnShapeClickListener(this); 43 | LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 44 | addView(highlightImageView,params); 45 | } 46 | 47 | public void setOnShapeClickListener(OnShapeClickListener listener){ 48 | this.onShapeClickListener = listener; 49 | } 50 | 51 | /** 52 | * Set a bubble view. 53 | * @param bubbleView a view object for display on image map. 54 | */ 55 | public void setBubbleView(View bubbleView) { 56 | setBubbleView(bubbleView,null); 57 | } 58 | 59 | /** 60 | * Aet a bubble view and it's displayer interface. 61 | * @param bubbleView a view object for display on image map. 62 | * @param displayer the display interface for bubble view render. 63 | */ 64 | public void setBubbleView(View bubbleView,Bubble.BubbleDisplayer displayer){ 65 | if(bubbleView == null){ 66 | throw new IllegalArgumentException("View for bubble cannot be null !"); 67 | } 68 | bubble = new Bubble(bubbleView); 69 | bubble.setDisplayer(displayer); 70 | addView(bubble.view); 71 | bubble.view.setVisibility(View.INVISIBLE); 72 | } 73 | 74 | @Override 75 | public void addShape(Shape shape) { 76 | highlightImageView.addShape(shape); 77 | } 78 | 79 | @Override 80 | public void addShapes(List shapes) { 81 | highlightImageView.addShapes(shapes); 82 | } 83 | 84 | @Override 85 | public void removeShape(Object tag) { 86 | highlightImageView.removeShape(tag); 87 | } 88 | 89 | @Override 90 | public final void onShapeClick(Shape shape, float xOnImage, float yOnImage) { 91 | for(Shape item : highlightImageView.getShapes()){ 92 | item.cleanBubbleRelation(); 93 | } 94 | if(bubble != null){ 95 | bubble.showAtShape(shape); 96 | } 97 | if(onShapeClickListener != null){ 98 | onShapeClickListener.onShapeClick(shape,xOnImage,yOnImage); 99 | } 100 | } 101 | 102 | /** 103 | * set a bitmap for image map. 104 | * @param bitmap image 105 | */ 106 | public void setMapBitmap(Bitmap bitmap){ 107 | highlightImageView.setImageBitmap(bitmap); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/MainActivity.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.graphics.Color; 6 | import android.os.Bundle; 7 | import android.app.Activity; 8 | import android.view.Menu; 9 | import android.widget.Toast; 10 | import net.yoojia.imagemap.support.*; 11 | 12 | public class MainActivity extends Activity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | // 18 | setContentView(R.layout.activity_main); 19 | 20 | ImageMap map = (ImageMap) findViewById(R.id.imagemap); 21 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.pink_girl,new BitmapFactory.Options()); 22 | map.setMapBitmap(bitmap); 23 | 24 | // set shape click listener 25 | map.setOnShapeClickListener(new ShapeExtension.OnShapeClickListener() { 26 | @Override 27 | public void onShapeClick(Shape shape, float xOnImage, float yOnImage) { 28 | String msg = "Shape "+shape.tag+" clicked !"; 29 | Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show(); 30 | } 31 | }); 32 | 33 | // set color 34 | // circle 35 | Shape black = new CircleShape("black", Color.BLACK); 36 | black.setValues(633,122,15); 37 | map.addShape(black); 38 | 39 | // circle 40 | Shape red = new CircleShape("red", Color.BLACK); 41 | red.setValues(665,144,15); 42 | map.addShape(red); 43 | 44 | // rect 45 | Shape blue = new RectShape("blue",Color.BLUE); 46 | blue.setValues(104,7,226, 94); 47 | map.addShape(blue); 48 | 49 | // poly 50 | 51 | // croods int/float values 52 | Shape orange = new PolyShape("orange",0xff8226); 53 | orange.setValues(172,370, 178,332, 194,283, 220,215, 253,172, 262,173, 268,197, 269,213, 279,264, 279,286, 288,319, 290,344, 288,368, 270,376, 238,370, 199,370, 175,373); 54 | map.addShape(orange); 55 | 56 | // coores string values 57 | Shape green = new PolyShape("poly",Color.GREEN); 58 | green.setValues("229,432, 238,394, 262,384, 293,372, 312,381, 342,393, 355,414, 357,420, 371,434, 375,456, 370,471, 363,479, 360,499, 358,509, 329,513, 310,518, 281,518, 268,512, 182,536, 133,544, 89,539, 98,530, 133,532, 125,520, 88,522, 79,530, 67,521, 84,510, 100,510, 133,491, 149,494, 228,436"); 59 | map.addShape(green); 60 | 61 | Shape yellow = new PolyShape("yellow",Color.YELLOW); 62 | yellow.setValues("626,482, 625,481, 669,491, 710,480, 679,522, 676,537, 658,538, 650,518, 628,486"); 63 | map.addShape(yellow); 64 | 65 | // 66 | Shape white = new PolyShape("white",0x8962a0); 67 | white.setValues(559,270, 599,239, 627,265, 642,267, 668,266, 680,294, 664,303, 669,323, 690,325, 712,310, 720,311, 713,335, 715,369, 722,390, 744,443, 745,456, 717,475, 673,481, 636,477, 604,458, 586,439, 591,423, 590,398, 571,336, 561,273); 68 | map.addShape(white); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/TouchImageView.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Robert Foss, Roman Truba 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 14 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 15 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 16 | THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | package net.yoojia.imagemap; 19 | 20 | import android.content.Context; 21 | import android.graphics.*; 22 | import android.util.AttributeSet; 23 | import android.view.MotionEvent; 24 | import android.view.ScaleGestureDetector; 25 | import android.view.View; 26 | import android.widget.ImageView; 27 | 28 | public class TouchImageView extends ImageView { 29 | 30 | final Matrix imageMatrix = new Matrix(); 31 | final Matrix imageSavedMatrix = new Matrix(); 32 | 33 | final Matrix overlayerMatrix = new Matrix(); 34 | 35 | private static final float FRICTION = 0.9f; 36 | 37 | static final int NONE = 0; 38 | static final int DRAG = 1; 39 | static final int ZOOM = 2; 40 | int mode = NONE; 41 | 42 | float redundantXSpace, redundantYSpace; 43 | float right, bottom, origWidth, origHeight, bmWidth, bmHeight; 44 | float width, height; 45 | PointF last = new PointF(); 46 | PointF mid = new PointF(); 47 | PointF start = new PointF(); 48 | float[] matrixValues; 49 | float matrixX, matrixY; 50 | 51 | float saveScale = 1f; 52 | float minScale = 1f; 53 | float maxScale = 5f; 54 | float oldDist = 1f; 55 | 56 | PointF lastDelta = new PointF(0, 0); 57 | float velocity = 0; 58 | long lastDragTime = 0; 59 | 60 | private Context mContext; 61 | private ScaleGestureDetector mScaleDetector; 62 | 63 | Paint overlayerPaint; 64 | 65 | public boolean onLeftSide = false, onTopSide = false, onRightSide = false, onBottomSide = false; 66 | 67 | public TouchImageView(Context context) { 68 | this(context,null); 69 | } 70 | 71 | public TouchImageView(Context context, AttributeSet attrs) 72 | { 73 | super(context, attrs); 74 | super.setClickable(true); 75 | this.mContext = context; 76 | init(); 77 | } 78 | 79 | private OnTouchListener touchListener = new OnTouchListener() { 80 | 81 | final static float MAX_VELOCITY = 1.5f; 82 | 83 | private long dragTime ; 84 | private float dragVelocity; 85 | 86 | @Override 87 | public boolean onTouch(View v, MotionEvent event) { 88 | mScaleDetector.onTouchEvent(event); 89 | 90 | fillMatrixXY(); 91 | PointF curr = new PointF(event.getX(), event.getY()); 92 | switch (event.getAction() & MotionEvent.ACTION_MASK) { 93 | case MotionEvent.ACTION_DOWN: 94 | mode = DRAG; 95 | float xOnView = event.getX(); 96 | float yOnView = event.getY(); 97 | onClick(xOnView,yOnView); 98 | imageSavedMatrix.set(imageMatrix); 99 | last.set(event.getX(), event.getY()); 100 | start.set(last); 101 | 102 | break; 103 | 104 | case MotionEvent.ACTION_POINTER_DOWN: 105 | oldDist = spacing(event); 106 | if (oldDist > 10f) { 107 | imageSavedMatrix.set(imageMatrix); 108 | midPoint(mid, event); 109 | mode = ZOOM; 110 | } 111 | break; 112 | 113 | case MotionEvent.ACTION_UP: 114 | if(mode == DRAG){ 115 | velocity = dragVelocity; 116 | } 117 | mode = NONE; 118 | break; 119 | 120 | case MotionEvent.ACTION_POINTER_UP: 121 | mode = NONE; 122 | velocity = 0; 123 | imageSavedMatrix.set(imageMatrix); 124 | oldDist = spacing(event); 125 | break; 126 | 127 | case MotionEvent.ACTION_MOVE: 128 | if (mode == DRAG) { 129 | dragTime = System.currentTimeMillis(); 130 | dragVelocity = (float)distanceBetween(curr, last) / (dragTime - lastDragTime) * FRICTION; 131 | dragVelocity = Math.min(MAX_VELOCITY,dragVelocity); 132 | lastDragTime = dragTime; 133 | float deltaX = curr.x - last.x; 134 | float deltaY = curr.y - last.y; 135 | checkAndSetTranslate(deltaX, deltaY); 136 | lastDelta.set(deltaX, deltaY); 137 | last.set(curr.x, curr.y); 138 | } 139 | break; 140 | } 141 | 142 | setImageMatrix(imageMatrix); 143 | invalidate(); 144 | return false; 145 | } 146 | }; 147 | 148 | protected void init() 149 | { 150 | imageMatrix.setTranslate(1f, 1f); 151 | overlayerMatrix.setTranslate(1f, 1f); 152 | matrixValues = new float[9]; 153 | setScaleType(ScaleType.MATRIX); 154 | setImageMatrix(imageMatrix); 155 | mScaleDetector = new ScaleGestureDetector(mContext, new ScaleListener()); 156 | setOnTouchListener(touchListener); 157 | overlayerPaint = new Paint(); 158 | overlayerPaint.setAntiAlias(true); 159 | } 160 | 161 | protected void onClick(float xOnView,float yOnView){} 162 | 163 | @Override 164 | protected void onDraw(Canvas canvas) { 165 | super.onDraw(canvas); 166 | final float deltaX = lastDelta.x * velocity, deltaY = lastDelta.y * velocity; 167 | if (deltaX > width || deltaY > height) return; 168 | velocity *= FRICTION; 169 | if (Math.abs(deltaX) < 0.1 && Math.abs(deltaY) < 0.1) { 170 | return; 171 | } 172 | checkAndSetTranslate(deltaX, deltaY); 173 | setImageMatrix(imageMatrix); 174 | } 175 | 176 | protected void postTranslate(float deltaX, float deltaY){ 177 | imageMatrix.postTranslate(deltaX,deltaY); 178 | overlayerMatrix.postTranslate(deltaX,deltaY); 179 | } 180 | 181 | protected void postScale(float scaleFactor, float scaleCenterX, float scaleCenterY){ 182 | imageMatrix.postScale(scaleFactor, scaleFactor, scaleCenterX, scaleCenterY); 183 | overlayerMatrix.postScale(scaleFactor, scaleFactor, scaleCenterX, scaleCenterY); 184 | } 185 | 186 | private void checkAndSetTranslate(float deltaX, float deltaY) 187 | { 188 | float scaleWidth = Math.round(origWidth * saveScale); 189 | float scaleHeight = Math.round(origHeight * saveScale); 190 | fillMatrixXY(); 191 | if (scaleWidth < width) { 192 | deltaX = 0; 193 | if (matrixY + deltaY > 0) 194 | deltaY = -matrixY; 195 | else if (matrixY + deltaY < -bottom) 196 | deltaY = -(matrixY + bottom); 197 | } else if (scaleHeight < height) { 198 | deltaY = 0; 199 | if (matrixX + deltaX > 0) 200 | deltaX = -matrixX; 201 | else if (matrixX + deltaX < -right) 202 | deltaX = -(matrixX + right); 203 | } 204 | else { 205 | if (matrixX + deltaX > 0) 206 | deltaX = -matrixX; 207 | else if (matrixX + deltaX < -right) 208 | deltaX = -(matrixX + right); 209 | 210 | if (matrixY + deltaY > 0) 211 | deltaY = -matrixY; 212 | else if (matrixY + deltaY < -bottom) 213 | deltaY = -(matrixY + bottom); 214 | } 215 | postTranslate(deltaX, deltaY); 216 | checkSiding(); 217 | } 218 | 219 | private void checkSiding() 220 | { 221 | fillMatrixXY(); 222 | 223 | float scaleWidth = Math.round(origWidth * saveScale); 224 | float scaleHeight = Math.round(origHeight * saveScale); 225 | onLeftSide = onRightSide = onTopSide = onBottomSide = false; 226 | if (-matrixX < 10.0f ) onLeftSide = true; 227 | if ((scaleWidth >= width && (matrixX + scaleWidth - width) < 10) || 228 | (scaleWidth <= width && -matrixX + scaleWidth <= width)) onRightSide = true; 229 | if (-matrixY < 10.0f) onTopSide = true; 230 | if (Math.abs(-matrixY + height - scaleHeight) < 10.0f) onBottomSide = true; 231 | } 232 | 233 | private void calcPadding() 234 | { 235 | right = width * saveScale - width - (2 * redundantXSpace * saveScale); 236 | bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 237 | } 238 | 239 | private void fillMatrixXY() 240 | { 241 | imageMatrix.getValues(matrixValues); 242 | matrixX = matrixValues[Matrix.MTRANS_X]; 243 | matrixY = matrixValues[Matrix.MTRANS_Y]; 244 | } 245 | 246 | @Override 247 | public void setImageBitmap(Bitmap bm) { 248 | bmWidth = bm.getWidth(); 249 | bmHeight = bm.getHeight(); 250 | super.setImageBitmap(bm); 251 | 252 | } 253 | 254 | @Override 255 | protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) 256 | { 257 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 258 | width = MeasureSpec.getSize(widthMeasureSpec); 259 | height = MeasureSpec.getSize(heightMeasureSpec); 260 | 261 | float scale = saveScale; 262 | 263 | imageMatrix.setScale(scale, scale); 264 | overlayerMatrix.setScale(scale, scale); 265 | 266 | // Center the image 267 | redundantYSpace = height - (scale * bmHeight) ; 268 | redundantXSpace = width - (scale * bmWidth); 269 | redundantYSpace /= (float)2; 270 | redundantXSpace /= (float)2; 271 | 272 | // show the image to left and top of the view. 273 | postTranslate(0, 0); 274 | 275 | origWidth = width - 2 * redundantXSpace; 276 | origHeight = height - 2 * redundantYSpace; 277 | calcPadding(); 278 | setImageMatrix(imageMatrix); 279 | } 280 | 281 | private double distanceBetween(PointF left, PointF right) 282 | { 283 | return Math.sqrt(Math.pow(left.x - right.x, 2) + Math.pow(left.y - right.y, 2)); 284 | } 285 | 286 | private float spacing(MotionEvent event) { 287 | // ... 288 | float x = event.getX(0) - event.getX(1); 289 | float y = event.getY(0) - event.getY(1); 290 | return (float)Math.sqrt(x * x + y * y); 291 | } 292 | 293 | private void midPoint(PointF point, MotionEvent event) { 294 | // ... 295 | float x = event.getX(0) + event.getX(1); 296 | float y = event.getY(0) + event.getY(1); 297 | point.set(x / 2, y / 2); 298 | } 299 | 300 | private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 301 | @Override 302 | public boolean onScaleBegin(ScaleGestureDetector detector) { 303 | mode = ZOOM; 304 | return true; 305 | } 306 | 307 | @Override 308 | public boolean onScale(ScaleGestureDetector detector) { 309 | float scaleFactor = detector.getScaleFactor(); 310 | //float scaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05); 311 | float origScale = saveScale; 312 | saveScale *= scaleFactor; 313 | if (saveScale > maxScale) { 314 | saveScale = maxScale; 315 | scaleFactor = maxScale / origScale; 316 | } else if (saveScale < minScale) { 317 | saveScale = minScale; 318 | scaleFactor = minScale / origScale; 319 | } 320 | right = width * saveScale - width - (2 * redundantXSpace * saveScale); 321 | bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 322 | 323 | // 显示的图片比源图片要小时进行缩放 324 | if (origWidth * saveScale <= width || origHeight * saveScale <= height) { 325 | final float scaleCenterX = width / 2; 326 | final float scaleCenterY = height / 2; 327 | postScale(scaleFactor, scaleCenterX, scaleCenterY); 328 | 329 | //在边缘时缩小图片的平移修正 330 | if (scaleFactor < 1) { 331 | imageMatrix.getValues(matrixValues); 332 | float x = matrixValues[Matrix.MTRANS_X]; 333 | float y = matrixValues[Matrix.MTRANS_Y]; 334 | if (scaleFactor < 1) { 335 | if (Math.round(origWidth * saveScale) < width) { 336 | float deltaX = 0,deltaY = 0; 337 | if (y < -bottom){ 338 | deltaY = -(y + bottom); 339 | postTranslate(deltaX, deltaY); 340 | } 341 | else if (y > 0){ 342 | deltaY = -y; 343 | postTranslate(deltaX, deltaY); 344 | } 345 | } else { 346 | float deltaX = 0,deltaY = 0; 347 | if (x < -right){ 348 | deltaX = -(x + right); 349 | postTranslate(deltaX, deltaY); 350 | } 351 | else if (x > 0){ 352 | deltaX = -x; 353 | postTranslate(deltaX, deltaY); 354 | } 355 | } 356 | } 357 | } 358 | } else { 359 | // 图片已经被放大,以触摸点为中心,缩放图片。 360 | postScale(scaleFactor, detector.getFocusX(), detector.getFocusY()); 361 | imageMatrix.getValues(matrixValues); 362 | float x = matrixValues[Matrix.MTRANS_X]; 363 | float y = matrixValues[Matrix.MTRANS_Y]; 364 | 365 | // 缩小图片时,如果在图片边缘缩小,为避免边缘出现空白,对图片进行平移处理 366 | if (scaleFactor < 1) { 367 | float deltaX = 0,deltaY = 0; 368 | if (x < -right){ 369 | deltaX = -(x + right); 370 | deltaY = 0; 371 | postTranslate(deltaX, deltaY); 372 | } 373 | else if (x > 0){ 374 | deltaX = -x; 375 | deltaY = 0; 376 | postTranslate(deltaX, deltaY); 377 | } 378 | if (y < -bottom){ 379 | deltaX = 0; 380 | deltaY = -(y + bottom); 381 | postTranslate(deltaX, deltaY); 382 | } 383 | else if (y > 0){ 384 | deltaX = 0; 385 | deltaY = -y; 386 | postTranslate(deltaX, deltaY); 387 | } 388 | } 389 | } 390 | return true; 391 | } 392 | } 393 | } -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/support/Bubble.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap.support; 2 | 3 | import android.graphics.PointF; 4 | import android.os.Build; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.FrameLayout; 8 | 9 | /** 10 | * author : chenyoca@gmail.com 11 | * date : 13-5-19 12 | * The bubble wrapper. 13 | */ 14 | public class Bubble { 15 | 16 | public interface BubbleDisplayer { 17 | void onDisplay(Shape shape, View bubbleView); 18 | } 19 | 20 | private BubbleDisplayer displayer; 21 | 22 | public final View view; 23 | 24 | public Bubble(View view){ 25 | this.view = view; 26 | final int wrapContent = ViewGroup.LayoutParams.WRAP_CONTENT; 27 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(wrapContent,wrapContent); 28 | this.view.setLayoutParams(params); 29 | this.view.setClickable(true); 30 | } 31 | 32 | /** 33 | * Set the interface for bubble view render. 34 | * @param displayer displayer implments 35 | */ 36 | public void setDisplayer(BubbleDisplayer displayer) { 37 | this.displayer = displayer; 38 | } 39 | 40 | /** 41 | * Show the bubble view on the shape. 42 | * @param shape the shape to show on 43 | */ 44 | public void showAtShape(Shape shape){ 45 | if(view == null) return; 46 | shape.createBubbleRelation(this); 47 | resetPosition(shape); 48 | if (displayer != null){ 49 | displayer.onDisplay(shape, view); 50 | } 51 | view.setVisibility(View.VISIBLE); 52 | } 53 | 54 | /** 55 | * Reset the bubble view to the other shape. 56 | * @param shape 57 | */ 58 | public void resetPosition(Shape shape){ 59 | if(view != null){ 60 | PointF center = shape.getCenter(); 61 | float posX = center.x - view.getWidth()/2; 62 | float posY = center.y - view.getHeight(); 63 | if(isSDK_11_Later()){ 64 | view.setX(posX); 65 | view.setY(posY); 66 | }else{ 67 | FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); 68 | if(params != null){ 69 | params.leftMargin = (int)posX; 70 | params.topMargin = (int)posY; 71 | } 72 | } 73 | 74 | } 75 | } 76 | 77 | /** 78 | * The image translated, sync translate the bubble view. 79 | * @param deltaX 80 | * @param deltaY 81 | */ 82 | public void onTranslate(float deltaX,float deltaY){ 83 | if(view != null && view.isShown()){ 84 | if(isSDK_11_Later()){ 85 | float x = view.getX(); 86 | float y = view.getY(); 87 | view.setX(x+deltaX); 88 | view.setY(y+deltaY); 89 | }else{ 90 | FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); 91 | if(params != null){ 92 | params.leftMargin += (int)deltaX; 93 | params.topMargin += (int)deltaY; 94 | } 95 | } 96 | } 97 | } 98 | 99 | boolean isSDK_11_Later(){ 100 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/support/CircleShape.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap.support; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.PointF; 5 | 6 | public class CircleShape extends Shape { 7 | 8 | private PointF center; 9 | private float radius; 10 | private float originRadius; 11 | 12 | public CircleShape(Object tag, int coverColor) { 13 | super(tag, coverColor); 14 | } 15 | 16 | /** 17 | * Set Center,radius 18 | * @param coords centerX,CenterY,radius 19 | */ 20 | @Override 21 | public void setValues(float...coords){ 22 | if(coords == null || coords.length != 3){ 23 | throw new IllegalArgumentException("Please set values with 3 paramters: centerX,centerY,radius"); 24 | } 25 | final float centerX = coords[0]; 26 | final float centerY = coords[1]; 27 | final float radius = coords[2]; 28 | set(new PointF(centerX, centerY), radius); 29 | } 30 | 31 | public void set(PointF center,float radius){ 32 | this.center = center; 33 | this.radius = radius; 34 | this.originRadius = radius; 35 | } 36 | 37 | @Override 38 | public PointF getCenter(){ 39 | return center; 40 | } 41 | 42 | @Override 43 | public void draw(Canvas canvas) { 44 | drawPaint.setAlpha(alaph); 45 | canvas.drawCircle(center.x, center.y, radius, drawPaint); 46 | } 47 | 48 | @Override 49 | public void scale(float scale,float centerX,float centerY) { 50 | PointF newCenter = ScaleUtility.scaleByPoint(center.x,center.y,centerX,centerY,scale); 51 | radius *= scale; 52 | center.set(newCenter.x,newCenter.y); 53 | //update the bubble position 54 | if( displayBubble != null ){ 55 | displayBubble.resetPosition(this); 56 | } 57 | } 58 | 59 | @Override 60 | public void translate(float deltaX, float deltaY) { 61 | center.x += deltaX; 62 | center.y += deltaY; 63 | } 64 | 65 | @Override 66 | public boolean inArea(float x, float y) { 67 | boolean ret = false; 68 | float dx = center.x - Math.abs(x); 69 | float dy = center.y - Math.abs(y); 70 | float d = (float)Math.sqrt((dx*dx)+(dy*dy)); 71 | if (d xPoints = new ArrayList(); 17 | ArrayList yPoints = new ArrayList(); 18 | 19 | // centroid point for this poly 20 | float _x; 21 | float _y; 22 | 23 | int pointCount; 24 | 25 | // bounding box 26 | float top = -1; 27 | float bottom = -1; 28 | float left = -1; 29 | float right = -1; 30 | 31 | public PolyShape(Object tag, int coverColor) { 32 | super(tag, coverColor); 33 | } 34 | 35 | @Override 36 | public void setValues(float... coords) { 37 | int i = 0; 38 | while ((i+1)y) != (yPoints.get(j)>y)) && 121 | (x < (xPoints.get(j)- xPoints.get(i)) * (y- yPoints.get(i)) / (yPoints.get(j)- yPoints.get(i)) + xPoints.get(i)) ) 122 | c = !c; 123 | } 124 | return c; 125 | } 126 | 127 | @Override 128 | public PointF getCenter() { 129 | return null; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/support/RectShape.java: -------------------------------------------------------------------------------- 1 | /** 2 | * author : 桥下一粒砂 (chenyoca@gmail.com) 3 | * date : 13-5-21 4 | * TODO 5 | */ 6 | package net.yoojia.imagemap.support; 7 | 8 | import android.graphics.Canvas; 9 | import android.graphics.PointF; 10 | 11 | public class RectShape extends Shape{ 12 | 13 | private float left; 14 | private float top; 15 | private float bottom; 16 | private float right; 17 | 18 | public RectShape(Object tag, int coverColor) { 19 | super(tag, coverColor); 20 | } 21 | 22 | /** 23 | * set Left,Top,Right,Bottim 24 | * @param coords left,top,right,buttom 25 | */ 26 | @Override 27 | public void setValues(float... coords) { 28 | if(coords == null || coords.length != 4){ 29 | throw new IllegalArgumentException("Please set values with 4 paramters: left,top,right,buttom"); 30 | } 31 | left = coords[0]; 32 | top = coords[1]; 33 | right = coords[2]; 34 | bottom = coords[3]; 35 | } 36 | 37 | @Override 38 | public void draw(Canvas canvas) { 39 | drawPaint.setAlpha(alaph); 40 | canvas.drawRect(left,top,right,bottom,drawPaint); 41 | } 42 | 43 | @Override 44 | public void scale(float scale, float centerX, float centerY) { 45 | 46 | PointF leftTop = ScaleUtility.scaleByPoint(left,top,centerX,centerY,scale); 47 | left = leftTop.x; 48 | top = leftTop.y; 49 | 50 | PointF righBottom = ScaleUtility.scaleByPoint(right,bottom,centerX,centerY,scale); 51 | right = righBottom.x; 52 | bottom = righBottom.y; 53 | } 54 | 55 | @Override 56 | public void translate(float deltaX, float deltaY) { 57 | left += deltaX; 58 | right += deltaX; 59 | top += deltaY; 60 | bottom += deltaY; 61 | } 62 | 63 | @Override 64 | public boolean inArea(float x, float y) { 65 | boolean ret = false; 66 | if ((x > left) && (x < right)) { 67 | if ((y > top) && (y < bottom)) { 68 | ret = true; 69 | } 70 | } 71 | return ret; 72 | } 73 | 74 | @Override 75 | public PointF getCenter() { 76 | float centerX = (left + right)/2.0f; 77 | float centerY = (top + bottom)/2.0f; 78 | return new PointF(centerX,centerY); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/support/ScaleUtility.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap.support; 2 | 3 | import android.graphics.Matrix; 4 | import android.graphics.PointF; 5 | 6 | /** 7 | * author : chenyoca@gmail.com 8 | * date : 13-5-19 9 | * A utility for scale options. 10 | */ 11 | public class ScaleUtility { 12 | 13 | /** 14 | * Get the new position object when scale with a given point. 15 | * @param targetPointX the x position before scale 16 | * @param targetPointY the y position before scale 17 | * @param scaleCenterX the scale point ,x position 18 | * @param scaleCenterY the scale point ,y position 19 | * @param scale scale 20 | * @return the new position after scale 21 | */ 22 | public static PointF scaleByPoint(float targetPointX,float targetPointY,float scaleCenterX,float scaleCenterY,float scale){ 23 | Matrix matrix = new Matrix(); 24 | // move the matrix to target position 25 | // then, scale with the given point and scale. 26 | matrix.preTranslate(targetPointX,targetPointY); 27 | matrix.postScale(scale,scale,scaleCenterX,scaleCenterY); 28 | float[] values = new float[9]; 29 | matrix.getValues(values); 30 | return new PointF(values[Matrix.MTRANS_X],values[Matrix.MTRANS_Y]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ImageMap/src/main/java/net/yoojia/imagemap/support/Shape.java: -------------------------------------------------------------------------------- 1 | package net.yoojia.imagemap.support; 2 | 3 | import android.graphics.*; 4 | 5 | public abstract class Shape { 6 | 7 | public final int color; 8 | public final Object tag; 9 | 10 | protected Bubble displayBubble; 11 | protected int alaph = 255; 12 | protected final Paint drawPaint; 13 | 14 | protected final static Paint cleanPaint; 15 | 16 | static { 17 | cleanPaint = new Paint(); 18 | cleanPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 19 | } 20 | 21 | public Shape(Object tag, int coverColor){ 22 | this.tag = tag; 23 | this.color = coverColor; 24 | 25 | drawPaint = new Paint(); 26 | drawPaint.setColor(coverColor); 27 | drawPaint.setStyle(Paint.Style.FILL); 28 | drawPaint.setAntiAlias(true); 29 | drawPaint.setFilterBitmap(true); 30 | 31 | } 32 | 33 | public void setAlaph(int alaph){ 34 | this.alaph = alaph; 35 | } 36 | 37 | public void createBubbleRelation(Bubble displayBubble) { 38 | this.displayBubble = displayBubble; 39 | } 40 | 41 | public void cleanBubbleRelation(){ 42 | this.displayBubble = null; 43 | } 44 | 45 | public abstract void setValues(float...coords); 46 | 47 | /** 48 | * Set coords. Split by char ',' . 49 | * @param coords coords 50 | */ 51 | public void setValues(String coords){ 52 | String[] parametrs = coords.split(","); 53 | final int size = parametrs.length; 54 | final float[] args = new float[size]; 55 | for(int i=0;i shapes); 16 | 17 | void removeShape(Object tag); 18 | } -------------------------------------------------------------------------------- /ImageMap/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImageMap/src/main/res/drawable-nodpi/pink_girl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/ImageMap/src/main/res/drawable-nodpi/pink_girl.jpg -------------------------------------------------------------------------------- /ImageMap/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ImageMap/src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ImageMap/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /ImageMap/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ImageMap 5 | Settings 6 | Hello world! 7 | 8 | 9 | -------------------------------------------------------------------------------- /ImageMap/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Image Map 2 | 3 | 一个类似HTML map标签功能的Android组件。可以实现HTML里图片热点映射。 4 | 5 | An android view like html map tag. 6 | 7 | ## 项目结构 8 | 9 | 此项目是在Android Stdio IDE中创建的,其目录结构与Eclipse很不同。 10 | 如果使用Eclipse打开,需要把路径设置到 ...../ImageMap/src/main 里。 11 | 12 | ## 截图 13 | 14 | ![ScreenShot](https://raw.github.com/chenyoca/android-image-map/master/screenshot.png) 15 | 16 | ## 特点 17 | 18 | * 支持图像缩放和拖动。图中色块覆盖的区域为图片热点。图像缩放和拖动时,这些热点区域也会跟着缩放和移动。 19 | 20 | * 支持 Circle,Rect,Poly 三种形状。对应的类为 CircleShape, RectShape, PolyShape。向ImageMap对象中添加即可。 21 | 22 | * 支持纯生HTML map数据,可以直接把HTML Map生成的coords数据直接设置到Shape中。 23 | 24 | * 支持Bitmap对象,res目录下的drawable文件等数据来源。 25 | 26 | * 在代码中创建或者XML中布局。 27 | 28 | ## 使用 29 | 30 | 详细代码见MainActivity.java文件。项目为Android可运行项目,直接运行即可。 31 | 32 | ```java 33 | 34 | //取得在XML中布局的ImageMap对象,并设置图片 35 | 36 | ImageMap map = (ImageMap) findViewById(R.id.imagemap); 37 | Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.pink_girl,new BitmapFactory.Options()); 38 | map.setMapBitmap(bitmap); 39 | 40 | // 设置Shape被点击时的监听 41 | // 注意:同一时刻只有一个Shape被监听点击 42 | map.setOnShapeClickListener(new ShapeExtension.OnShapeClickListener() { 43 | @Override 44 | public void onShapeClick(Shape shape, float xOnImage, float yOnImage) { 45 | String msg = "Shape "+shape.tag+" clicked !"; 46 | Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show(); 47 | } 48 | }); 49 | 50 | // 圆形 51 | // "black"是唯一标识这个Shape的字符串,不可重复。 52 | Shape black = new CircleShape("black", Color.BLACK); 53 | black.setValues(633,122,15); 54 | map.addShape(black); 55 | 56 | // 矩形 57 | Shape black = new CircleShape("black", Color.BLACK); 58 | black.setValues(633,122,15); 59 | map.addShape(black); 60 | 61 | // 多边形 62 | Shape black = new CircleShape("black", Color.BLACK); 63 | black.setValues(633,122,15); 64 | map.addShape(black); 65 | 66 | ``` 67 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/build.gradle -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.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 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CFutureTeam/android-image-map/e262df5a5627919497ba65012a85e035a757daba/screenshot.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':ImageMap' 2 | --------------------------------------------------------------------------------