diff --git a/.gitignore b/.gitignore index de0f16a..72b147d 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ gen/ # Gradle files .gradle/ -build/ \ No newline at end of file +build/ + +*.iml \ No newline at end of file diff --git a/README.md b/README.md index aebdbdb..6867797 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,33 @@ -# ![Logo](https://github.com/xiaopansky/RubberView/raw/master/app/src/main/res/drawable-mdpi/ic_launcher.png) RubberView +# ![logo_image] ScratchAwardView -这是Android上的一个涂抹视图,用于实现刮奖效果 +![Platform][platform_image] +[![API][min_api_image]][min_api_link] +[![Release Version][release_version_image]][release_version-link] -![Sample](https://github.com/xiaopansky/RubberView/raw/master/docs/sample.png) +这是一个刮刮卡组件,用于实现刮奖效果 + +![Sample](docs/sample.png) + +## 开始使用 + +### 1. 导入 ScratchAwardView + +在 app 的 build.gradle 文件的 dependencies 节点中加入依赖 + +```groovy +dependencies{ + implementation 'me.panpf:scratch-award-view:$lastVersionName' +} +``` + +请自行替换 `$lastVersionName` 为最新的版本:[![Release Version][release_version_image]][release_version-link] `(不要v)` + +最低支持 `Android 2.3` + +### 2. 在布局中使用 + +你只需将 ScratchAwardView 覆盖在中奖提示语之上即可,这样的用法很灵活,因此你可以决定你的中奖提示语是一段文字或者一张图片,如下所示: -##Usage guide -你只需将RubberView覆盖在中奖提示语之上即可,这样的用法很灵活,因此你可以决定你的中奖提示语是一段文字或者一张图片,如下所示: ```xml - ``` + 扩展功能: ->* 调用setMaskImage()方法自定义遮罩图片,默认的是灰色 ->* 调用setStrokeWidth()方法自定义画笔宽度 ->* 调用enableAcrossMonitor()方法监听用户划过的区域,你可以指定一个隐藏在RubberView下面的视图,当用户划过这个视图的时候就会触发回调 - -##Downloads ->* [android-rubber-view-1.1.2.jar](https://github.com/xiaopansky/RubberView/raw/master/releases/android-rubber-view-1.1.2.jar) ->* [android-rubber-view-1.1.2-with-src.jar](https://github.com/xiaopansky/RubberView/raw/master/releases/android-rubber-view-1.1.2-with-src.jar) - -##Change log - -####1.1.2 ->* 修复单击事件不灵敏的BUG ->* RubberView包名改为me.xiaopan.android.widget - -####1.1.1 ->* 修复当被ScrollView包括时,无法正常滑动的BUG - -####1.1.0 ->* 增加enableAcrossMonitor()方法,用于监听用户的滑动操作,实现滑过指定视图的时候触发回调 - -##License -```java -/* - * Copyright (C) 2013 Peng fei Pan - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -``` +* 调用 setMaskImage() 方法自定义遮罩图片,默认的是灰色 +* 调用 setStrokeWidth() 方法自定义画笔宽度 +* 调用 enableAcrossMonitor() 方法监听用户划过的区域,你可以指定一个隐藏在 ScratchAwardView 下面的视图,当用户划过这个视图的时候就会触发回调 + +## License + Copyright (C) 2017 Peng fei Pan + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +[logo_image]: sample/src/main/res/drawable-mdpi/ic_launcher.png +[platform_image]: https://img.shields.io/badge/Platform-Android-brightgreen.svg +[min_api_image]: https://img.shields.io/badge/API-10%2B-orange.svg +[min_api_link]: https://android-arsenal.com/api?level=10 +[release_version_image]: https://img.shields.io/github/release/panpf/scratch-award-view.svg +[release_version-link]: https://github.com/panpf/scratch-award-view/releases diff --git a/RubberView.iml b/RubberView.iml deleted file mode 100644 index 0bb6048..0000000 --- a/RubberView.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/app.iml b/app/app.iml deleted file mode 100644 index 5e9236d..0000000 --- a/app/app.iml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index aa4d2fc..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -apply plugin: 'android' - -android { - compileSdkVersion 19 - buildToolsVersion "19.1.0" - - defaultConfig { - applicationId "me.xiaopan.android.rubberview" - minSdkVersion 9 - targetSdkVersion 19 - versionCode 112 - versionName "1.1.2" - } - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml deleted file mode 100644 index 5a7389d..0000000 --- a/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/java/me/xiaopan/android/rubberview/sample/MainActivity.java b/app/src/main/java/me/xiaopan/android/rubberview/sample/MainActivity.java deleted file mode 100644 index 0ab6769..0000000 --- a/app/src/main/java/me/xiaopan/android/rubberview/sample/MainActivity.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.xiaopan.android.rubberview.sample; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; - -import me.xiaopan.android.rubberview.R; -import me.xiaopan.android.widget.RubberView; - -public class MainActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - final RubberView rubberView = (RubberView) findViewById(R.id.rubberView_main); - rubberView.enableAcrossMonitor(findViewById(R.id.text_main), new RubberView.OnAcrossHintViewListener() { - private boolean across; - @Override - public void onAcrossHintView(View hintView) { - if(!across){ - across = true; - rubberView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - } - } - }); - } -} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index a5ab20a..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index b1dbc64..0000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - RubberView - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index ff6c9d2..0000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/build.gradle b/build.gradle index a1d991f..a98c871 100644 --- a/build.gradle +++ b/build.gradle @@ -2,11 +2,13 @@ buildscript { repositories { - mavenCentral() + jcenter() + maven { url 'https://dl.google.com/dl/android/maven2/' } } dependencies { - classpath 'com.android.tools.build:gradle:0.12.+' - + classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -14,6 +16,7 @@ buildscript { allprojects { repositories { - mavenCentral() + jcenter() + maven { url 'https://dl.google.com/dl/android/maven2/' } } } diff --git a/docs/sample.png b/docs/sample.png index 0391476..a8b6c80 100644 Binary files a/docs/sample.png and b/docs/sample.png differ diff --git a/gradle.properties b/gradle.properties index 5d08ba7..87971af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,13 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true + +COMPILE_SDK_VERSION=25 +MIN_SDK_VERSION=10 +TARGET_SDK_VERSION=22 + +VERSION_CODE=120 +VERSION_NAME=1.2.0 + +ANDROID_SUPPORT_LIBRARY_VERSION=25.3.0 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1ef2911..7ed8429 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip +distributionUrl=http\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/releases/android-rubber-view-1.1.2-with-src.jar b/releases/android-rubber-view-1.1.2-with-src.jar deleted file mode 100644 index 39c3180..0000000 Binary files a/releases/android-rubber-view-1.1.2-with-src.jar and /dev/null differ diff --git a/releases/android-rubber-view-1.1.2.jar b/releases/android-rubber-view-1.1.2.jar deleted file mode 100644 index 6b0de67..0000000 Binary files a/releases/android-rubber-view-1.1.2.jar and /dev/null differ diff --git a/sample/build.gradle b/sample/build.gradle new file mode 100644 index 0000000..737cf82 --- /dev/null +++ b/sample/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion COMPILE_SDK_VERSION.toInteger() + + defaultConfig { + applicationId "me.panpf.scratch.sample" + + minSdkVersion MIN_SDK_VERSION.toInteger() + targetSdkVersion TARGET_SDK_VERSION.toInteger() + versionCode VERSION_CODE.toInteger() + versionName VERSION_NAME + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation "com.android.support:appcompat-v7:${ANDROID_SUPPORT_LIBRARY_VERSION}" + implementation project(':scratch-award-view') +} diff --git a/app/proguard-rules.pro b/sample/proguard-rules.pro similarity index 100% rename from app/proguard-rules.pro rename to sample/proguard-rules.pro diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d440e6a --- /dev/null +++ b/sample/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/ic_launcher-web.png b/sample/src/main/ic_launcher-web.png similarity index 100% rename from app/src/main/ic_launcher-web.png rename to sample/src/main/ic_launcher-web.png diff --git a/sample/src/main/java/me/panpf/scratch/sample/MainActivity.java b/sample/src/main/java/me/panpf/scratch/sample/MainActivity.java new file mode 100644 index 0000000..ffc62bf --- /dev/null +++ b/sample/src/main/java/me/panpf/scratch/sample/MainActivity.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 Peng fei Pan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package me.panpf.scratch.sample; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; + +import me.panpf.scratch.ScratchAwardView; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + final ScratchAwardView scratchAwardView = (ScratchAwardView) findViewById(R.id.rubberView_main); + scratchAwardView.enableAcrossMonitor(findViewById(R.id.text_main), new ScratchAwardView.OnAcrossHintViewListener() { + private boolean across; + + @Override + public void onAcrossHintView(View hintView) { + if (!across) { + across = true; + scratchAwardView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + } + }); + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/sample/src/main/res/drawable-hdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_launcher.png rename to sample/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/sample/src/main/res/drawable-mdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_launcher.png rename to sample/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/sample/src/main/res/drawable-xhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_launcher.png rename to sample/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/sample/src/main/res/drawable-xxhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_launcher.png rename to sample/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..67201fe --- /dev/null +++ b/sample/src/main/res/layout/activity_main.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/sample/src/main/res/values/colors.xml b/sample/src/main/res/values/colors.xml new file mode 100644 index 0000000..19d0822 --- /dev/null +++ b/sample/src/main/res/values/colors.xml @@ -0,0 +1,16 @@ + + + + #3F51B5 + #303F9F + #FF4081 + \ No newline at end of file diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml new file mode 100644 index 0000000..3171b3e --- /dev/null +++ b/sample/src/main/res/values/strings.xml @@ -0,0 +1,14 @@ + + + + ScratchAwardView + diff --git a/sample/src/main/res/values/styles.xml b/sample/src/main/res/values/styles.xml new file mode 100644 index 0000000..39e6585 --- /dev/null +++ b/sample/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/scratch-award-view/build.gradle b/scratch-award-view/build.gradle new file mode 100644 index 0000000..cec29b9 --- /dev/null +++ b/scratch-award-view/build.gradle @@ -0,0 +1,23 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion COMPILE_SDK_VERSION.toInteger() + + defaultConfig { + minSdkVersion MIN_SDK_VERSION.toInteger() + targetSdkVersion TARGET_SDK_VERSION.toInteger() + versionCode VERSION_CODE.toInteger() + versionName VERSION_NAME + + consumerProguardFiles 'proguard-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +apply from: "https://raw.githubusercontent.com/panpf/android-library-publish-to-jcenter/master/bintrayUpload.gradle" diff --git a/scratch-award-view/proguard-rules.pro b/scratch-award-view/proguard-rules.pro new file mode 100644 index 0000000..f142320 --- /dev/null +++ b/scratch-award-view/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in D:\Program Files\Android\android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/scratch-award-view/project.properties b/scratch-award-view/project.properties new file mode 100644 index 0000000..d07a605 --- /dev/null +++ b/scratch-award-view/project.properties @@ -0,0 +1,10 @@ +#project +project.name=scratch-award-view +project.groupId=me.panpf +project.artifactId=scratch-award-view +project.packaging=aar +project.siteUrl=https://github.com/panpf/scratch-award-view +project.gitUrl=https://github.com/panpf/scratch-award-view.git + +#javadoc +javadoc.name=ScratchAwardView \ No newline at end of file diff --git a/scratch-award-view/src/main/AndroidManifest.xml b/scratch-award-view/src/main/AndroidManifest.xml new file mode 100644 index 0000000..40091e7 --- /dev/null +++ b/scratch-award-view/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/java/me/xiaopan/android/widget/RubberView.java b/scratch-award-view/src/main/java/me/panpf/scratch/ScratchAwardView.java similarity index 65% rename from app/src/main/java/me/xiaopan/android/widget/RubberView.java rename to scratch-award-view/src/main/java/me/panpf/scratch/ScratchAwardView.java index 783625f..459ab8b 100644 --- a/app/src/main/java/me/xiaopan/android/widget/RubberView.java +++ b/scratch-award-view/src/main/java/me/panpf/scratch/ScratchAwardView.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Peng fei Pan + * Copyright (C) 2017 Peng fei Pan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,9 @@ * limitations under the License. */ -package me.xiaopan.android.widget; +package me.panpf.scratch; +import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -32,9 +33,9 @@ import android.view.View; import android.widget.ImageView; -public class RubberView extends View{ +public class ScratchAwardView extends View { private Paint drawPaint; - private Bitmap trackBitmap; // 轨迹图片,一会儿要在此图片上画滑动轨迹,然后通过Xfermode技术同遮罩层图片融合就能实现涂抹的效果 + private Bitmap trackBitmap; // 轨迹图片,一会儿要在此图片上画滑动轨迹,然后通过 Xfermode 技术同遮罩层图片融合就能实现涂抹的效果 private Canvas trackBitmapCanvas; private Xfermode xfermode; private Paint linePaint; // 触摸轨迹线画笔 @@ -49,15 +50,15 @@ public class RubberView extends View{ private GestureDetector gestureDetector; - public RubberView(Context context) { + public ScratchAwardView(Context context) { this(context, null, 0); } - public RubberView(Context context, AttributeSet attrs) { + public ScratchAwardView(Context context, AttributeSet attrs) { this(context, attrs, 0); } - public RubberView(Context context, AttributeSet attrs, int defStyleAttr) { + public ScratchAwardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); drawPaint = new Paint(); @@ -76,15 +77,61 @@ public RubberView(Context context, AttributeSet attrs, int defStyleAttr) { gestureDetector = new GestureDetector(getContext(), new EventHandleListener()); } + public static Rect computeSrcRect(Point sourceSize, Point targetSize, ImageView.ScaleType scaleType) { + if (scaleType == ImageView.ScaleType.CENTER_INSIDE || scaleType == ImageView.ScaleType.MATRIX || scaleType == ImageView.ScaleType.FIT_XY) { + return new Rect(0, 0, sourceSize.x, sourceSize.y); + } else { + float scale; + if (Math.abs(sourceSize.x - targetSize.x) < Math.abs(sourceSize.y - targetSize.y)) { + scale = (float) sourceSize.x / targetSize.x; + if ((int) (targetSize.y * scale) > sourceSize.y) { + scale = (float) sourceSize.y / targetSize.y; + } + } else { + scale = (float) sourceSize.y / targetSize.y; + if ((int) (targetSize.x * scale) > sourceSize.x) { + scale = (float) sourceSize.x / targetSize.x; + } + } + int srcLeft; + int srcTop; + int srcWidth = (int) (targetSize.x * scale); + int srcHeight = (int) (targetSize.y * scale); + if (scaleType == ImageView.ScaleType.FIT_START) { + srcLeft = 0; + srcTop = 0; + } else if (scaleType == ImageView.ScaleType.FIT_END) { + if (sourceSize.x > sourceSize.y) { + srcLeft = sourceSize.x - srcWidth; + srcTop = 0; + } else { + srcLeft = 0; + srcTop = sourceSize.y - srcHeight; + } + } else { + if (sourceSize.x > sourceSize.y) { + srcLeft = (sourceSize.x - srcWidth) / 2; + srcTop = 0; + } else { + srcLeft = 0; + srcTop = (sourceSize.y - srcHeight) / 2; + } + } + return new Rect(srcLeft, srcTop, srcLeft + srcWidth, srcTop + srcHeight); + } + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - int layerCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); + @SuppressLint("WrongConstant") + int layerCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, + Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.drawBitmap(trackBitmap, getPaddingLeft(), getPaddingTop(), drawPaint); drawPaint.setXfermode(xfermode); canvas.drawBitmap(maskBitmap, srcRect, dstRect, drawPaint); drawPaint.setXfermode(null); - if(!isInEditMode()){ + if (!isInEditMode()) { canvas.restoreToCount(layerCount); } } @@ -93,31 +140,31 @@ protected void onDraw(Canvas canvas) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - int width = right-left; - int height = bottom-top; + int width = right - left; + int height = bottom - top; // 初始化轨迹图片,稍后将在此图上绘制触摸轨迹 - if(trackBitmap == null){ - trackBitmap = Bitmap.createBitmap(width-getPaddingRight()-getPaddingLeft(), height-getPaddingBottom()-getPaddingTop(), Bitmap.Config.ARGB_8888); + if (trackBitmap == null) { + trackBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888); trackBitmapCanvas = new Canvas(trackBitmap); - // 如果已经创建了但是宽高有变化就重新创建 - }else if(trackBitmap.getWidth() != width-getPaddingRight()-getPaddingLeft() || trackBitmap.getHeight() != height-getPaddingBottom()-getPaddingTop()){ + // 如果已经创建了但是宽高有变化就重新创建 + } else if (trackBitmap.getWidth() != width - getPaddingRight() - getPaddingLeft() || trackBitmap.getHeight() != height - getPaddingBottom() - getPaddingTop()) { trackBitmap.recycle(); - trackBitmap = Bitmap.createBitmap(width-getPaddingRight()-getPaddingLeft(), height-getPaddingBottom()-getPaddingTop(), Bitmap.Config.ARGB_8888); + trackBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888); trackBitmapCanvas.setBitmap(trackBitmap); } // 初始化遮罩图片 - if(maskBitmap == null){ - maskBitmap = Bitmap.createBitmap(width-getPaddingRight()-getPaddingLeft(), height-getPaddingBottom()-getPaddingTop(), Bitmap.Config.ARGB_8888); + if (maskBitmap == null) { + maskBitmap = Bitmap.createBitmap(width - getPaddingRight() - getPaddingLeft(), height - getPaddingBottom() - getPaddingTop(), Bitmap.Config.ARGB_8888); new Canvas(maskBitmap).drawColor(defaultMaskColor); } // 初始化dst位置 - if(dstRect == null){ - dstRect = new Rect(getPaddingLeft(), getPaddingTop(), width-getPaddingRight(), height-getPaddingBottom()); - }else{ - dstRect.set(getPaddingLeft(), getPaddingTop(), width-getPaddingRight(), height-getPaddingBottom()); + if (dstRect == null) { + dstRect = new Rect(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom()); + } else { + dstRect.set(getPaddingLeft(), getPaddingTop(), width - getPaddingRight(), height - getPaddingBottom()); } srcRect = computeSrcRect(new Point(maskBitmap.getWidth(), maskBitmap.getHeight()), new Point(dstRect.width(), dstRect.height()), ImageView.ScaleType.CENTER_CROP); @@ -130,8 +177,10 @@ public boolean onTouchEvent(MotionEvent event) { /** * 设置遮罩图片 + * * @param maskBitmap 遮罩图片 */ + @SuppressWarnings("unused") public void setMaskImage(Bitmap maskBitmap) { this.maskBitmap = maskBitmap; requestLayout(); @@ -139,12 +188,14 @@ public void setMaskImage(Bitmap maskBitmap) { /** * 设置遮罩图片 + * * @param color 遮罩图片的颜色,稍后将使用此颜色创建一张图片 */ + @SuppressWarnings("unused") public void setMaskImage(int color) { this.defaultMaskColor = color; - if(maskBitmap != null){ - if(!maskBitmap.isRecycled()){ + if (maskBitmap != null) { + if (!maskBitmap.isRecycled()) { maskBitmap.recycle(); } maskBitmap = null; @@ -154,71 +205,30 @@ public void setMaskImage(int color) { /** * 设置画笔的宽度 + * * @param strokeWidth 画笔的宽度 */ + @SuppressWarnings("unused") public void setStrokeWidth(int strokeWidth) { this.linePaint.setStrokeWidth(strokeWidth); } /** * 激活监听划过提示视图的功能 - * @param hintView 提示视图,当用户划过此视图的时候就会回调监听器,一般来说此视图应该是隐藏在RubberView之下的中奖提示视图 + * + * @param hintView 提示视图,当用户划过此视图的时候就会回调监听器,一般来说此视图应该是隐藏在 {@link ScratchAwardView} 之下的中奖提示视图 * @param onAcrossHintViewListener 当用户划过提示视图的时候就会回调此监听器 */ - public void enableAcrossMonitor(View hintView, OnAcrossHintViewListener onAcrossHintViewListener){ + public void enableAcrossMonitor(View hintView, OnAcrossHintViewListener onAcrossHintViewListener) { this.hintView = hintView; this.onAcrossHintViewListener = onAcrossHintViewListener; } - public static Rect computeSrcRect(Point sourceSize, Point targetSize, ImageView.ScaleType scaleType){ - if(scaleType == ImageView.ScaleType.CENTER_INSIDE || scaleType == ImageView.ScaleType.MATRIX || scaleType == ImageView.ScaleType.FIT_XY){ - return new Rect(0, 0, sourceSize.x, sourceSize.y); - }else{ - float scale; - if(Math.abs(sourceSize.x - targetSize.x) < Math.abs(sourceSize.y - targetSize.y)){ - scale = (float) sourceSize.x/targetSize.x; - if((int)(targetSize.y*scale) > sourceSize.y){ - scale = (float) sourceSize.y/targetSize.y; - } - }else{ - scale = (float) sourceSize.y/targetSize.y; - if((int)(targetSize.x*scale) > sourceSize.x){ - scale = (float) sourceSize.x/targetSize.x; - } - } - int srcLeft; - int srcTop; - int srcWidth = (int)(targetSize.x*scale); - int srcHeight = (int)(targetSize.y*scale); - if (scaleType == ImageView.ScaleType.FIT_START) { - srcLeft = 0; - srcTop = 0; - } else if (scaleType == ImageView.ScaleType.FIT_END) { - if(sourceSize.x > sourceSize.y){ - srcLeft = sourceSize.x - srcWidth; - srcTop = 0; - }else{ - srcLeft = 0; - srcTop = sourceSize.y - srcHeight; - } - } else { - if(sourceSize.x > sourceSize.y){ - srcLeft = (sourceSize.x - srcWidth)/2; - srcTop = 0; - }else{ - srcLeft = 0; - srcTop = (sourceSize.y - srcHeight)/2; - } - } - return new Rect(srcLeft, srcTop, srcLeft+srcWidth, srcTop+srcHeight); - } - } - - public interface OnAcrossHintViewListener{ - public void onAcrossHintView(View hintView); + public interface OnAcrossHintViewListener { + void onAcrossHintView(View hintView); } - private class EventHandleListener implements GestureDetector.OnGestureListener{ + private class EventHandleListener implements GestureDetector.OnGestureListener { private float downX; private float downY; private float moveX; @@ -228,7 +238,7 @@ private class EventHandleListener implements GestureDetector.OnGestureListener{ @Override public boolean onDown(MotionEvent event) { - if(getParent() != null){ + if (getParent() != null) { getParent().requestDisallowInterceptTouchEvent(true); } downX = event.getX(); @@ -244,7 +254,7 @@ public void onShowPress(MotionEvent e) { @Override public boolean onSingleTapUp(MotionEvent e) { - if(isEnabled() && isClickable()){ + if (isEnabled() && isClickable()) { performClick(); } return true; @@ -259,12 +269,12 @@ public boolean onScroll(MotionEvent e1, MotionEvent event, float distanceX, floa downY = moveY; invalidate(); - if(allowAcrossCallback){ - if(hintViewGlobalVisibleRect == null){ + if (allowAcrossCallback) { + if (hintViewGlobalVisibleRect == null) { hintViewGlobalVisibleRect = new Rect(); hintView.getGlobalVisibleRect(hintViewGlobalVisibleRect); } - if(hintViewGlobalVisibleRect.contains((int)event.getRawX(), (int)event.getRawY())){ + if (hintViewGlobalVisibleRect.contains((int) event.getRawX(), (int) event.getRawY())) { onAcrossHintViewListener.onAcrossHintView(hintView); allowAcrossCallback = false; } diff --git a/settings.gradle b/settings.gradle index e7b4def..f919000 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app' +include ':sample', "scratch-award-view"