Permalink
Please sign in to comment.
Showing
with
738 additions
and 0 deletions.
- +1 −0 app/.gitignore
- +27 −0 app/build.gradle
- +17 −0 app/proguard-rules.pro
- +20 −0 app/src/main/AndroidManifest.xml
- +35 −0 app/src/main/java/com/camnter/easycountdownsurfaceview/demo/MainActivity.java
- +23 −0 app/src/main/res/layout/activity_main.xml
- BIN app/src/main/res/mipmap-hdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-mdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xhdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xxhdpi/ic_launcher.png
- BIN app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
- +6 −0 app/src/main/res/values-w820dp/dimens.xml
- +6 −0 app/src/main/res/values/colors.xml
- +5 −0 app/src/main/res/values/dimens.xml
- +3 −0 app/src/main/res/values/strings.xml
- +11 −0 app/src/main/res/values/styles.xml
- +23 −0 build.gradle
- +18 −0 gradle.properties
- BIN gradle/wrapper/gradle-wrapper.jar
- +6 −0 gradle/wrapper/gradle-wrapper.properties
- +160 −0 gradlew
- +90 −0 gradlew.bat
- +1 −0 library/.gitignore
- +25 −0 library/build.gradle
- +17 −0 library/proguard-rules.pro
- +9 −0 library/src/main/AndroidManifest.xml
- +231 −0 library/src/main/java/com/camnter/easycountdownsurfaceview/EasyCountDownSurfaceView.java
- +3 −0 library/src/main/res/values/strings.xml
- +1 −0 settings.gradle
1
app/.gitignore
@@ -0,0 +1 @@ | ||
+/build |
27
app/build.gradle
@@ -0,0 +1,27 @@ | ||
+apply plugin: 'com.android.application' | ||
+ | ||
+android { | ||
+ compileSdkVersion 23 | ||
+ buildToolsVersion "23.0.2" | ||
+ | ||
+ defaultConfig { | ||
+ applicationId "com.camnter.easycountdownsurfaceview.demo" | ||
+ minSdkVersion 10 | ||
+ targetSdkVersion 23 | ||
+ versionCode 1 | ||
+ versionName "1.0" | ||
+ } | ||
+ buildTypes { | ||
+ release { | ||
+ minifyEnabled false | ||
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
+dependencies { | ||
+ compile fileTree(include: ['*.jar'], dir: 'libs') | ||
+ testCompile 'junit:junit:4.12' | ||
+ compile 'com.android.support:appcompat-v7:23.2.0' | ||
+ compile project(':library') | ||
+} |
17
app/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 /Users/CaMnter/Android/adt-bundle-mac-x86_64-20140702/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 *; | ||
+#} |
20
app/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@ | ||
+<?xml version="1.0" encoding="utf-8"?> | ||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
+ package="com.camnter.easycountdownsurfaceview.demo"> | ||
+ | ||
+ <application | ||
+ android:allowBackup="true" | ||
+ android:icon="@mipmap/ic_launcher" | ||
+ android:label="@string/app_name" | ||
+ android:supportsRtl="true" | ||
+ android:theme="@style/AppTheme"> | ||
+ <activity android:name=".MainActivity"> | ||
+ <intent-filter> | ||
+ <action android:name="android.intent.action.MAIN" /> | ||
+ | ||
+ <category android:name="android.intent.category.LAUNCHER" /> | ||
+ </intent-filter> | ||
+ </activity> | ||
+ </application> | ||
+ | ||
+</manifest> |
35
app/src/main/java/com/camnter/easycountdownsurfaceview/demo/MainActivity.java
@@ -0,0 +1,35 @@ | ||
+package com.camnter.easycountdownsurfaceview.demo; | ||
+ | ||
+import android.os.Bundle; | ||
+import android.support.v7.app.AppCompatActivity; | ||
+import android.view.View; | ||
+ | ||
+import com.camnter.easycountdownsurfaceview.EasyCountDownSurfaceView; | ||
+ | ||
+public class MainActivity extends AppCompatActivity implements View.OnClickListener { | ||
+ | ||
+ private EasyCountDownSurfaceView baseSv; | ||
+ | ||
+ @Override | ||
+ protected void onCreate(Bundle savedInstanceState) { | ||
+ super.onCreate(savedInstanceState); | ||
+ setContentView(R.layout.activity_main); | ||
+ this.baseSv = (EasyCountDownSurfaceView) this.findViewById(R.id.base_sv); | ||
+ this.findViewById(R.id.start).setOnClickListener(this); | ||
+ } | ||
+ | ||
+ /** | ||
+ * Called when a view has been clicked. | ||
+ * | ||
+ * @param v The view that was clicked. | ||
+ */ | ||
+ @Override | ||
+ public void onClick(View v) { | ||
+ switch (v.getId()) { | ||
+ case R.id.start: | ||
+ this.baseSv.start(); | ||
+ break; | ||
+ } | ||
+ } | ||
+ | ||
+} |
23
app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,23 @@ | ||
+<?xml version="1.0" encoding="utf-8"?> | ||
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
+ xmlns:tools="http://schemas.android.com/tools" | ||
+ android:layout_width="match_parent" | ||
+ android:layout_height="match_parent" | ||
+ android:paddingBottom="@dimen/activity_vertical_margin" | ||
+ android:paddingLeft="@dimen/activity_horizontal_margin" | ||
+ android:paddingRight="@dimen/activity_horizontal_margin" | ||
+ android:paddingTop="@dimen/activity_vertical_margin" | ||
+ tools:context="com.camnter.easycountdownsurfaceview.demo.MainActivity"> | ||
+ | ||
+ <com.camnter.easycountdownsurfaceview.EasyCountDownSurfaceView | ||
+ android:id="@+id/base_sv" | ||
+ android:layout_width="500dp" | ||
+ android:layout_height="100dp" /> | ||
+ | ||
+ <Button | ||
+ android:id="@+id/start" | ||
+ android:layout_width="wrap_content" | ||
+ android:layout_height="wrap_content" | ||
+ android:layout_alignParentBottom="true" | ||
+ android:text="begin" /> | ||
+</RelativeLayout> |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6
app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@ | ||
+<resources> | ||
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml | ||
+ (such as screen margins) for screens with more than 820dp of available width. This | ||
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> | ||
+ <dimen name="activity_horizontal_margin">64dp</dimen> | ||
+</resources> |
6
app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@ | ||
+<?xml version="1.0" encoding="utf-8"?> | ||
+<resources> | ||
+ <color name="colorPrimary">#3F51B5</color> | ||
+ <color name="colorPrimaryDark">#303F9F</color> | ||
+ <color name="colorAccent">#FF4081</color> | ||
+</resources> |
5
app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@ | ||
+<resources> | ||
+ <!-- Default screen margins, per the Android Design guidelines. --> | ||
+ <dimen name="activity_horizontal_margin">16dp</dimen> | ||
+ <dimen name="activity_vertical_margin">16dp</dimen> | ||
+</resources> |
3
app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@ | ||
+<resources> | ||
+ <string name="app_name">EasyCountDownSurfaceView</string> | ||
+</resources> |
11
app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@ | ||
+<resources> | ||
+ | ||
+ <!-- Base application theme. --> | ||
+ <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | ||
+ <!-- Customize your theme here. --> | ||
+ <item name="colorPrimary">@color/colorPrimary</item> | ||
+ <item name="colorPrimaryDark">@color/colorPrimaryDark</item> | ||
+ <item name="colorAccent">@color/colorAccent</item> | ||
+ </style> | ||
+ | ||
+</resources> |
23
build.gradle
@@ -0,0 +1,23 @@ | ||
+// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
+ | ||
+buildscript { | ||
+ repositories { | ||
+ jcenter() | ||
+ } | ||
+ dependencies { | ||
+ classpath 'com.android.tools.build:gradle:2.0.0-beta6' | ||
+ | ||
+ // NOTE: Do not place your application dependencies here; they belong | ||
+ // in the individual module build.gradle files | ||
+ } | ||
+} | ||
+ | ||
+allprojects { | ||
+ repositories { | ||
+ jcenter() | ||
+ } | ||
+} | ||
+ | ||
+task clean(type: Delete) { | ||
+ delete rootProject.buildDir | ||
+} |
18
gradle.properties
@@ -0,0 +1,18 @@ | ||
+# Project-wide Gradle settings. | ||
+ | ||
+# IDE (e.g. Android Studio) users: | ||
+# Gradle settings configured through the IDE *will override* | ||
+# any settings specified in this file. | ||
+ | ||
+# For more details on how to configure your build environment visit | ||
+# http://www.gradle.org/docs/current/userguide/build_environment.html | ||
+ | ||
+# Specifies the JVM arguments used for the daemon process. | ||
+# The setting is particularly useful for tweaking memory settings. | ||
+# Default value: -Xmx10248m -XX:MaxPermSize=256m | ||
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 | ||
+ | ||
+# 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 |
BIN
gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@ | ||
+#Mon Dec 28 10:00:20 PST 2015 | ||
+distributionBase=GRADLE_USER_HOME | ||
+distributionPath=wrapper/dists | ||
+zipStoreBase=GRADLE_USER_HOME | ||
+zipStorePath=wrapper/dists | ||
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip |
160
gradlew
@@ -0,0 +1,160 @@ | ||
+#!/usr/bin/env bash | ||
+ | ||
+############################################################################## | ||
+## | ||
+## Gradle start up script for UN*X | ||
+## | ||
+############################################################################## | ||
+ | ||
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
+DEFAULT_JVM_OPTS="" | ||
+ | ||
+APP_NAME="Gradle" | ||
+APP_BASE_NAME=`basename "$0"` | ||
+ | ||
+# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
+MAX_FD="maximum" | ||
+ | ||
+warn ( ) { | ||
+ echo "$*" | ||
+} | ||
+ | ||
+die ( ) { | ||
+ echo | ||
+ echo "$*" | ||
+ echo | ||
+ exit 1 | ||
+} | ||
+ | ||
+# OS specific support (must be 'true' or 'false'). | ||
+cygwin=false | ||
+msys=false | ||
+darwin=false | ||
+case "`uname`" in | ||
+ CYGWIN* ) | ||
+ cygwin=true | ||
+ ;; | ||
+ Darwin* ) | ||
+ darwin=true | ||
+ ;; | ||
+ MINGW* ) | ||
+ msys=true | ||
+ ;; | ||
+esac | ||
+ | ||
+# Attempt to set APP_HOME | ||
+# Resolve links: $0 may be a link | ||
+PRG="$0" | ||
+# Need this for relative symlinks. | ||
+while [ -h "$PRG" ] ; do | ||
+ ls=`ls -ld "$PRG"` | ||
+ link=`expr "$ls" : '.*-> \(.*\)$'` | ||
+ if expr "$link" : '/.*' > /dev/null; then | ||
+ PRG="$link" | ||
+ else | ||
+ PRG=`dirname "$PRG"`"/$link" | ||
+ fi | ||
+done | ||
+SAVED="`pwd`" | ||
+cd "`dirname \"$PRG\"`/" >/dev/null | ||
+APP_HOME="`pwd -P`" | ||
+cd "$SAVED" >/dev/null | ||
+ | ||
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
+ | ||
+# Determine the Java command to use to start the JVM. | ||
+if [ -n "$JAVA_HOME" ] ; then | ||
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
+ # IBM's JDK on AIX uses strange locations for the executables | ||
+ JAVACMD="$JAVA_HOME/jre/sh/java" | ||
+ else | ||
+ JAVACMD="$JAVA_HOME/bin/java" | ||
+ fi | ||
+ if [ ! -x "$JAVACMD" ] ; then | ||
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
+ | ||
+Please set the JAVA_HOME variable in your environment to match the | ||
+location of your Java installation." | ||
+ fi | ||
+else | ||
+ JAVACMD="java" | ||
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
+ | ||
+Please set the JAVA_HOME variable in your environment to match the | ||
+location of your Java installation." | ||
+fi | ||
+ | ||
+# Increase the maximum file descriptors if we can. | ||
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then | ||
+ MAX_FD_LIMIT=`ulimit -H -n` | ||
+ if [ $? -eq 0 ] ; then | ||
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
+ MAX_FD="$MAX_FD_LIMIT" | ||
+ fi | ||
+ ulimit -n $MAX_FD | ||
+ if [ $? -ne 0 ] ; then | ||
+ warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
+ fi | ||
+ else | ||
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
+ fi | ||
+fi | ||
+ | ||
+# For Darwin, add options to specify how the application appears in the dock | ||
+if $darwin; then | ||
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
+fi | ||
+ | ||
+# For Cygwin, switch paths to Windows format before running java | ||
+if $cygwin ; then | ||
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
+ JAVACMD=`cygpath --unix "$JAVACMD"` | ||
+ | ||
+ # We build the pattern for arguments to be converted via cygpath | ||
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
+ SEP="" | ||
+ for dir in $ROOTDIRSRAW ; do | ||
+ ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
+ SEP="|" | ||
+ done | ||
+ OURCYGPATTERN="(^($ROOTDIRS))" | ||
+ # Add a user-defined pattern to the cygpath arguments | ||
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
+ fi | ||
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
+ i=0 | ||
+ for arg in "$@" ; do | ||
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
+ | ||
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
+ else | ||
+ eval `echo args$i`="\"$arg\"" | ||
+ fi | ||
+ i=$((i+1)) | ||
+ done | ||
+ case $i in | ||
+ (0) set -- ;; | ||
+ (1) set -- "$args0" ;; | ||
+ (2) set -- "$args0" "$args1" ;; | ||
+ (3) set -- "$args0" "$args1" "$args2" ;; | ||
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
+ esac | ||
+fi | ||
+ | ||
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | ||
+function splitJvmOpts() { | ||
+ JVM_OPTS=("$@") | ||
+} | ||
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | ||
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | ||
+ | ||
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" |
90
gradlew.bat
@@ -0,0 +1,90 @@ | ||
+@if "%DEBUG%" == "" @echo off | ||
+@rem ########################################################################## | ||
+@rem | ||
+@rem Gradle startup script for Windows | ||
+@rem | ||
+@rem ########################################################################## | ||
+ | ||
+@rem Set local scope for the variables with windows NT shell | ||
+if "%OS%"=="Windows_NT" setlocal | ||
+ | ||
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
+set DEFAULT_JVM_OPTS= | ||
+ | ||
+set DIRNAME=%~dp0 | ||
+if "%DIRNAME%" == "" set DIRNAME=. | ||
+set APP_BASE_NAME=%~n0 | ||
+set APP_HOME=%DIRNAME% | ||
+ | ||
+@rem Find java.exe | ||
+if defined JAVA_HOME goto findJavaFromJavaHome | ||
+ | ||
+set JAVA_EXE=java.exe | ||
+%JAVA_EXE% -version >NUL 2>&1 | ||
+if "%ERRORLEVEL%" == "0" goto init | ||
+ | ||
+echo. | ||
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
+echo. | ||
+echo Please set the JAVA_HOME variable in your environment to match the | ||
+echo location of your Java installation. | ||
+ | ||
+goto fail | ||
+ | ||
+:findJavaFromJavaHome | ||
+set JAVA_HOME=%JAVA_HOME:"=% | ||
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
+ | ||
+if exist "%JAVA_EXE%" goto init | ||
+ | ||
+echo. | ||
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
+echo. | ||
+echo Please set the JAVA_HOME variable in your environment to match the | ||
+echo location of your Java installation. | ||
+ | ||
+goto fail | ||
+ | ||
+:init | ||
+@rem Get command-line arguments, handling Windowz variants | ||
+ | ||
+if not "%OS%" == "Windows_NT" goto win9xME_args | ||
+if "%@eval[2+2]" == "4" goto 4NT_args | ||
+ | ||
+:win9xME_args | ||
+@rem Slurp the command line arguments. | ||
+set CMD_LINE_ARGS= | ||
+set _SKIP=2 | ||
+ | ||
+:win9xME_args_slurp | ||
+if "x%~1" == "x" goto execute | ||
+ | ||
+set CMD_LINE_ARGS=%* | ||
+goto execute | ||
+ | ||
+:4NT_args | ||
+@rem Get arguments from the 4NT Shell from JP Software | ||
+set CMD_LINE_ARGS=%$ | ||
+ | ||
+:execute | ||
+@rem Setup the command line | ||
+ | ||
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
+ | ||
+@rem Execute Gradle | ||
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
+ | ||
+:end | ||
+@rem End local scope for the variables with windows NT shell | ||
+if "%ERRORLEVEL%"=="0" goto mainEnd | ||
+ | ||
+:fail | ||
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
+rem the _cmd.exe /c_ return code! | ||
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
+exit /b 1 | ||
+ | ||
+:mainEnd | ||
+if "%OS%"=="Windows_NT" endlocal | ||
+ | ||
+:omega |
1
library/.gitignore
@@ -0,0 +1 @@ | ||
+/build |
25
library/build.gradle
@@ -0,0 +1,25 @@ | ||
+apply plugin: 'com.android.library' | ||
+ | ||
+android { | ||
+ compileSdkVersion 23 | ||
+ buildToolsVersion "23.0.2" | ||
+ | ||
+ defaultConfig { | ||
+ minSdkVersion 10 | ||
+ targetSdkVersion 23 | ||
+ versionCode 1 | ||
+ versionName "1.0" | ||
+ } | ||
+ buildTypes { | ||
+ release { | ||
+ minifyEnabled false | ||
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||
+ } | ||
+ } | ||
+} | ||
+ | ||
+dependencies { | ||
+ compile fileTree(dir: 'libs', include: ['*.jar']) | ||
+ testCompile 'junit:junit:4.12' | ||
+ compile 'com.android.support:appcompat-v7:23.2.0' | ||
+} |
17
library/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 /Users/CaMnter/Android/adt-bundle-mac-x86_64-20140702/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 *; | ||
+#} |
9
library/src/main/AndroidManifest.xml
@@ -0,0 +1,9 @@ | ||
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
+ package="com.camnter.easycountdownsurfaceview"> | ||
+ | ||
+ <application android:allowBackup="true" android:label="@string/app_name" | ||
+ android:supportsRtl="true"> | ||
+ | ||
+ </application> | ||
+ | ||
+</manifest> |
231
library/src/main/java/com/camnter/easycountdownsurfaceview/EasyCountDownSurfaceView.java
@@ -0,0 +1,231 @@ | ||
+package com.camnter.easycountdownsurfaceview; | ||
+ | ||
+import android.annotation.TargetApi; | ||
+import android.content.Context; | ||
+import android.graphics.Canvas; | ||
+import android.graphics.Paint; | ||
+import android.graphics.PixelFormat; | ||
+import android.graphics.RectF; | ||
+import android.os.Build; | ||
+import android.util.AttributeSet; | ||
+import android.util.DisplayMetrics; | ||
+import android.util.TypedValue; | ||
+import android.view.SurfaceHolder; | ||
+import android.view.SurfaceView; | ||
+ | ||
+import java.util.Date; | ||
+ | ||
+/** | ||
+ * Description:EasyCountDownSurfaceView | ||
+ * Created by:CaMnter | ||
+ * Time:2016-03-15 19:49 | ||
+ */ | ||
+public class EasyCountDownSurfaceView extends SurfaceView implements SurfaceHolder.Callback2 { | ||
+ | ||
+ private static final int DEFAULT_COLOR_BACKGROUND = 0xff000000; | ||
+ private static final int DEFAULT_COLOR_TIME = 0xffffffff; | ||
+ private DisplayMetrics mMetrics; | ||
+ | ||
+ private static final int COUNT_DOWN_INTERVAL = 1000; | ||
+ | ||
+ private long mMillisInFuture = 99000L; | ||
+ | ||
+ private static final float DEFAULT_BACKGROUND_PAINT_WIDTH = 0.66f; | ||
+ private static final float DEFAULT_TIME_PAINT_WIDTH = 0.66f; | ||
+ | ||
+ private double increaseTime = 0.0d; | ||
+ private long lastTimeRefresh = 0L; | ||
+ | ||
+ private SurfaceHolder mHolder; | ||
+ private EasyThread mThread; | ||
+ | ||
+ private Paint timePaint; | ||
+ private Paint backgroundPaint; | ||
+ | ||
+ public EasyCountDownSurfaceView(Context context) { | ||
+ super(context); | ||
+ this.init(); | ||
+ } | ||
+ | ||
+ public EasyCountDownSurfaceView(Context context, AttributeSet attrs) { | ||
+ super(context, attrs); | ||
+ this.init(); | ||
+ } | ||
+ | ||
+ public EasyCountDownSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { | ||
+ super(context, attrs, defStyleAttr); | ||
+ this.init(); | ||
+ } | ||
+ | ||
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||
+ public EasyCountDownSurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { | ||
+ super(context, attrs, defStyleAttr, defStyleRes); | ||
+ this.init(); | ||
+ } | ||
+ | ||
+ private void init() { | ||
+ this.mMetrics = this.getResources().getDisplayMetrics(); | ||
+ this.mHolder = this.getHolder(); | ||
+ this.mHolder.addCallback(this); | ||
+ | ||
+ this.setZOrderOnTop(true); | ||
+ this.mHolder.setFormat(PixelFormat.TRANSPARENT); | ||
+ | ||
+ this.initPaints(); | ||
+ this.mThread = new EasyThread(); | ||
+ | ||
+ } | ||
+ | ||
+ private void initPaints() { | ||
+ this.backgroundPaint = new Paint(); | ||
+ this.backgroundPaint.setAntiAlias(true); | ||
+ this.backgroundPaint.setColor(DEFAULT_COLOR_BACKGROUND); | ||
+ this.backgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE); | ||
+ this.backgroundPaint.setStrokeWidth(this.dp2px(DEFAULT_BACKGROUND_PAINT_WIDTH)); | ||
+ | ||
+ this.timePaint = new Paint(); | ||
+ this.timePaint.setAntiAlias(true); | ||
+ this.timePaint.setColor(DEFAULT_COLOR_TIME); | ||
+ this.timePaint.setStyle(Paint.Style.FILL_AND_STROKE); | ||
+ this.timePaint.setStrokeWidth(this.dp2px(DEFAULT_TIME_PAINT_WIDTH)); | ||
+ this.timePaint.setTextSize(30); | ||
+ } | ||
+ | ||
+ | ||
+ @Override | ||
+ public void surfaceRedrawNeeded(SurfaceHolder holder) { | ||
+ | ||
+ } | ||
+ | ||
+ | ||
+ @Override | ||
+ public void surfaceCreated(SurfaceHolder holder) { | ||
+ if (null == mThread) { | ||
+ mThread = new EasyThread(); | ||
+ mThread.start(); | ||
+ } | ||
+ } | ||
+ | ||
+ | ||
+ @Override | ||
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | ||
+ | ||
+ } | ||
+ | ||
+ | ||
+ @Override | ||
+ public void surfaceDestroyed(SurfaceHolder holder) { | ||
+ if (null != mThread) { | ||
+ mThread.stopThread(); | ||
+ } | ||
+ } | ||
+ | ||
+ @Override | ||
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
+ } | ||
+ | ||
+ /** | ||
+ * Start count down by date | ||
+ * | ||
+ * @param date date | ||
+ */ | ||
+ public void start(Date date) { | ||
+ this.mThread.start(); | ||
+ } | ||
+ | ||
+ /** | ||
+ * Start count down by timeMillis | ||
+ * | ||
+ * @param timeMillis timeMillis | ||
+ */ | ||
+ public void start(long timeMillis) { | ||
+ | ||
+ } | ||
+ | ||
+ /** | ||
+ * Stop count down | ||
+ */ | ||
+ public void stop() { | ||
+ | ||
+ } | ||
+ | ||
+ public void start() { | ||
+ if (this.mThread.isAlive()) { | ||
+ this.mThread.start(); | ||
+ } else { | ||
+ this.mThread.run(); | ||
+ } | ||
+ } | ||
+ | ||
+ private class EasyThread extends Thread { | ||
+ | ||
+ public boolean isRunning = false; | ||
+ | ||
+ public EasyThread() { | ||
+ this.isRunning = true; | ||
+ } | ||
+ | ||
+ public synchronized final void stopThread() { | ||
+ isRunning = false; | ||
+ boolean workIsNotFinish = true; | ||
+ while (workIsNotFinish) { | ||
+ try { | ||
+ this.join(); | ||
+ } catch (InterruptedException e) { | ||
+ // TODO Auto-generated catch block | ||
+ e.printStackTrace(); | ||
+ } | ||
+ workIsNotFinish = false; | ||
+ } | ||
+ } | ||
+ | ||
+ @Override | ||
+ public void run() { | ||
+ System.out.println("Run"); | ||
+ long deltaTime = 0; | ||
+ long tickTime = 0; | ||
+ while (isRunning) { | ||
+ Canvas canvas = null; | ||
+ try { | ||
+ synchronized (this) { | ||
+ canvas = mHolder.lockCanvas(); | ||
+ this.drawBackground(canvas); | ||
+ this.drawTime(canvas, (int) ((mMillisInFuture -= COUNT_DOWN_INTERVAL) / 1000)); | ||
+ } | ||
+ } catch (Exception e) { | ||
+ e.printStackTrace(); | ||
+ } finally { | ||
+ if (mHolder != null) { | ||
+ mHolder.unlockCanvasAndPost(canvas); | ||
+ } | ||
+ } | ||
+ deltaTime = System.currentTimeMillis() - tickTime; | ||
+ if (deltaTime < COUNT_DOWN_INTERVAL) { | ||
+ try { | ||
+ Thread.sleep(COUNT_DOWN_INTERVAL - deltaTime); | ||
+ } catch (InterruptedException e) { | ||
+ e.printStackTrace(); | ||
+ } | ||
+ } | ||
+ tickTime = System.currentTimeMillis(); | ||
+ } | ||
+ | ||
+ } | ||
+ | ||
+ private void drawBackground(Canvas canvas) { | ||
+ canvas.drawRoundRect(new RectF(0, 0, 100, 100), dp2px(4), dp2px(4), backgroundPaint); | ||
+ canvas.drawRoundRect(new RectF(150, 0, 250, 100), dp2px(4), dp2px(4), backgroundPaint); | ||
+ canvas.drawRoundRect(new RectF(300, 0, 400, 100), dp2px(4), dp2px(4), backgroundPaint); | ||
+ } | ||
+ | ||
+ private void drawTime(Canvas canvas, int time) { | ||
+ canvas.drawText(time + "", 330, 70, timePaint); | ||
+ } | ||
+ } | ||
+ | ||
+ private float dp2px(float dp) { | ||
+ return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, this.mMetrics); | ||
+ } | ||
+ | ||
+} |
3
library/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@ | ||
+<resources> | ||
+ <string name="app_name">library</string> | ||
+</resources> |
1
settings.gradle
@@ -0,0 +1 @@ | ||
+include ':app', ':library' |
0 comments on commit
2ae23ab