├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── lilei │ │ │ └── depthmapview │ │ │ └── demo │ │ │ └── MainActivity.kt │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── lilei │ │ │ └── depthmapview │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── github │ │ └── lilei │ │ └── depthmapview │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── depthmapview ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── attrs.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── lilei │ │ │ └── depthmapview │ │ │ ├── DepthBuySellData.java │ │ │ ├── GestureMoveActionCompat.java │ │ │ └── DepthMapView.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── github │ │ │ └── lilei │ │ │ └── depthmapview │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── github │ │ └── lilei │ │ └── depthmapview │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── 1563953796571899.gif ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── vcs.xml ├── misc.xml ├── runConfigurations.xml ├── gradle.xml └── inspectionProfiles │ └── Project_Default.xml ├── .gitignore ├── README.md ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /depthmapview/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /depthmapview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':depthmapview' 2 | rootProject.name='DepthMapView' 3 | -------------------------------------------------------------------------------- /1563953796571899.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/1563953796571899.gif -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DepthMapView 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /depthmapview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DepthMapView 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liulilei/DepthMapView/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /depthmapview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jul 19 16:32:27 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DepthMapView 2 | android深度图 交易深度 DepthMapView 3 | 4 | 5 | 背景:深度图是很多币圈交易所需要的数据展示效果,更好的帮助用户快速的查看买卖盘的价格以及数量。 6 | 7 | 如下效果图: 8 | 9 | ![image](https://github.com/liulilei/DepthMapView/blob/master/1563953796571899.gif) 10 | 11 | 12 | - 买卖盘价格,价格居中分布显示,提供多种参数设置。 13 | - 解决使用在scrollview中的手势冲突,按下深度图上时可以左右滑动查看数据,上下滑动时不受影响。 14 | 如果对您有帮助,请动动手指点个star,谢谢! 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/lilei/depthmapview/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /depthmapview/src/test/java/com/github/lilei/depthmapview/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /depthmapview/src/main/java/com/github/lilei/depthmapview/DepthBuySellData.java: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview; 2 | 3 | /** 4 | * @Description: 5 | * @author: lll 6 | * @date: 2019-07-19 7 | */ 8 | public class DepthBuySellData { 9 | 10 | public DepthBuySellData(String price, String amount) { 11 | this.price = price; 12 | this.amount = amount; 13 | } 14 | 15 | public String price; 16 | public String amount; 17 | 18 | public String getPrice() { 19 | return price; 20 | } 21 | 22 | public void setPrice(String price) { 23 | this.price = price; 24 | } 25 | 26 | public String getAmount() { 27 | return amount; 28 | } 29 | 30 | public void setAmount(String amount) { 31 | this.amount = amount; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/github/lilei/depthmapview/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.github.lilei.depthmapview", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /depthmapview/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /depthmapview/src/androidTest/java/com/github/lilei/depthmapview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.github.lilei.depthmapview.test", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /depthmapview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 28 5 | 6 | 7 | defaultConfig { 8 | minSdkVersion 18 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | consumerProguardFiles 'consumer-rules.pro' 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | 29 | implementation 'androidx.appcompat:appcompat:1.0.2' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 33 | } 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | # AndroidX package structure to make it clearer which packages are bundled with the 20 | # Android operating system, and which are packaged with your app's APK 21 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 22 | android.useAndroidX=true 23 | # Automatically convert third-party libraries to use AndroidX 24 | android.enableJetifier=true 25 | 26 | # Kotlin code style for this project: "official" or "obsolete": 27 | kotlin.code.style=official 28 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "com.github.lilei.depthmapview.demo" 11 | minSdkVersion 18 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 28 | implementation 'androidx.appcompat:appcompat:1.0.2' 29 | implementation 'androidx.core:core-ktx:1.0.2' 30 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 31 | testImplementation 'junit:junit:4.12' 32 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 33 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 34 | 35 | implementation project(':depthmapview') 36 | implementation 'com.google.code.gson:gson:2.8.2' 37 | } 38 | -------------------------------------------------------------------------------- /depthmapview/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 18 | 19 | 25 | 26 | 32 | 33 | 52 | 53 | 54 | 60 | 61 | 67 | 68 | 74 | 75 | 81 | 82 | 88 | 89 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | xmlns:android 17 | 18 | ^$ 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | xmlns:.* 28 | 29 | ^$ 30 | 31 | 32 | BY_NAME 33 | 34 |
35 |
36 | 37 | 38 | 39 | .*:id 40 | 41 | http://schemas.android.com/apk/res/android 42 | 43 | 44 | 45 |
46 |
47 | 48 | 49 | 50 | .*:name 51 | 52 | http://schemas.android.com/apk/res/android 53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 | name 62 | 63 | ^$ 64 | 65 | 66 | 67 |
68 |
69 | 70 | 71 | 72 | style 73 | 74 | ^$ 75 | 76 | 77 | 78 |
79 |
80 | 81 | 82 | 83 | .* 84 | 85 | ^$ 86 | 87 | 88 | BY_NAME 89 | 90 |
91 |
92 | 93 | 94 | 95 | .* 96 | 97 | http://schemas.android.com/apk/res/android 98 | 99 | 100 | ANDROID_ATTRIBUTE_ORDER 101 | 102 |
103 |
104 | 105 | 106 | 107 | .* 108 | 109 | .* 110 | 111 | 112 | BY_NAME 113 | 114 |
115 |
116 |
117 |
118 | 119 | 121 |
122 |
-------------------------------------------------------------------------------- /depthmapview/src/main/java/com/github/lilei/depthmapview/GestureMoveActionCompat.java: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * @Description: 7 | * @author: lll 8 | * @date: 2019-07-19 9 | */ 10 | public class GestureMoveActionCompat { 11 | private OnGestureMoveListener gestureMoveListener; 12 | 13 | /** 14 | * 本次 ACTION_DOWN 事件的坐标 x 15 | */ 16 | private float lastMotionX; 17 | 18 | /** 19 | * 本次 ACTION_DOWN 事件的坐标 y 20 | */ 21 | private float lastMotionY; 22 | 23 | /** 24 | * 当前滑动的方向。0 无滑动(视为点击);1 垂直滑动;2 横向滑动 25 | */ 26 | private int interceptStatus = 0; 27 | 28 | /** 29 | * 是否响应点击事件 30 | * 31 | * 因为有手指抖动的影响,有时候会产生少量的 ACTION_MOVE 事件,造成程序识别错误。 32 | */ 33 | private boolean mEnableClick = true; 34 | 35 | /** 36 | * 避免程序识别错误的一个阀值。只有触摸移动的距离大于这个阀值时,才认为是一个有效的移动。 37 | */ 38 | private int touchSlop = 20; 39 | 40 | private boolean dragging = false; 41 | 42 | public GestureMoveActionCompat(OnGestureMoveListener onGestureMoveListener) { 43 | gestureMoveListener = onGestureMoveListener; 44 | } 45 | 46 | public void enableClick(boolean enableClick) { 47 | mEnableClick = enableClick; 48 | } 49 | 50 | public void setTouchSlop(int touchSlop) { 51 | this.touchSlop = touchSlop; 52 | } 53 | 54 | public boolean isDragging() { 55 | return dragging; 56 | } 57 | 58 | /** 59 | * @param e 事件 e 60 | * @param x 本次事件的坐标 x。可以是 e.getRawX() 或是 e.getX(),具体看情况 61 | * @param y 本次事件的坐标 y。可以是 e.getRawY() 或是 e.getY(),具体看情况 62 | * 63 | * @return 事件是否是横向滑动 64 | */ 65 | public boolean onTouchEvent(MotionEvent e, float x, float y) { 66 | switch (e.getAction()) { 67 | case MotionEvent.ACTION_DOWN: 68 | lastMotionY = y; 69 | lastMotionX = x; 70 | interceptStatus = 0; 71 | dragging = false; 72 | break; 73 | 74 | case MotionEvent.ACTION_MOVE: 75 | float deltaY = Math.abs(y - lastMotionY); 76 | float deltaX = Math.abs(x - lastMotionX); 77 | 78 | /** 79 | * 如果之前是垂直滑动,即使现在是横向滑动,仍然认为它是垂直滑动的 80 | * 如果之前是横向滑动,即使现在是垂直滑动,仍然认为它是横向滑动的 81 | * 防止在一个方向上来回滑动时,发生垂直滑动和横向滑动的频繁切换,造成识别错误 82 | */ 83 | if (interceptStatus != 1 && 84 | (dragging || deltaX > deltaY && deltaX > touchSlop)) { 85 | interceptStatus = 2; 86 | dragging = true; 87 | 88 | if (gestureMoveListener != null) { 89 | gestureMoveListener.onHorizontalMove(e, x, y); 90 | } 91 | } else if (interceptStatus != 2 && 92 | (dragging || deltaX < deltaY && deltaY > touchSlop)) { 93 | interceptStatus = 1; 94 | dragging = true; 95 | 96 | if (gestureMoveListener != null) { 97 | gestureMoveListener.onVerticalMove(e, x, y); 98 | } 99 | } 100 | break; 101 | 102 | case MotionEvent.ACTION_UP: 103 | if (interceptStatus == 0) { 104 | if (mEnableClick && gestureMoveListener != null) { 105 | gestureMoveListener.onClick(e, x, y); 106 | } 107 | } 108 | interceptStatus = 0; 109 | dragging = false; 110 | break; 111 | } 112 | return interceptStatus == 2; 113 | } 114 | 115 | public interface OnGestureMoveListener { 116 | 117 | /** 118 | * 横向移动 119 | */ 120 | void onHorizontalMove(MotionEvent e, float x, float y); 121 | 122 | /** 123 | * 垂直移动 124 | */ 125 | void onVerticalMove(MotionEvent e, float x, float y); 126 | 127 | /** 128 | * 点击事件 129 | */ 130 | void onClick(MotionEvent e, float x, float y); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 | 70 | 72 | 74 | 75 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 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 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/lilei/depthmapview/demo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview.demo 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.github.lilei.depthmapview.DepthBuySellData 6 | import com.google.gson.Gson 7 | import com.google.gson.reflect.TypeToken 8 | import kotlinx.android.synthetic.main.activity_main.* 9 | import java.lang.reflect.Type 10 | 11 | 12 | class MainActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_main) 17 | 18 | var buy = 19 | "[{\"amount\":\"516494.4900\",\"price\":\"0.000148\"},{\"amount\":\"10099.9999\",\"price\":\"0.000145\"},{\"amount\":\"28865.9722\",\"price\":\"0.000144\"},{\"amount\":\"1019275.5244\",\"price\":\"0.000143\"},{\"amount\":\"1243819.0139\",\"price\":\"0.000142\"},{\"amount\":\"2467081.9859\",\"price\":\"0.000141\"},{\"amount\":\"685328.5708\",\"price\":\"0.000140\"},{\"amount\":\"2384900.7191\",\"price\":\"0.000139\"},{\"amount\":\"210871.7389\",\"price\":\"0.000138\"},{\"amount\":\"17296.3502\",\"price\":\"0.000137\"},{\"amount\":\"123081.6173\",\"price\":\"0.000136\"},{\"amount\":\"861877.0363\",\"price\":\"0.000135\"},{\"amount\":\"598669.4028\",\"price\":\"0.000134\"},{\"amount\":\"887218.7968\",\"price\":\"0.000133\"},{\"amount\":\"2684262.8786\",\"price\":\"0.000132\"},{\"amount\":\"3122257.2515\",\"price\":\"0.000131\"},{\"amount\":\"612505.3840\",\"price\":\"0.000130\"},{\"amount\":\"71791.4728\",\"price\":\"0.000129\"},{\"amount\":\"650141.4061\",\"price\":\"0.000128\"},{\"amount\":\"454568.5038\",\"price\":\"0.000127\"},{\"amount\":\"3887016.6663\",\"price\":\"0.000126\"},{\"amount\":\"247112.8000\",\"price\":\"0.000125\"},{\"amount\":\"1572039.5160\",\"price\":\"0.000124\"},{\"amount\":\"898388.6176\",\"price\":\"0.000123\"},{\"amount\":\"30499.1802\",\"price\":\"0.000122\"},{\"amount\":\"203665.2889\",\"price\":\"0.000121\"},{\"amount\":\"482505.8332\",\"price\":\"0.000120\"},{\"amount\":\"19102.5209\",\"price\":\"0.000119\"},{\"amount\":\"1039101.6948\",\"price\":\"0.000118\"},{\"amount\":\"125602.5640\",\"price\":\"0.000117\"},{\"amount\":\"87967.2412\",\"price\":\"0.000116\"},{\"amount\":\"966166.0868\",\"price\":\"0.000115\"},{\"amount\":\"334629.8244\",\"price\":\"0.000114\"},{\"amount\":\"115053.9821\",\"price\":\"0.000113\"},{\"amount\":\"239043.7499\",\"price\":\"0.000112\"},{\"amount\":\"2481802.7026\",\"price\":\"0.000111\"},{\"amount\":\"396694.5453\",\"price\":\"0.000110\"},{\"amount\":\"8042.2018\",\"price\":\"0.000109\"},{\"amount\":\"45685.1850\",\"price\":\"0.000108\"},{\"amount\":\"276085.9811\",\"price\":\"0.000107\"},{\"amount\":\"1110069.8113\",\"price\":\"0.000106\"},{\"amount\":\"153936.1904\",\"price\":\"0.000105\"},{\"amount\":\"12069.2307\",\"price\":\"0.000104\"},{\"amount\":\"2097548.5436\",\"price\":\"0.000103\"},{\"amount\":\"1641847.0588\",\"price\":\"0.000102\"},{\"amount\":\"729310.8909\",\"price\":\"0.000101\"},{\"amount\":\"1708698.0000\",\"price\":\"0.000100\"},{\"amount\":\"2200.0000\",\"price\":\"0.000096\"},{\"amount\":\"99672.6315\",\"price\":\"0.000095\"},{\"amount\":\"606000.0000\",\"price\":\"0.000094\"}]" 20 | var sell = 21 | "[{\"amount\":\"18998.3492\",\"price\":\"0.000149\"},{\"amount\":\"579375.2636\",\"price\":\"0.000150\"},{\"amount\":\"10000.0000\",\"price\":\"0.000151\"},{\"amount\":\"23938.1907\",\"price\":\"0.000152\"},{\"amount\":\"39437.0592\",\"price\":\"0.000153\"},{\"amount\":\"70086.8975\",\"price\":\"0.000154\"},{\"amount\":\"119481.8449\",\"price\":\"0.000155\"},{\"amount\":\"31000.0000\",\"price\":\"0.000156\"},{\"amount\":\"398481.1022\",\"price\":\"0.000157\"},{\"amount\":\"1020826.4943\",\"price\":\"0.000158\"},{\"amount\":\"19700.0000\",\"price\":\"0.000159\"},{\"amount\":\"1540570.1143\",\"price\":\"0.000160\"},{\"amount\":\"510000.0000\",\"price\":\"0.000161\"},{\"amount\":\"42297.9030\",\"price\":\"0.000162\"},{\"amount\":\"905817.4543\",\"price\":\"0.000163\"},{\"amount\":\"320918.8569\",\"price\":\"0.000164\"},{\"amount\":\"85984.6779\",\"price\":\"0.000165\"},{\"amount\":\"849310.8825\",\"price\":\"0.000166\"},{\"amount\":\"337482.8245\",\"price\":\"0.000167\"},{\"amount\":\"1058834.3325\",\"price\":\"0.000168\"},{\"amount\":\"189803.0301\",\"price\":\"0.000169\"},{\"amount\":\"1010000.0000\",\"price\":\"0.000170\"},{\"amount\":\"553919.1734\",\"price\":\"0.000171\"},{\"amount\":\"103177.0000\",\"price\":\"0.000172\"},{\"amount\":\"69936.9942\",\"price\":\"0.000173\"},{\"amount\":\"112300.0984\",\"price\":\"0.000174\"},{\"amount\":\"89297.2116\",\"price\":\"0.000175\"},{\"amount\":\"224360.1818\",\"price\":\"0.000176\"},{\"amount\":\"539730.2447\",\"price\":\"0.000177\"},{\"amount\":\"30000.0000\",\"price\":\"0.000178\"},{\"amount\":\"25469.0000\",\"price\":\"0.000179\"},{\"amount\":\"1146947.3660\",\"price\":\"0.000180\"},{\"amount\":\"1000000.0000\",\"price\":\"0.000181\"},{\"amount\":\"523562.9441\",\"price\":\"0.000183\"},{\"amount\":\"2000.0000\",\"price\":\"0.000184\"},{\"amount\":\"876996.7708\",\"price\":\"0.000185\"},{\"amount\":\"558687.6729\",\"price\":\"0.000186\"},{\"amount\":\"570457.3663\",\"price\":\"0.000187\"},{\"amount\":\"1130000.0000\",\"price\":\"0.000188\"},{\"amount\":\"397615.3157\",\"price\":\"0.000190\"},{\"amount\":\"300000.0000\",\"price\":\"0.000191\"},{\"amount\":\"100000.0000\",\"price\":\"0.000192\"},{\"amount\":\"130077.7202\",\"price\":\"0.000193\"},{\"amount\":\"6257.9403\",\"price\":\"0.000194\"},{\"amount\":\"273440.9221\",\"price\":\"0.000195\"},{\"amount\":\"649800.0000\",\"price\":\"0.000196\"},{\"amount\":\"167367.9134\",\"price\":\"0.000197\"},{\"amount\":\"1109832.5267\",\"price\":\"0.000198\"},{\"amount\":\"30570.7676\",\"price\":\"0.000199\"},{\"amount\":\"3486373.7985\",\"price\":\"0.000200\"}]" 22 | 23 | var buyList: ArrayList? = 24 | parseGSON(buy, object : TypeToken>() {}.type) 25 | var sellList: ArrayList? = 26 | parseGSON(sell, object : TypeToken>() {}.type) 27 | 28 | if (buyList?.isNotEmpty()!! && sellList?.isEmpty()!!) { 29 | sellList.add(0, DepthBuySellData("0", "0")) 30 | } else if (buyList.isEmpty() && sellList?.isNotEmpty()!!) { 31 | buyList.add(0, DepthBuySellData("0", "0")) 32 | } 33 | depthMapView.setData(buyList, sellList, "BTC", 6, 4) 34 | } 35 | 36 | //根据 Type 解析 37 | fun parseGSON(jsonString: String, typeOfT: Type): T? { 38 | var t: T? = null 39 | try { 40 | t = Gson().fromJson(jsonString, typeOfT) 41 | } catch (e: Exception) { 42 | // TODO: handle exception 43 | e.printStackTrace() 44 | } 45 | 46 | return t 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /depthmapview/src/main/java/com/github/lilei/depthmapview/DepthMapView.java: -------------------------------------------------------------------------------- 1 | package com.github.lilei.depthmapview; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.content.res.Resources; 6 | import android.content.res.TypedArray; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.LinearGradient; 10 | import android.graphics.Paint; 11 | import android.graphics.Path; 12 | import android.graphics.RectF; 13 | import android.graphics.Shader; 14 | import android.util.AttributeSet; 15 | import android.view.GestureDetector; 16 | import android.view.MotionEvent; 17 | import android.view.View; 18 | import android.view.ViewConfiguration; 19 | 20 | import androidx.annotation.Nullable; 21 | import androidx.core.content.ContextCompat; 22 | import androidx.core.view.MotionEventCompat; 23 | 24 | import java.math.BigDecimal; 25 | import java.util.ArrayList; 26 | import java.util.Collections; 27 | import java.util.Comparator; 28 | import java.util.HashMap; 29 | import java.util.List; 30 | 31 | /** 32 | * @Description: 33 | * @author: lll 34 | * @date: 2019-07-19 35 | */ 36 | public class DepthMapView extends View { 37 | 38 | private int mWidth; 39 | //圆点半径 40 | private int mDotRadius = 2; 41 | //圆圈半径 42 | private int mCircleRadius = 8; 43 | private float mGridWidth; 44 | //底部价格区域高度 45 | private int mBottomPriceHeight; 46 | //右侧委托量绘制个数 47 | private int mLineCount; 48 | //背景颜色 49 | private int mBackgroundColor; 50 | 51 | private boolean mIsHave; 52 | //是否是长按 53 | private boolean mIsLongPress; 54 | 55 | //最大的委托量 56 | private float mMaxVolume; 57 | private float mMultiple; 58 | private int mLastPosition; 59 | private int mDrawWidth = 0; 60 | private int mDrawHeight; 61 | //触摸点的X轴值 62 | private int mEventX; 63 | 64 | //文案绘制画笔 65 | private Paint mTextPaint; 66 | //买入区域边线绘制画笔 67 | private Paint mBuyLinePaint; 68 | //卖出区域边线绘制画笔 69 | private Paint mSellLinePaint; 70 | //买入区域绘制画笔 71 | private Paint mBuyPathPaint; 72 | //卖出取悦绘制画笔 73 | private Paint mSellPathPaint; 74 | //选中时圆点绘制画笔 75 | private Paint mRadioPaint; 76 | //选中时圆圈绘制画笔 77 | private Paint mCirclePaint; 78 | //选中时中间文案背景画笔 79 | private Paint mSelectorBackgroundPaint; 80 | //选中时中间文案画笔 81 | private Paint mSelectorTextPaint; 82 | 83 | private Path mBuyPath = new Path(); 84 | private Path mSellPath = new Path(); 85 | 86 | private List mBuyData; 87 | private List mSellData; 88 | 89 | private List buyAmountMoney; 90 | private List sellAmountMoney; 91 | 92 | // 价格显示精度限制 93 | public int mPriceLimit = 7; 94 | // private int mVolumeLimit = 5; 95 | 96 | private HashMap mMapX; 97 | private HashMap mMapY; 98 | private HashMap mAmount; 99 | private Float[] mBottomPrice; 100 | 101 | private boolean onTouch = false; 102 | private boolean onLongPress = false; 103 | private boolean onVerticalMove = false; 104 | 105 | private String tradePost = ""; 106 | private String coin = ""; 107 | private int pricisionCoin = 0; 108 | private int pricisionPrice = 0; 109 | private int priTradePost = 2;//显示委托价精度 110 | 111 | public DepthMapView(Context context) { 112 | this(context, null); 113 | } 114 | 115 | public DepthMapView(Context context, @Nullable AttributeSet attrs) { 116 | this(context, attrs, 0); 117 | } 118 | 119 | public DepthMapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 120 | super(context, attrs, defStyleAttr); 121 | 122 | int touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 123 | gestureCompat.setTouchSlop(touchSlop); 124 | 125 | init(attrs); 126 | } 127 | 128 | @SuppressLint("UseSparseArrays") 129 | private void init(AttributeSet attrs) { 130 | mBottomPriceHeight = 40; 131 | mMapX = new HashMap<>(); 132 | mMapY = new HashMap<>(); 133 | mAmount = new HashMap<>(); 134 | mBottomPrice = new Float[4]; 135 | mBuyData = new ArrayList<>(); 136 | mSellData = new ArrayList<>(); 137 | buyAmountMoney = new ArrayList<>(); 138 | sellAmountMoney = new ArrayList<>(); 139 | 140 | mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 141 | mTextPaint.setTextAlign(Paint.Align.RIGHT); 142 | 143 | mBuyLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 144 | mBuyLinePaint.setStyle(Paint.Style.STROKE); 145 | mBuyLinePaint.setTextAlign(Paint.Align.CENTER); 146 | mBuyPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 147 | 148 | mSellLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 149 | mSellLinePaint.setStyle(Paint.Style.STROKE); 150 | mSellLinePaint.setTextAlign(Paint.Align.CENTER); 151 | mSellPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 152 | 153 | mRadioPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 154 | mRadioPaint.setTextAlign(Paint.Align.CENTER); 155 | 156 | mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 157 | mCirclePaint.setTextAlign(Paint.Align.CENTER); 158 | 159 | mSelectorBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 160 | mSelectorTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 161 | mSelectorTextPaint.setTextAlign(Paint.Align.RIGHT); 162 | 163 | TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.DepthMapView); 164 | if (typedArray != null) { 165 | try { 166 | mLineCount = typedArray.getInt(R.styleable.DepthMapView_line_count, 4); 167 | mDotRadius = typedArray.getDimensionPixelSize(R.styleable.DepthMapView_dot_radius, dip2px(mDotRadius)); 168 | mCircleRadius = typedArray.getDimensionPixelSize(R.styleable.DepthMapView_circle_radius, dip2px(mCircleRadius)); 169 | mBackgroundColor = typedArray.getColor(R.styleable.DepthMapView_background_color, ContextCompat.getColor(getContext(), android.R.color.white)); 170 | mBuyLinePaint.setStrokeWidth(typedArray.getDimensionPixelSize(R.styleable.DepthMapView_line_width, dip2px(1.5f))); 171 | mSellLinePaint.setStrokeWidth(typedArray.getDimensionPixelSize(R.styleable.DepthMapView_line_width, dip2px(1.5f))); 172 | mTextPaint.setColor(typedArray.getColor(R.styleable.DepthMapView_text_color, Color.parseColor("#9B9B9B"))); 173 | mTextPaint.setTextSize(typedArray.getDimension(R.styleable.DepthMapView_text_size, dip2px(10f))); 174 | mBuyLinePaint.setColor(typedArray.getColor(R.styleable.DepthMapView_buy_line_color, Color.parseColor("#00BE66"))); 175 | mSellLinePaint.setColor(typedArray.getColor(R.styleable.DepthMapView_sell_line_color, Color.parseColor("#EA573C"))); 176 | int buyColor = typedArray.getColor(R.styleable.DepthMapView_buy_path_color, Color.parseColor("#00BE66")); 177 | int sellColor = typedArray.getColor(R.styleable.DepthMapView_sell_path_color, Color.parseColor("#EA573C")); 178 | mSelectorBackgroundPaint.setColor(typedArray.getColor(R.styleable.DepthMapView_selector_background_color, Color.parseColor("#252B3E"))); 179 | mSelectorTextPaint.setColor(typedArray.getColor(R.styleable.DepthMapView_selector_text_color, ContextCompat.getColor(getContext(), android.R.color.white))); 180 | mSelectorTextPaint.setTextSize(typedArray.getDimension(R.styleable.DepthMapView_selector_text_size, dip2px(10f))); 181 | LinearGradient buyLg = new LinearGradient(0, 0, 0, 800, buyColor, Color.parseColor("#2000BE66"), Shader.TileMode.CLAMP); 182 | mBuyPathPaint.setShader(buyLg); 183 | LinearGradient sellLg = new LinearGradient(getWidth(), 0, getWidth(), 800, sellColor, Color.parseColor("#20EA573C"), Shader.TileMode.CLAMP); 184 | mSellPathPaint.setShader(sellLg); 185 | } finally { 186 | typedArray.recycle(); 187 | } 188 | } 189 | } 190 | 191 | @Override 192 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 193 | super.onSizeChanged(w, h, oldw, oldh); 194 | this.mWidth = w; 195 | mDrawWidth = mWidth / 2 - 1; 196 | mDrawHeight = h - mBottomPriceHeight; 197 | } 198 | 199 | //设置交易区精度 200 | public void setPriTradePost(int priTradePost) { 201 | this.priTradePost = priTradePost; 202 | } 203 | 204 | public void setData(List buyData, List sellData, String name, int prinPrice, int priCoin) { 205 | double vol = 0; 206 | float amountmoney = 0; 207 | if (buyData.size() > 0) { 208 | mBuyData.clear(); 209 | buyAmountMoney.clear(); 210 | //买入数据按价格进行排序 211 | Collections.sort(buyData, new comparePrice()); 212 | DepthBuySellData depthDataBean; 213 | //累加买入委托量 214 | for (int index = buyData.size() - 1; index >= 0; index--) { 215 | depthDataBean = buyData.get(index); 216 | vol += Double.valueOf(depthDataBean.getAmount()); 217 | amountmoney += Float.valueOf(depthDataBean.getAmount()) * Float.valueOf(depthDataBean.getPrice()); 218 | depthDataBean.setAmount("" + vol); 219 | mBuyData.add(0, depthDataBean); 220 | buyAmountMoney.add(0, amountmoney); 221 | } 222 | //修改底部买入价格展示 223 | mBottomPrice[0] = Float.valueOf(mBuyData.get(0).getPrice()); 224 | mBottomPrice[1] = Float.valueOf(mBuyData.get(mBuyData.size() > 1 ? mBuyData.size() - 1 : 0).getPrice()); 225 | mMaxVolume = Float.valueOf(mBuyData.get(0).getAmount()); 226 | } 227 | 228 | if (sellData.size() > 0) { 229 | mSellData.clear(); 230 | sellAmountMoney.clear(); 231 | vol = 0; 232 | amountmoney = 0; 233 | //卖出数据按价格进行排序 234 | Collections.sort(sellData, new comparePrice()); 235 | //累加卖出委托量 236 | for (DepthBuySellData depthDataBean : sellData) { 237 | vol += Double.valueOf(depthDataBean.getAmount()); 238 | amountmoney += Float.valueOf(depthDataBean.getAmount()) * Float.valueOf(depthDataBean.getPrice()); 239 | depthDataBean.setAmount("" + vol); 240 | mSellData.add(depthDataBean); 241 | sellAmountMoney.add(amountmoney); 242 | } 243 | //修改底部卖出价格展示 244 | mBottomPrice[2] = Float.valueOf(mSellData.get(0).getPrice()); 245 | mBottomPrice[3] = Float.valueOf(mSellData.get(mSellData.size() > 1 ? mSellData.size() - 1 : 0).getPrice()); 246 | mMaxVolume = Math.max(mMaxVolume, Float.valueOf(mSellData.get(mSellData.size() - 1).getAmount())); 247 | } 248 | mMaxVolume = mMaxVolume * 1.05f; 249 | mMultiple = mMaxVolume / mLineCount; 250 | tradePost = name; 251 | coin = name; 252 | pricisionPrice = prinPrice; 253 | pricisionCoin = priCoin; 254 | invalidate(); 255 | } 256 | 257 | private final GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { 258 | @Override 259 | public void onLongPress(MotionEvent e) { 260 | if (onTouch) { 261 | onLongPress = true; 262 | mIsLongPress = true; 263 | invalidate(); 264 | } 265 | } 266 | }); 267 | 268 | private GestureMoveActionCompat gestureCompat = new GestureMoveActionCompat(null); 269 | 270 | @Override 271 | public boolean onTouchEvent(MotionEvent event) { 272 | gestureDetector.onTouchEvent(event); 273 | mEventX = (int) event.getX(); 274 | switch (event.getAction() & MotionEvent.ACTION_MASK) { 275 | case MotionEvent.ACTION_DOWN: 276 | onTouch = true; 277 | mIsLongPress = true; 278 | break; 279 | case MotionEvent.ACTION_MOVE: 280 | if (event.getPointerCount() == 1) { 281 | // mIsLongPress = true; 282 | invalidate(); 283 | } 284 | break; 285 | case MotionEvent.ACTION_UP: 286 | onTouch = false; 287 | onLongPress = false; 288 | mIsLongPress = true; 289 | invalidate(); 290 | break; 291 | case MotionEvent.ACTION_CANCEL: 292 | onTouch = false; 293 | onLongPress = false; 294 | // mIsLongPress = false; 295 | // invalidate(); 296 | break; 297 | } 298 | return true; 299 | } 300 | 301 | @Override 302 | public boolean dispatchTouchEvent(MotionEvent event) { 303 | boolean onHorizontalMove = gestureCompat.onTouchEvent(event, event.getX(), event.getY()); 304 | final int action = MotionEventCompat.getActionMasked(event); 305 | 306 | onVerticalMove = false; 307 | 308 | if (action == MotionEvent.ACTION_MOVE) { 309 | if (!onHorizontalMove && !onLongPress && gestureCompat.isDragging()) { 310 | onTouch = false; 311 | onVerticalMove = true; 312 | } 313 | } 314 | 315 | getParent().requestDisallowInterceptTouchEvent(!onVerticalMove); 316 | 317 | return super.dispatchTouchEvent(event); 318 | } 319 | 320 | @Override 321 | protected void onDraw(Canvas canvas) { 322 | super.onDraw(canvas); 323 | canvas.drawColor(mBackgroundColor); 324 | canvas.save(); 325 | //绘制买入区域 326 | drawBuy(canvas); 327 | //绘制卖出区域 328 | drawSell(canvas); 329 | //绘制界面相关文案 330 | drawText(canvas); 331 | canvas.restore(); 332 | } 333 | 334 | private void drawBuy(Canvas canvas) { 335 | mGridWidth = (mDrawWidth * 1.0f / (mBuyData.size() - 1 == 0 ? 1 : mBuyData.size() - 1)); 336 | mBuyPath.reset(); 337 | mMapX.clear(); 338 | mMapY.clear(); 339 | mAmount.clear(); 340 | float x; 341 | float y; 342 | for (int i = 0; i < mBuyData.size(); i++) { 343 | if (i == 0) { 344 | mBuyPath.moveTo(0, getY(Float.valueOf(mBuyData.get(0).getAmount()))); 345 | } 346 | y = getY(Float.valueOf(mBuyData.get(i).getAmount())); 347 | if (i >= 1) { 348 | canvas.drawLine(mGridWidth * (i - 1), getY(Float.valueOf(mBuyData.get(i - 1).getAmount())), mGridWidth * i, y, mBuyLinePaint); 349 | } 350 | if (i != mBuyData.size() - 1) { 351 | mBuyPath.quadTo(mGridWidth * i, y, mGridWidth * (i + 1), getY(Float.valueOf(mBuyData.get(i + 1).getAmount()))); 352 | } 353 | 354 | x = mGridWidth * i; 355 | mMapX.put((int) x, mBuyData.get(i)); 356 | mMapY.put((int) x, y); 357 | mAmount.put((int) x, buyAmountMoney.get(i)); 358 | if (i == mBuyData.size() - 1) { 359 | mBuyPath.quadTo(mGridWidth * i, y, mGridWidth * i, mDrawHeight); 360 | mBuyPath.quadTo(mGridWidth * i, mDrawHeight, 0, mDrawHeight); 361 | mBuyPath.close(); 362 | } 363 | } 364 | if (mBuyData.size() > 1) { 365 | canvas.drawPath(mBuyPath, mBuyPathPaint); 366 | } 367 | } 368 | 369 | private void drawSell(Canvas canvas) { 370 | mGridWidth = (mDrawWidth * 1.0f / (mSellData.size() - 1 == 0 ? 1 : mSellData.size() - 1)); 371 | mSellPath.reset(); 372 | float x; 373 | float y; 374 | for (int i = 0; i < mSellData.size(); i++) { 375 | if (i == 0) { 376 | mSellPath.moveTo(mDrawWidth, getY(Float.valueOf(mSellData.get(0).getAmount()))); 377 | } 378 | y = getY(Float.valueOf(mSellData.get(i).getAmount())); 379 | if (i >= 1) { 380 | canvas.drawLine((mGridWidth * (i - 1)) + mDrawWidth, getY(Float.valueOf(mSellData.get(i - 1).getAmount())), 381 | (mGridWidth * i) + mDrawWidth, y, mSellLinePaint); 382 | } 383 | if (i != mSellData.size() - 1) { 384 | mSellPath.quadTo((mGridWidth * i) + mDrawWidth, y, 385 | (mGridWidth * (i + 1)) + mDrawWidth, getY(Float.valueOf(mSellData.get(i + 1).getAmount()))); 386 | } 387 | x = (mGridWidth * i) + mDrawWidth; 388 | mMapX.put((int) x, mSellData.get(i)); 389 | mMapY.put((int) x, y); 390 | mAmount.put((int) x, sellAmountMoney.get(i)); 391 | if (i == mSellData.size() - 1) { 392 | mSellPath.quadTo(mWidth, y, (mGridWidth * i) + mDrawWidth, mDrawHeight); 393 | mSellPath.quadTo((mGridWidth * i) + mDrawWidth, mDrawHeight, mDrawWidth, mDrawHeight); 394 | mSellPath.close(); 395 | } 396 | } 397 | if (mSellData.size() > 1) { 398 | canvas.drawPath(mSellPath, mSellPathPaint); 399 | } 400 | } 401 | 402 | private void drawText(Canvas canvas) { 403 | float value; 404 | String str; 405 | for (int j = 0; j < mLineCount; j++) { 406 | value = mMaxVolume - mMultiple * j; 407 | str = getSelectTotalValue(value); 408 | canvas.drawText(str, mWidth, mDrawHeight / mLineCount * j + 30, mTextPaint); 409 | } 410 | int size = mBottomPrice.length; 411 | int height = mDrawHeight + mBottomPriceHeight / 2 + 10; 412 | if (size > 0 && mBottomPrice[0] != null) { 413 | String data = getSelectPriceValue(mBottomPrice[0]); 414 | canvas.drawText(data, mTextPaint.measureText(data), height, mTextPaint); 415 | data = getSelectPriceValue(mBottomPrice[1]); 416 | canvas.drawText(data, mDrawWidth - 10, height, mTextPaint); 417 | data = getSelectPriceValue(mBottomPrice[2]); 418 | canvas.drawText(data, mDrawWidth + mTextPaint.measureText(data) + 10, height, mTextPaint); 419 | data = getSelectPriceValue(mBottomPrice[3]); 420 | canvas.drawText(data, mWidth, height, mTextPaint); 421 | } 422 | if (mIsLongPress) { 423 | boolean mIsHave = false; 424 | for (int key : mMapX.keySet()) { 425 | if (key == mEventX) { 426 | mIsHave = true; 427 | mLastPosition = mEventX; 428 | break; 429 | } 430 | } 431 | if (mIsHave) { 432 | drawSelectorView(canvas, mLastPosition); 433 | } else { 434 | mLastPosition = getApproximate(mEventX); 435 | drawSelectorView(canvas, mLastPosition); 436 | } 437 | } 438 | } 439 | 440 | private int getApproximate(int x) { 441 | int minDifference = Integer.MAX_VALUE; 442 | int key1 = 0; 443 | for (int key : mMapX.keySet()) { 444 | int temp = Math.abs(key - x); 445 | if (temp < minDifference) { 446 | minDifference = temp; 447 | key1 = key; 448 | } 449 | } 450 | return key1; 451 | } 452 | 453 | private void drawSelectorView(Canvas canvas, int position) { 454 | // mIsHave = true; 455 | Float y = mMapY.get(position); 456 | if (y == null) { 457 | return; 458 | } 459 | if (position < mDrawWidth) { 460 | mCirclePaint.setColor(Color.parseColor("#454E6B")); 461 | mRadioPaint.setColor(Color.parseColor("#7E9AEF")); 462 | } else { 463 | mCirclePaint.setColor(Color.parseColor("#454E6B")); 464 | mRadioPaint.setColor(Color.parseColor("#7E9AEF")); 465 | } 466 | canvas.drawCircle(position, y, mCircleRadius, mCirclePaint); 467 | canvas.drawCircle(position, y, mDotRadius, mRadioPaint); 468 | 469 | String volume = "累计数量:" + getSelectVolumeValue(Double.valueOf(mMapX.get(position).getAmount())) + " " + coin; 470 | String price = "委托价:" + getSelectPriceValue(Float.valueOf(mMapX.get(position).getPrice())) + " " + tradePost; 471 | float totalPrice = mAmount.get(position); 472 | String total = "累计金额:" + getSelectTotalValue(totalPrice) + " " + tradePost; 473 | float width = Math.max(mSelectorTextPaint.measureText(volume), mSelectorTextPaint.measureText(price)); 474 | width = Math.max(width, mSelectorTextPaint.measureText(total)); 475 | Paint.FontMetrics metrics = mSelectorTextPaint.getFontMetrics(); 476 | float textHeight = metrics.descent - metrics.ascent; 477 | 478 | int padding = dip2px(5); 479 | canvas.drawRoundRect(new RectF(mDrawWidth - width / 2 - padding, 20, mDrawWidth + width / 2 + padding * 2, textHeight * 3 + padding * 3 + 20), 10, 10, mSelectorBackgroundPaint); 480 | canvas.drawText("委托价:", 481 | mDrawWidth - width / 2 + padding + mSelectorTextPaint.measureText("委托价:"), textHeight + 22, mSelectorTextPaint); 482 | canvas.drawText(getSelectPriceValue(Float.valueOf(mMapX.get(position).getPrice())) + " " + tradePost, mDrawWidth + width / 2 + padding, textHeight + 22, mSelectorTextPaint); 483 | canvas.drawText("累计数量:", 484 | mDrawWidth - width / 2 + padding + mSelectorTextPaint.measureText("累计数量:"), textHeight * 2 + padding + 20, mSelectorTextPaint); 485 | canvas.drawText(getSelectVolumeValue(Double.valueOf(mMapX.get(position).getAmount())) + " " + coin, mDrawWidth + width / 2 + padding, textHeight * 2 + padding + 20, mSelectorTextPaint); 486 | canvas.drawText("累计金额:", 487 | mDrawWidth - width / 2 + padding + mSelectorTextPaint.measureText("累计金额:"), textHeight * 3 + padding * 2 + 20, mSelectorTextPaint); 488 | canvas.drawText(getSelectTotalValue(totalPrice) + " " + tradePost, mDrawWidth + width / 2 + padding, textHeight * 3 + padding * 2 + 20, mSelectorTextPaint); 489 | } 490 | 491 | public class comparePrice implements Comparator { 492 | @Override 493 | public int compare(DepthBuySellData o1, DepthBuySellData o2) { 494 | float str1 = Float.valueOf(o1.getPrice()); 495 | float str2 = Float.valueOf(o2.getPrice()); 496 | return Float.compare(str1, str2); 497 | } 498 | } 499 | 500 | private float getY(float volume) { 501 | return mDrawHeight - (mDrawHeight) * volume / mMaxVolume; 502 | } 503 | 504 | private String getValue(float value) { 505 | // String value = new BigDecimal(data).toPlainString(); 506 | // return subZeroAndDot(value); 507 | return String.format("%." + mPriceLimit + "f", value); 508 | } 509 | 510 | @SuppressLint("DefaultLocale") 511 | private String getVolumeValue(float value) { 512 | return String.format("%.4f", value); 513 | } 514 | 515 | private String getSelectVolumeValue(double targetValue) { 516 | if (targetValue > 100000) { 517 | BigDecimal bigDecimal = new BigDecimal(targetValue / 1000); 518 | return bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "K"; 519 | } else { 520 | BigDecimal bigDecimal = new BigDecimal(targetValue); 521 | return bigDecimal.setScale(pricisionCoin, BigDecimal.ROUND_HALF_UP).toPlainString(); 522 | } 523 | } 524 | 525 | private String getSelectPriceValue(float targetValue) { 526 | BigDecimal bigDecimal = new BigDecimal(targetValue); 527 | return bigDecimal.setScale(pricisionPrice, BigDecimal.ROUND_HALF_UP).toPlainString(); 528 | } 529 | 530 | private String getSelectTotalValue(float targetValue) { 531 | if (targetValue > 100000) { 532 | BigDecimal bigDecimal = new BigDecimal(targetValue / 1000); 533 | return bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "K"; 534 | } else { 535 | BigDecimal bigDecimal = new BigDecimal(targetValue); 536 | return bigDecimal.setScale(priTradePost, BigDecimal.ROUND_HALF_UP).toPlainString(); 537 | } 538 | } 539 | 540 | public static int dip2px(float dpValue) { 541 | final float scale = Resources.getSystem().getDisplayMetrics().density; 542 | return (int) (dpValue * scale + 0.5f); 543 | } 544 | 545 | } 546 | --------------------------------------------------------------------------------