├── 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_vertical_time_ruler.xml │ │ │ │ └── activity_main.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── kubi │ │ │ │ └── timruledemo │ │ │ │ ├── VideoBean.java │ │ │ │ ├── TimeBean.java │ │ │ │ ├── MainActivity.kt │ │ │ │ └── VerticalTimeRulerActivity.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── kubi │ │ │ └── timruledemo │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── kubi │ │ └── timruledemo │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro └── build.gradle ├── .idea ├── .name ├── codeStyles │ ├── codeStyleConfig.xml │ └── Project.xml ├── compiler.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── jarRepositories.xml ├── TimeRuler ├── .gitignore ├── consumer-rules.pro ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── kubi │ │ │ └── timeruler │ │ │ └── ExampleUnitTest.kt │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── kubi │ │ │ │ └── timeruler │ │ │ │ ├── utils │ │ │ │ └── SizeUtils.java │ │ │ │ ├── TimeRulerBar.java │ │ │ │ ├── TimeRulerBarVertical.java │ │ │ │ ├── BaseScaleBar.java │ │ │ │ └── BaseScaleBarVertical.java │ │ └── res │ │ │ └── values │ │ │ └── attrs.xml │ └── androidTest │ │ └── java │ │ └── com │ │ └── kubi │ │ └── timeruler │ │ └── ExampleInstrumentedTest.kt ├── proguard-rules.pro ├── maven-release-aar.gradle ├── build.gradle └── VERTICAL_SCROLLING_README.md ├── pic └── view.gif ├── repo └── com │ └── kubi │ └── timeruler │ └── scaleBar │ ├── maven-metadata.xml.md5 │ ├── 1.0 │ ├── scaleBar-1.0.aar.md5 │ ├── scaleBar-1.0.pom.md5 │ ├── scaleBar-1.0.aar.sha1 │ ├── scaleBar-1.0.pom.sha1 │ ├── scaleBar-1.0.aar │ └── scaleBar-1.0.pom │ ├── maven-metadata.xml.sha1 │ └── maven-metadata.xml ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── .gitignore ├── gradlew.bat ├── README.md ├── gradlew └── LICENSE /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | TimeRuleViewDemo -------------------------------------------------------------------------------- /TimeRuler/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /TimeRuler/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pic/view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/pic/view.gif -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/maven-metadata.xml.md5: -------------------------------------------------------------------------------- 1 | 78c65c57d4ff29d2e2c4fa35906da20f -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.aar.md5: -------------------------------------------------------------------------------- 1 | 55db574c8711a2dc74887cd91db1a053 -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.pom.md5: -------------------------------------------------------------------------------- 1 | 6b4c174609528964397177da49cd845a -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.aar.sha1: -------------------------------------------------------------------------------- 1 | 2e6e3860a3684b4b50cf56fe49c22a8234cf21d3 -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.pom.sha1: -------------------------------------------------------------------------------- 1 | 3c1ea4dbe4b2866024e9395fded6e2022b35002b -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/maven-metadata.xml.sha1: -------------------------------------------------------------------------------- 1 | 86131960cfec8921eeaedd16c377e74f7afb173a -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':TimeRuler' 2 | include ':app' 3 | rootProject.name = "TimeRuleViewDemo" -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | TimeRuleViewDemo 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/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/Liberations/TimeRuler/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/Liberations/TimeRuler/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/Liberations/TimeRuler/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/Liberations/TimeRuler/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liberations/TimeRuler/HEAD/repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.aar -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Mar 31 10:26:38 CST 2021 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-8.14.3-bin.zip -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.kubi.timeruler 4 | scaleBar 5 | 6 | 1.0 7 | 8 | 1.0 9 | 10 | 20200824043532 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/kubi/timruledemo/VideoBean.java: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo; 2 | 3 | public class VideoBean { 4 | public long startTime; 5 | public long endTime; 6 | public boolean isSos; 7 | 8 | public VideoBean(long startTime, long endTime, boolean isSos) { 9 | this.startTime = startTime; 10 | this.endTime = endTime; 11 | this.isSos = isSos; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/test/java/com/kubi/timruledemo/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo 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 | } -------------------------------------------------------------------------------- /TimeRuler/src/test/java/com/kubi/timeruler/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timeruler 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 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /TimeRuler/src/main/java/com/kubi/timeruler/utils/SizeUtils.java: -------------------------------------------------------------------------------- 1 | package com.kubi.timeruler.utils; 2 | 3 | import android.content.Context; 4 | import android.util.TypedValue; 5 | 6 | public class SizeUtils { 7 | public static int dp2px(Context context, float dpValue) { 8 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics()); 9 | } 10 | 11 | public static int sp2px(Context context, float spValue) { 12 | return (int) (spValue * context.getResources().getDisplayMetrics().scaledDensity + 0.5f); 13 | } 14 | 15 | public static int px2sp(Context context, float pxValue) { 16 | return (int) (pxValue / context.getResources().getDisplayMetrics().scaledDensity + 0.5f); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/kubi/timruledemo/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo 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.kubi.timruledemo", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /TimeRuler/src/androidTest/java/com/kubi/timeruler/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timeruler 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.kubi.timeruler.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /TimeRuler/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 -------------------------------------------------------------------------------- /app/src/main/java/com/kubi/timruledemo/TimeBean.java: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo; 2 | 3 | import android.graphics.Color; 4 | 5 | import com.kubi.timeruler.TimeRulerBar; 6 | 7 | import java.util.List; 8 | 9 | public class TimeBean implements TimeRulerBar.ColorScale { 10 | List videoBeans; 11 | 12 | public TimeBean(List videoBeans) { 13 | this.videoBeans = videoBeans; 14 | } 15 | 16 | @Override 17 | public int getSize() { 18 | return videoBeans.size(); 19 | } 20 | 21 | @Override 22 | public long getStart(int index) { 23 | return videoBeans.get(index).startTime; 24 | } 25 | 26 | @Override 27 | public long getEnd(int index) { 28 | return videoBeans.get(index).endTime; 29 | } 30 | 31 | @Override 32 | public int getColor(int index) { 33 | return videoBeans.get(index).isSos ? Color.RED : Color.GREEN; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /TimeRuler/maven-release-aar.gradle: -------------------------------------------------------------------------------- 1 | // 1.maven-插件 2 | apply plugin: 'maven' 3 | // 2.maven-信息 4 | ext {// ext is a gradle closure allowing the declaration of global properties 5 | PUBLISH_GROUP_ID = 'com.kubi.timeruler' 6 | PUBLISH_ARTIFACT_ID = 'scaleBar' 7 | PUBLISH_VERSION = "1.0" 8 | } 9 | // 3.maven-路径 10 | uploadArchives { 11 | repositories.mavenDeployer { 12 | //Maven仓库本地路径(可以自己新建文件夹,复制链接过来) 13 | //注意”file://“ + 路径,有三个斜杠,别漏了 14 | repository(url: uri('../repo')) //定义本地maven仓库的地址 15 | 16 | pom.project { 17 | groupId project.PUBLISH_GROUP_ID 18 | artifactId project.PUBLISH_ARTIFACT_ID 19 | version project.PUBLISH_VERSION 20 | } 21 | } 22 | } 23 | 24 | //以下代码会生成 jar 包源文件,如果是不开源码,请不要输入这段 25 | //aar包内包含注释 26 | /* 27 | task androidSourcesJar(type: Jar) { 28 | classifier = 'sources' 29 | from android.sourceSets.main.java.sourceFiles 30 | } 31 | 32 | artifacts { 33 | archives androidSourcesJar 34 | }*/ 35 | -------------------------------------------------------------------------------- /TimeRuler/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | //aar打包 3 | //apply from: 'maven-release-aar.gradle' 4 | //apply plugin: 'com.github.dcendents.android-maven' 5 | //group='com.github.fiui' 6 | //version = '1.0' 7 | //apply from: '../gradle/build_upload.gradle' 8 | 9 | android { 10 | compileSdkVersion 36 11 | 12 | namespace "com.kubi.timeruler" 13 | 14 | defaultConfig { 15 | minSdkVersion 21 16 | targetSdkVersion 36 17 | versionCode 1 18 | versionName "1.0" 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | consumerProguardFiles "consumer-rules.pro" 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(dir: "libs", include: ["*.jar"]) 34 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 35 | implementation 'androidx.core:core-ktx:1.17.0' 36 | implementation 'androidx.appcompat:appcompat:1.7.1' 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | android { 4 | compileSdkVersion 36 5 | namespace "com.kubi.timruledemo" 6 | 7 | defaultConfig { 8 | applicationId "com.kubi.timruledemo" 9 | minSdkVersion 21 10 | targetSdkVersion 36 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | } 16 | 17 | buildFeatures { 18 | viewBinding true 19 | } 20 | 21 | kotlinOptions { 22 | jvmTarget = "1.8" 23 | } 24 | 25 | 26 | 27 | buildTypes { 28 | release { 29 | minifyEnabled false 30 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 31 | } 32 | } 33 | } 34 | 35 | dependencies { 36 | implementation fileTree(dir: "libs", include: ["*.jar"]) 37 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 38 | implementation 'androidx.core:core-ktx:1.17.0' 39 | implementation 'androidx.appcompat:appcompat:1.7.1' 40 | implementation 'androidx.constraintlayout:constraintlayout:2.2.1' 41 | implementation project(':TimeRuler') 42 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official -------------------------------------------------------------------------------- /repo/com/kubi/timeruler/scaleBar/1.0/scaleBar-1.0.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.kubi.timeruler 6 | scaleBar 7 | 1.0 8 | aar 9 | 10 | 11 | org.jetbrains.kotlin 12 | kotlin-android-extensions-runtime 13 | 1.3.72 14 | compile 15 | 16 | 17 | org.jetbrains.kotlin 18 | kotlin-stdlib 19 | 1.3.72 20 | compile 21 | 22 | 23 | androidx.core 24 | core-ktx 25 | 1.3.1 26 | compile 27 | 28 | 29 | androidx.appcompat 30 | appcompat 31 | 1.2.0 32 | compile 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | 17 | # Gradle files 18 | .gradle/ 19 | build/ 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | 27 | # Log Files 28 | *.log 29 | 30 | # Android Studio Navigation editor temp files 31 | .navigation/ 32 | 33 | # Android Studio captures folder 34 | captures/ 35 | 36 | # IntelliJ 37 | *.iml 38 | .idea/workspace.xml 39 | .idea/tasks.xml 40 | .idea/gradle.xml 41 | .idea/assetWizardSettings.xml 42 | .idea/dictionaries 43 | .idea/libraries 44 | .idea/caches 45 | 46 | # Keystore files 47 | # Uncomment the following lines if you do not want to check your keystore files in. 48 | #*.jks 49 | #*.keystore 50 | 51 | # External native build folder generated in Android Studio 2.2 and later 52 | .externalNativeBuild 53 | 54 | # Google Services (e.g. APIs or Firebase) 55 | # google-services.json 56 | 57 | # Freeline 58 | freeline.py 59 | freeline/ 60 | freeline_project_description.json 61 | 62 | # fastlane 63 | fastlane/report.xml 64 | fastlane/Preview.html 65 | fastlane/screenshots 66 | fastlane/test_output 67 | fastlane/readme.md 68 | 69 | # Version control 70 | vcs.xml 71 | 72 | # lint 73 | lint/intermediates/ 74 | lint/generated/ 75 | lint/outputs/ 76 | lint/tmp/ 77 | # lint/reports/ 78 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | 39 | 40 | 44 | 45 | 49 | 50 | 54 | 55 | 59 | 60 | 64 | 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TimeRuler 2 | 3 | [![](https://jitpack.io/v/Liberations/TimeRuler.svg)](https://jitpack.io/#Liberations/TimeRuler) 4 | 5 | 可以缩放平移的时间刻度尺,方便自定义UI需求。仿萤石云历史录像时间轴 6 | 7 | ## 效果: 8 |

timeBar

9 | 10 | Add it to your build.gradle with: 11 | ```gradle 12 | allprojects { 13 | repositories { 14 | maven { url "https://jitpack.io" } 15 | } 16 | } 17 | ``` 18 | and: 19 | 20 | ```gradle 21 | dependencies { 22 | implementation 'com.github.Liberations:TimeRuler:{latest version}' 23 | } 24 | ``` 25 | 26 | ## BaseScaleBar支持的属性设置(Attributes): 27 | |name|format|description| 28 | |:---:|:---:|:---:| 29 | |keyTickHeight|dimension,reference|关键刻度高度| 30 | |tickValueOffset|dimension,reference|刻度文字偏移| 31 | |cursorPosition|float|游标相对view width的位置 0~ 1| 32 | |baselinePosition|float|刻度尺横线相对view height的位置 0~1| 33 | |tickColor|color,reference|刻度线颜色| 34 | |showTickLine|boolean|是否显示刻度横线| 35 | |showCursorLine|boolean|是否显示游标线| 36 | |showTickValue|boolean|是否显示刻度值| 37 | |tickDirectionUp|boolean|刻度线开口方向| 38 | |cursorLineColor|color,reference|游标线颜色| 39 | |maxScaleValueSize|color,reference|刻度值最大规格(字体大小)| 40 | 41 | 42 | ## TimeRulerBar支持的额外属性(Attributes): 43 | |name|format|description| 44 | |:---:|:---:|:---:| 45 | |tickValueColor|color,reference|刻度值颜色| 46 | |colorScaleBackground|color,reference|颜色区域背景色| 47 | |cursorBackgroundColor|color,reference|游标背景色| 48 | |drawCursorContent|boolean|是否绘制游标内容| 49 | |tickValueSize|dimension,reference|刻度值文字大小| 50 | |videoAreaOffset|dimension,reference|绘制颜色区域相对于顶部的偏移量| 51 | |videoAreaHeight|dimension,reference|绘制颜色区域的高度| 52 | |tickValueColor|color,reference|刻度值颜色| 53 | 54 | ## 基本使用 55 | 56 | ``` 57 | val calendar = Calendar.getInstance() 58 | 59 | // 00:00:00 000 60 | calendar[Calendar.HOUR_OF_DAY] = 0 61 | calendar[Calendar.MINUTE] = 0 62 | calendar[Calendar.SECOND] = 0 63 | calendar[Calendar.MILLISECOND] = 0 64 | var startTime = calendar.timeInMillis 65 | 66 | // 23:59:59 999 67 | calendar[Calendar.HOUR_OF_DAY] = 23 68 | calendar[Calendar.MINUTE] = 59 69 | calendar[Calendar.SECOND] = 59 70 | calendar[Calendar.MILLISECOND] = 999 71 | var endTime = calendar.timeInMillis 72 | //设置刻度尺时间范围 73 | timeBar.setRange(startTime, endTime) 74 | //设置初始化缩放模式 75 | timeBar.setMode(TimeRulerBar.MODE_UINT_30_MIN) 76 | //设置当前刻度值 77 | timeBar.setCursorValue(System.currentTimeMillis()) 78 | ``` 79 | 80 | ## 滑动事件监听 81 | 82 | ``` 83 | timeBar.setOnCursorListener(object : BaseScaleBar.OnCursorListener { 84 | override fun onStartTrackingTouch(cursorValue: Long) { 85 | //开滑动 86 | 87 | } 88 | 89 | override fun onProgressChanged(cursorValue: Long,fromeUser:Boolean) { 90 | //刻度发生变化 fromeUser是否触摸事件触发 91 | } 92 | 93 | override fun onStopTrackingTouch(cursorValue: Long) { 94 | //结束滑动 95 | 96 | } 97 | }) 98 | ``` 99 | ## 更多方法参照Demo 100 | -------------------------------------------------------------------------------- /.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 |
-------------------------------------------------------------------------------- /TimeRuler/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 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /TimeRuler/VERTICAL_SCROLLING_README.md: -------------------------------------------------------------------------------- 1 | # TimeRuler 纵向滚动功能 2 | 3 | ## 概述 4 | 5 | TimeRuler库现在支持纵向滚动功能!除了原有的横向滚动`TimeRulerBar`,我们新增了纵向滚动的`TimeRulerBarVertical`组件。 6 | 7 | ## 新增组件 8 | 9 | ### 1. BaseScaleBarVertical 10 | - 纵向滚动的基础类 11 | - 支持垂直方向的时间轴滚动 12 | - 提供与横向版本相同的功能,但适配了纵向布局 13 | 14 | ### 2. TimeRulerBarVertical 15 | - 纵向滚动的时间尺组件 16 | - 继承自`BaseScaleBarVertical` 17 | - 提供完整的时间轴功能,包括缩放、拖拽、惯性滚动等 18 | 19 | ## 使用方法 20 | 21 | ### 在XML布局中使用 22 | 23 | ```xml 24 | 41 | ``` 42 | 43 | ### 在代码中配置 44 | 45 | ```kotlin 46 | // 设置时间范围 47 | val calendar = Calendar.getInstance() 48 | calendar[Calendar.HOUR_OF_DAY] = 0 49 | calendar[Calendar.MINUTE] = 0 50 | calendar[Calendar.SECOND] = 0 51 | calendar[Calendar.MILLISECOND] = 0 52 | val startTime = calendar.timeInMillis 53 | 54 | calendar[Calendar.HOUR_OF_DAY] = 23 55 | calendar[Calendar.MINUTE] = 59 56 | calendar[Calendar.SECOND] = 59 57 | calendar[Calendar.MILLISECOND] = 999 58 | val endTime = calendar.timeInMillis 59 | 60 | timeBarVertical.setRange(startTime, endTime) 61 | timeBarVertical.setMode(TimeRulerBarVertical.MODE_UINT_30_MIN) 62 | timeBarVertical.setCursorValue(System.currentTimeMillis()) 63 | 64 | // 设置监听器 65 | timeBarVertical.setOnCursorListener(object : BaseScaleBarVertical.OnCursorListener { 66 | override fun onStartTrackingTouch(cursorValue: Long) { 67 | // 开始拖拽 68 | } 69 | 70 | override fun onProgressChanged(cursorValue: Long, fromUser: Boolean) { 71 | // 时间值变化 72 | val timeText = SimpleDateFormat("HH:mm:ss").format(Date(cursorValue)) 73 | } 74 | 75 | override fun onStopTrackingTouch(cursorValue: Long) { 76 | // 停止拖拽 77 | } 78 | }) 79 | ``` 80 | 81 | ## 主要特性 82 | 83 | ### 1. 纵向滚动支持 84 | - 支持垂直方向的拖拽滚动 85 | - 支持惯性滚动 86 | - 支持缩放功能 87 | 88 | ### 2. 刻度线方向控制 89 | - `tickDirectionLeft`: 控制刻度线向左还是向右延伸 90 | - 默认值为`true`(向左) 91 | 92 | ### 3. 游标位置控制 93 | - `cursorPosition`: 游标在视图中的相对位置(0-1) 94 | - 默认值为0.5(中间位置) 95 | 96 | ### 4. 基线位置控制 97 | - `baselinePosition`: 刻度尺基线在视图中的相对位置(0-1) 98 | - 默认值为0.67 99 | 100 | ## 属性说明 101 | 102 | ### BaseScaleBarVertical 属性 103 | - `keyTickWidthVertical`: 关键刻度宽度 104 | - `tickValueOffsetVertical`: 文字偏移量 105 | - `normalTickRatioVertical`: 普通刻度与关键刻度的比率 106 | - `cursorPositionVertical`: 游标相对位置 107 | - `baselinePositionVertical`: 基线相对位置 108 | - `tickColorVertical`: 刻度线颜色 109 | - `showTickLineVertical`: 是否显示刻度线 110 | - `showCursorLineVertical`: 是否显示游标线 111 | - `showTickValueVertical`: 是否显示刻度值 112 | - `tickDirectionLeftVertical`: 刻度线方向 113 | - `cursorLineColorVertical`: 游标线颜色 114 | - `maxScaleValueSizeVertical`: 刻度值最大字体大小 115 | 116 | ### TimeRulerBarVertical 属性 117 | - `tickValueColorVertical`: 刻度值颜色 118 | - `videoAreaWidthVertical`: 视频区域宽度 119 | - `videoAreaOffsetVertical`: 视频区域偏移量 120 | - `tickValueSizeVertical`: 刻度值字体大小 121 | - `drawCursorContentVertical`: 是否绘制游标内容 122 | - `cursorBackgroundColorVertical`: 游标背景颜色 123 | - `cursorValueSizeVertical`: 游标值字体大小 124 | - `colorScaleBackgroundVertical`: 颜色刻度尺背景 125 | 126 | ## 模式支持 127 | 128 | 纵向滚动组件支持与横向版本相同的时间模式: 129 | 130 | - `MODE_UINT_1_MIN`: 1分钟单位 131 | - `MODE_UINT_5_MIN`: 5分钟单位 132 | - `MODE_UINT_10_MIN`: 10分钟单位 133 | - `MODE_UINT_30_MIN`: 30分钟单位 134 | - `MODE_UINT_1_HOUR`: 1小时单位 135 | 136 | ## 示例项目 137 | 138 | 查看 `VerticalTimeRulerActivity` 了解完整的使用示例,包括: 139 | - 基本配置 140 | - 事件监听 141 | - 缩放控制 142 | - 游标显示控制 143 | - 刻度线方向控制 144 | 145 | ## 注意事项 146 | 147 | 1. 纵向滚动组件使用画布旋转来实现垂直布局,性能与横向版本相当 148 | 2. 触摸事件已适配纵向滚动,使用`distanceY`而不是`distanceX` 149 | 3. 惯性滚动同样适配了纵向方向 150 | 4. 所有原有的功能都得到保留,只是方向从横向变为纵向 151 | 5. 游标绘制和颜色区域绘制已完全适配纵向布局 152 | 6. 所有public方法都添加了详细的JavaDoc注释 153 | 154 | ## 兼容性 155 | 156 | - 与原有横向滚动组件完全兼容 157 | - 可以同时使用横向和纵向组件 158 | - 共享相同的数据模型和接口 159 | -------------------------------------------------------------------------------- /app/src/main/java/com/kubi/timruledemo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.widget.SeekBar 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.kubi.timeruler.BaseScaleBar 8 | import com.kubi.timeruler.TimeRulerBar 9 | import com.kubi.timruledemo.databinding.ActivityMainBinding 10 | import java.text.SimpleDateFormat 11 | import java.util.* 12 | 13 | class MainActivity : AppCompatActivity() { 14 | lateinit var binding: ActivityMainBinding 15 | val cursorDateFormat = SimpleDateFormat("MM月dd日 HH:mm:ss") 16 | var nowTime = 1 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | binding = ActivityMainBinding.inflate(layoutInflater) 20 | setContentView(binding.root) 21 | initTimeBar() 22 | } 23 | 24 | private fun initTimeBar() { 25 | val calendar = Calendar.getInstance() 26 | 27 | // 00:00:00 000 28 | calendar[Calendar.HOUR_OF_DAY] = 0 29 | calendar[Calendar.MINUTE] = 0 30 | calendar[Calendar.SECOND] = 0 31 | calendar[Calendar.MILLISECOND] = 0 32 | var startTime = calendar.timeInMillis 33 | 34 | // 23:59:59 999 35 | calendar[Calendar.HOUR_OF_DAY] = 23 36 | calendar[Calendar.MINUTE] = 59 37 | calendar[Calendar.SECOND] = 59 38 | calendar[Calendar.MILLISECOND] = 999 39 | var endTime = calendar.timeInMillis 40 | 41 | binding.timeBar.setRange(startTime, endTime) 42 | binding.timeBar.setMode(TimeRulerBar.MODE_UINT_30_MIN) 43 | binding.timeBar.setCursorValue(System.currentTimeMillis()) 44 | 45 | binding.timeBar.setOnCursorListener(object : BaseScaleBar.OnCursorListener { 46 | override fun onStartTrackingTouch(cursorValue: Long) { 47 | 48 | } 49 | 50 | override fun onProgressChanged(cursorValue: Long, fromeUser: Boolean) { 51 | //监听时间戳变化 52 | binding.tvData.text = cursorDateFormat.format(Date(cursorValue)) 53 | } 54 | 55 | override fun onStopTrackingTouch(cursorValue: Long) { 56 | 57 | } 58 | }) 59 | 60 | binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { 61 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 62 | binding.timeBar.setScale(progress.toFloat()) 63 | } 64 | 65 | override fun onStartTrackingTouch(seekBar: SeekBar?) { 66 | } 67 | 68 | override fun onStopTrackingTouch(seekBar: SeekBar?) { 69 | } 70 | 71 | }) 72 | 73 | binding.seekAreaOffset.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { 74 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 75 | binding.timeBar.setVideoAreaOffset(progress) 76 | } 77 | 78 | override fun onStartTrackingTouch(seekBar: SeekBar?) { 79 | } 80 | 81 | override fun onStopTrackingTouch(seekBar: SeekBar?) { 82 | } 83 | 84 | }) 85 | 86 | binding.btnDir.setOnClickListener { 87 | binding.btnDir.isSelected = !binding.btnDir.isSelected 88 | binding.timeBar.setTickDirection(binding.btnDir.isSelected) 89 | } 90 | 91 | binding.btnShowCursor.setOnClickListener { 92 | binding.btnShowCursor.isSelected = !binding.btnShowCursor.isSelected 93 | binding.timeBar.setShowCursor(binding.btnShowCursor.isSelected); 94 | } 95 | 96 | binding.btnPlay.setOnClickListener { 97 | nowTime++ 98 | binding.timeBar.setCursorValue(System.currentTimeMillis() + 1000 * nowTime * 60) 99 | } 100 | 101 | binding.btnVerticalDemo.setOnClickListener { 102 | startActivity(Intent(this, VerticalTimeRulerActivity::class.java)) 103 | } 104 | 105 | setData() 106 | 107 | } 108 | 109 | private fun setData() { 110 | var videos = mutableListOf() 111 | var testTime = System.currentTimeMillis() 112 | for (i in 1..5) { 113 | val video = VideoBean(testTime, testTime + i * 10 * 60 * 1000, i % 2 == 0) 114 | videos.add(video) 115 | testTime += i * 15 * 60 * 1000 116 | } 117 | val timeBean = TimeBean(videos) 118 | binding.timeBar.setColorScale(timeBean) 119 | } 120 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kubi/timruledemo/VerticalTimeRulerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kubi.timruledemo 2 | 3 | import android.os.Bundle 4 | import android.widget.SeekBar 5 | import androidx.appcompat.app.AppCompatActivity 6 | import com.kubi.timeruler.BaseScaleBarVertical 7 | import com.kubi.timeruler.TimeRulerBarVertical 8 | import com.kubi.timruledemo.databinding.ActivityVerticalTimeRulerBinding 9 | import java.text.SimpleDateFormat 10 | import java.util.* 11 | 12 | class VerticalTimeRulerActivity : AppCompatActivity() { 13 | lateinit var binding: ActivityVerticalTimeRulerBinding 14 | val cursorDateFormat = SimpleDateFormat("MM月dd日 HH:mm:ss") 15 | var nowTime = 1 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | binding = ActivityVerticalTimeRulerBinding.inflate(layoutInflater) 20 | setContentView(binding.root) 21 | initTimeBar() 22 | } 23 | 24 | private fun initTimeBar() { 25 | val calendar = Calendar.getInstance() 26 | 27 | // 00:00:00 000 28 | calendar[Calendar.HOUR_OF_DAY] = 0 29 | calendar[Calendar.MINUTE] = 0 30 | calendar[Calendar.SECOND] = 0 31 | calendar[Calendar.MILLISECOND] = 0 32 | var startTime = calendar.timeInMillis 33 | 34 | // 23:59:59 999 35 | calendar[Calendar.HOUR_OF_DAY] = 23 36 | calendar[Calendar.MINUTE] = 59 37 | calendar[Calendar.SECOND] = 59 38 | calendar[Calendar.MILLISECOND] = 999 39 | var endTime = calendar.timeInMillis 40 | 41 | binding.timeBarVertical.setRange(startTime, endTime) 42 | binding.timeBarVertical.setMode(TimeRulerBarVertical.MODE_UINT_30_MIN) 43 | binding.timeBarVertical.setCursorValue(System.currentTimeMillis()) 44 | 45 | binding.timeBarVertical.setOnCursorListener(object : BaseScaleBarVertical.OnCursorListener { 46 | override fun onStartTrackingTouch(cursorValue: Long) { 47 | 48 | } 49 | 50 | override fun onProgressChanged(cursorValue: Long, fromeUser: Boolean) { 51 | //监听时间戳变化 52 | binding.tvDataVertical.text = cursorDateFormat.format(Date(cursorValue)) 53 | } 54 | 55 | override fun onStopTrackingTouch(cursorValue: Long) { 56 | 57 | } 58 | }) 59 | 60 | binding.seekBarVertical.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { 61 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 62 | binding.timeBarVertical.setScale(progress.toFloat()) 63 | } 64 | 65 | override fun onStartTrackingTouch(seekBar: SeekBar?) { 66 | } 67 | 68 | override fun onStopTrackingTouch(seekBar: SeekBar?) { 69 | } 70 | 71 | }) 72 | 73 | binding.seekAreaOffsetVertical.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { 74 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 75 | binding.timeBarVertical.setVideoAreaOffset(progress) 76 | } 77 | 78 | override fun onStartTrackingTouch(seekBar: SeekBar?) { 79 | } 80 | 81 | override fun onStopTrackingTouch(seekBar: SeekBar?) { 82 | } 83 | 84 | }) 85 | 86 | binding.btnDirVertical.setOnClickListener { 87 | binding.btnDirVertical.isSelected = !binding.btnDirVertical.isSelected 88 | binding.timeBarVertical.setTickDirection(binding.btnDirVertical.isSelected) 89 | } 90 | 91 | binding.btnShowCursorVertical.setOnClickListener { 92 | binding.btnShowCursorVertical.isSelected = !binding.btnShowCursorVertical.isSelected 93 | binding.timeBarVertical.setShowCursor(binding.btnShowCursorVertical.isSelected); 94 | } 95 | 96 | binding.btnPlayVertical.setOnClickListener { 97 | nowTime++ 98 | binding.timeBarVertical.setCursorValue(System.currentTimeMillis() + 1000 * nowTime * 60) 99 | } 100 | setData() 101 | 102 | } 103 | 104 | private fun setData() { 105 | var videos = mutableListOf() 106 | var testTime = System.currentTimeMillis() 107 | for (i in 1..5) { 108 | val video = VideoBean(testTime, testTime + i * 10 * 60 * 1000, i % 2 == 0) 109 | videos.add(video) 110 | testTime += i * 15 * 60 * 1000 111 | } 112 | val timeBean = TimeBean(videos) 113 | binding.timeBarVertical.setColorScale(timeBean) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_vertical_time_ruler.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 28 | 29 | 39 | 40 | 49 | 50 | 59 | 60 | 69 | 70 | 79 | 80 |