├── .idea ├── libraries │ ├── Dart_SDK.xml │ └── Flutter_for_Android.xml ├── modules.xml └── runConfigurations │ └── example_lib_main_dart.xml ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── example │ └── flutterseekbar │ └── FlutterSeekbarPlugin.java ├── example ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutterseekbarexample │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ └── contents.xcworkspacedata │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m ├── lib │ └── main.dart ├── pubspec.yaml └── test │ └── widget_test.dart ├── flutter_seekbar.iml ├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterSeekbarPlugin.h │ └── FlutterSeekbarPlugin.m └── flutter_seekbar.podspec ├── lib ├── flutter_seekbar.dart └── seekbar │ ├── get_text_width.dart │ ├── progress_value.dart │ ├── section_text_model.dart │ └── seekbar.dart ├── pubspec.yaml └── screenshot.gif /.idea/libraries/Dart_SDK.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/Flutter_for_Android.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations/example_lib_main_dart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: c5251cdc0257ad85db9ad8c2caf70d65c5979eee 8 | channel: master 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 LiucCheng 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_seekbar 2 | 3 | flutter 插件 4 | 5 | flutter seekbar 6 | 7 | A beautiful flutter custom seekbar, which has a bubble view with progress appearing upon when seeking. 自定义SeekBar,进度变化更以可视化气泡样式呈现 8 | 9 | 10 | 11 | ### 效果图 12 | ![flutter_seekbar](/screenshot.gif) 13 | 14 | #### 引入: 15 | ``` 16 | dependencies: 17 | flutter: 18 | sdk: flutter 19 | flutter_seekbar: 20 | git: https://github.com/LiuC520/flutter_seekbar.git 21 | ``` 22 | #### 属性 23 | 24 | | Attribute 属性 | 默认值|Description 描述 | 25 | |:--- |:--- |:---| 26 | | min | 0.0 |最小值| 27 | | max | 100.0 |最大值| 28 | | value |0 |默认进度值,最大值默认是100,指定了max,最大值是max| 29 | | backgroundColor | 页面配置的backgroundColor |进度条背景颜色| 30 | | progressColor | accentColor | 当前进度的颜色| 31 | | progresseight | 5 |进度条的高度| 32 | | sectionCount | 1 |进度条分为几段| 33 | | sectionColor | 当前进度的颜色 |进度条每一个间隔的圆圈的颜色| 34 | | sectionUnSelecteColor | 进度条的背景颜色 |间隔未选中的颜色| 35 | | sectionRadius | 0.0 |间隔圆的半径 36 | | showSectionText | false |是否显示刻度值| 37 | | sectionTexts | 空数组 |自定义刻度值,是个数组,数组必须是SectionTextModel的实体| 38 | | sectionTextSize |14| 刻度值字体的大小| 39 | | afterDragShowSectionText | false|是否在拖拽结束后显示刻度值| 40 | | sectionTextColor | 黑色 | 刻度值字体的颜色| 41 | | sectionSelectTextColor | 透明(Colors.transparent) | 选中的刻度值字体的颜色| 42 | | sectionDecimal | 0|刻度值的小数点位数| 43 | | sectionTextMarginTop | 4.0 |刻度值距离进度条的间距| 44 | | indicatorRadius | 进度条的高度 + 2 |中间指示器圆圈的半径| 45 | | indicatorColor |进度条当前进度的颜色 |中间指示器圆圈的颜色| 46 | | semanticsLabel | |这个是给盲人用的,屏幕阅读器的要读出来的标签 47 | | semanticsValue | |这个是给盲人用的,屏幕阅读器的要读出的进度条的值 48 | | onValueChanged | 默认是空方法 | 进度改变的回调,是ProgressValue的实体,里面包含了进度,0-1,还包含了当前的进度值 | 49 | | isRound | true ( 圆角 ) |圆角还是直角,圆角的默认半径是进度条高度的一半 50 | | hideBubble | true|是否显示气泡,默认是隐藏 51 | | alwaysShowBubble |false |是否一致显示气泡,默认是false,也就是只有在拖拽的时间才显示气泡,拖拽结束不显示 52 | | bubbleRadius | 20|气泡的半径 53 | | bubbleHeight | 60 |气泡的总高度,包含顶部圆形的半径,默认是气泡半径的3倍 54 | | bubbleColor | 当前进度条的颜色 | 气泡的背景颜色 | 55 | | bubbleTextColor |白色 |气泡中当前进度值的字体颜色,默认是白色 56 | | bubbleTextSize |14 |气泡中当前进度值的字体大小,默认是14 57 | | bubbleMargin | 4|气泡底部距离进度条的高度,默认是4 58 | | bubbleInCenter | false |气泡是否在进度条的中间显示,默认是 59 | | isCanTouch | true |是否响应触摸事件,默认是响应的,也就是可以拖拽显示进度的 60 | 61 | 62 | 63 | 64 | # Example 65 | 66 | 1、首先在pubspec.yaml中添加依赖 67 | ``` 68 | dependencies: 69 | flutter: 70 | sdk: flutter 71 | flutter_seekbar: 72 | git: https://github.com/LiuC520/flutter_seekbar.git 73 | 74 | ``` 75 | 76 | 2、示例 77 | ``` 78 | import 'package:flutter_seekbar/flutter_seekbar.dart' show ProgressValue, SectionTextModel, SeekBar; 79 | 80 | 81 | 82 | class Home extends StatefulWidget { 83 | @override 84 | State createState() { 85 | return _HomeState(); 86 | } 87 | } 88 | 89 | class _HomeState extends State with SingleTickerProviderStateMixin { 90 | List sectionTexts = []; 91 | 92 | @override 93 | void initState() { 94 | super.initState(); 95 | sectionTexts.add( 96 | SectionTextModel(position: 0, text: 'bad', progressColor: Colors.red)); 97 | sectionTexts.add(SectionTextModel( 98 | position: 2, text: 'good', progressColor: Colors.yellow)); 99 | sectionTexts.add(SectionTextModel( 100 | position: 4, text: 'great', progressColor: Colors.green)); 101 | } 102 | 103 | @override 104 | Widget build(BuildContext context) { 105 | return SingleChildScrollView( 106 | child: Container( 107 | padding: EdgeInsets.fromLTRB(0, 80, 0, 0), 108 | child: Column( 109 | children: [ 110 | Column( 111 | children: [ 112 | Container( 113 | width: 200, 114 | child: SeekBar( 115 | progresseight: 10, 116 | indicatorRadius: 0.0, 117 | value: v, 118 | isRound: false, 119 | progressColor: Colors.red, 120 | )), 121 | GestureDetector( 122 | onTap: () => { 123 | this.setState(() { 124 | v = 60; 125 | }) 126 | }, 127 | child: Container( 128 | margin: EdgeInsets.fromLTRB(0, 30, 0, 0), 129 | width: 50, 130 | height: 50, 131 | color: Colors.blue, 132 | child: Text( 133 | "直角", 134 | textDirection: TextDirection.ltr, 135 | maxLines: 1, 136 | style: TextStyle(fontSize: 10), 137 | ), 138 | )), 139 | ], 140 | ), 141 | Padding( 142 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 143 | child: Column( 144 | children: [ 145 | Container( 146 | width: 200, 147 | child: SeekBar( 148 | isCanTouch: false, 149 | indicatorRadius: 0.0, 150 | progresseight: 5, 151 | value: 50, 152 | hideBubble: false, 153 | alwaysShowBubble: true, 154 | bubbleRadius: 14, 155 | bubbleColor: Colors.purple, 156 | bubbleTextColor: Colors.white, 157 | bubbleTextSize: 14, 158 | bubbleMargin: 4, 159 | bubbleInCenter: true)), 160 | Text( 161 | "圆角,气泡居中,始终显示气泡", 162 | textDirection: TextDirection.ltr, 163 | maxLines: 1, 164 | style: TextStyle(fontSize: 10), 165 | ), 166 | ], 167 | ), 168 | ), 169 | Padding( 170 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 171 | child: Column( 172 | children: [ 173 | Container( 174 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 175 | width: 200, 176 | child: SeekBar( 177 | progresseight: 5, 178 | value: 20, 179 | )), 180 | Text( 181 | "圆角带指示器", 182 | textDirection: TextDirection.ltr, 183 | style: TextStyle(fontSize: 10), 184 | ), 185 | ], 186 | ), 187 | ), 188 | Padding( 189 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 190 | child: Column( 191 | children: [ 192 | Container( 193 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 194 | width: 200, 195 | child: SeekBar( 196 | progresseight: 5, 197 | value: 50, 198 | sectionCount: 5, 199 | )), 200 | Text( 201 | "带间隔带指示器", 202 | textDirection: TextDirection.ltr, 203 | style: TextStyle(fontSize: 10), 204 | ) 205 | ], 206 | ), 207 | ), 208 | Padding( 209 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 210 | child: Column( 211 | children: [ 212 | Container( 213 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 214 | width: 200, 215 | child: SeekBar( 216 | progresseight: 5, 217 | value: 50, 218 | sectionCount: 4, 219 | sectionRadius: 6, 220 | sectionColor: Colors.red, 221 | )), 222 | Text( 223 | "带间隔画间隔的指示器", 224 | textDirection: TextDirection.ltr, 225 | style: TextStyle(fontSize: 10), 226 | ) 227 | ], 228 | ), 229 | ), 230 | Padding( 231 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 232 | child: Column( 233 | children: [ 234 | Row( 235 | crossAxisAlignment: CrossAxisAlignment.center, 236 | mainAxisSize: MainAxisSize.min, 237 | textDirection: TextDirection.ltr, 238 | children: [ 239 | Text( 240 | '-10', 241 | textDirection: TextDirection.ltr, 242 | ), 243 | Container( 244 | margin: EdgeInsets.fromLTRB(10, 0, 10, 4), 245 | width: 200, 246 | child: SeekBar( 247 | progresseight: 5, 248 | value: 58, 249 | min: -10, 250 | max: 80, 251 | sectionCount: 4, 252 | sectionRadius: 6, 253 | sectionColor: Colors.red, 254 | hideBubble: false, 255 | alwaysShowBubble: true, 256 | bubbleRadius: 14, 257 | bubbleColor: Colors.purple, 258 | bubbleTextColor: Colors.white, 259 | bubbleTextSize: 14, 260 | bubbleMargin: 4, 261 | onValueChanged: (v) { 262 | print('当前进度:${v.progress} ,当前的取值:${v.value}'); 263 | })), 264 | Text( 265 | '80', 266 | textDirection: TextDirection.ltr, 267 | ) 268 | ], 269 | ), 270 | Text( 271 | "带间隔带气泡的指示器,气泡", 272 | textDirection: TextDirection.ltr, 273 | style: TextStyle(fontSize: 10), 274 | ) 275 | ], 276 | ), 277 | ), 278 | Padding( 279 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 280 | child: Column( 281 | children: [ 282 | Container( 283 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 284 | width: 200, 285 | child: SeekBar( 286 | progresseight: 10, 287 | value: 50, 288 | sectionCount: 4, 289 | sectionRadius: 5, 290 | sectionColor: Colors.red, 291 | sectionUnSelecteColor: Colors.red[100], 292 | showSectionText: true, 293 | sectionTextMarginTop: 2, 294 | sectionDecimal: 0, 295 | sectionTextColor: Colors.black, 296 | sectionSelectTextColor: Colors.red, 297 | sectionTextSize: 14, 298 | )), 299 | Text( 300 | "带带刻度的指示器,可设置刻度的样式和选中的刻度的样式", 301 | textDirection: TextDirection.ltr, 302 | style: TextStyle(fontSize: 10), 303 | ) 304 | ], 305 | ), 306 | ), 307 | Padding( 308 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 309 | child: Column( 310 | children: [ 311 | Container( 312 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 313 | width: 200, 314 | child: SeekBar( 315 | progresseight: 10, 316 | value: 50, 317 | sectionCount: 4, 318 | sectionRadius: 5, 319 | sectionColor: Colors.red, 320 | sectionUnSelecteColor: Colors.red[100], 321 | showSectionText: true, 322 | sectionTextMarginTop: 2, 323 | sectionDecimal: 0, 324 | sectionTextColor: Colors.black, 325 | sectionSelectTextColor: Colors.red, 326 | sectionTextSize: 14, 327 | hideBubble: false, 328 | bubbleRadius: 14, 329 | bubbleColor: Colors.purple, 330 | bubbleTextColor: Colors.white, 331 | bubbleTextSize: 14, 332 | bubbleMargin: 4, 333 | afterDragShowSectionText: true, 334 | )), 335 | Text( 336 | "带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 337 | textDirection: TextDirection.ltr, 338 | style: TextStyle(fontSize: 10), 339 | ) 340 | ], 341 | ), 342 | ), 343 | Padding( 344 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 345 | child: Column( 346 | children: [ 347 | Container( 348 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 349 | width: 200, 350 | child: SeekBar( 351 | min: -100, 352 | max: 200, 353 | progresseight: 10, 354 | value: 50, 355 | sectionCount: 4, 356 | sectionRadius: 6, 357 | showSectionText: true, 358 | sectionTexts: [], 359 | sectionTextMarginTop: 2, 360 | sectionDecimal: 0, 361 | sectionTextColor: Colors.black, 362 | sectionSelectTextColor: Colors.red, 363 | sectionTextSize: 14, 364 | hideBubble: false, 365 | bubbleRadius: 14, 366 | bubbleColor: Colors.purple, 367 | bubbleTextColor: Colors.white, 368 | bubbleTextSize: 14, 369 | bubbleMargin: 4, 370 | afterDragShowSectionText: true, 371 | )), 372 | Text( 373 | "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 374 | textDirection: TextDirection.ltr, 375 | style: TextStyle(fontSize: 10), 376 | ) 377 | ], 378 | ), 379 | ), 380 | Padding( 381 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 382 | child: Column( 383 | children: [ 384 | Container( 385 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 386 | width: 200, 387 | child: SeekBar( 388 | progresseight: 10, 389 | value: 75, 390 | sectionCount: 4, 391 | sectionRadius: 6, 392 | showSectionText: true, 393 | sectionTexts: sectionTexts, 394 | sectionTextMarginTop: 2, 395 | sectionDecimal: 0, 396 | sectionTextColor: Colors.black, 397 | sectionSelectTextColor: Colors.red, 398 | sectionTextSize: 14, 399 | hideBubble: false, 400 | bubbleRadius: 14, 401 | bubbleColor: Colors.purple, 402 | bubbleTextColor: Colors.white, 403 | bubbleTextSize: 14, 404 | bubbleMargin: 4, 405 | afterDragShowSectionText: true, 406 | )), 407 | Text( 408 | "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 409 | textDirection: TextDirection.ltr, 410 | style: TextStyle(fontSize: 10), 411 | ) 412 | ], 413 | ), 414 | ), 415 | ], 416 | )), 417 | ); 418 | 419 | } 420 | } 421 | 422 | ``` 423 | 424 | # License 425 | 426 | ``` 427 | Copyright 2018 LiucCheng 428 | 429 | Licensed under the Apache License, Version 2.0 (the "License"); 430 | you may not use this file except in compliance with the License. 431 | You may obtain a copy of the License at 432 | 433 | http://www.apache.org/licenses/LICENSE-2.0 434 | 435 | Unless required by applicable law or agreed to in writing, software 436 | distributed under the License is distributed on an "AS IS" BASIS, 437 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 438 | See the License for the specific language governing permissions and 439 | limitations under the License. 440 | ``` 441 | 442 | # contact me 443 | qq: 674668211 444 | wechat :674668211 加微信进flutter微信群 445 | 掘金: https://juejin.im/user/581206302f301e005c60cd2f 446 | 简书:https://www.jianshu.com/u/4a5dce56807b 447 | csdn:https://me.csdn.net/liu__520 448 | github : https://github.com/LiuC520/ -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.example.flutterseekbar' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.2.1' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 27 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_seekbar' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/com/example/flutterseekbar/FlutterSeekbarPlugin.java: -------------------------------------------------------------------------------- 1 | package com.example.flutterseekbar; 2 | 3 | import io.flutter.plugin.common.MethodCall; 4 | import io.flutter.plugin.common.MethodChannel; 5 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 6 | import io.flutter.plugin.common.MethodChannel.Result; 7 | import io.flutter.plugin.common.PluginRegistry.Registrar; 8 | 9 | /** FlutterSeekbarPlugin */ 10 | public class FlutterSeekbarPlugin implements MethodCallHandler { 11 | /** Plugin registration. */ 12 | public static void registerWith(Registrar registrar) { 13 | final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_seekbar"); 14 | channel.setMethodCallHandler(new FlutterSeekbarPlugin()); 15 | } 16 | 17 | @Override 18 | public void onMethodCall(MethodCall call, Result result) { 19 | if (call.method.equals("getPlatformVersion")) { 20 | result.success("Android " + android.os.Build.VERSION.RELEASE); 21 | } else { 22 | result.notImplemented(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: c5251cdc0257ad85db9ad8c2caf70d65c5979eee 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_seekbar_example 2 | 3 | Demonstrates how to use the flutter_seekbar plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.io/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 27 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.flutterseekbarexample" 37 | minSdkVersion 16 38 | targetSdkVersion 27 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/flutterseekbarexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.flutterseekbarexample; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 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-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | post_install do |installer| 64 | installer.pods_project.targets.each do |target| 65 | target.build_configurations.each do |config| 66 | config.build_settings['ENABLE_BITCODE'] = 'NO' 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXCopyFilesBuildPhase section */ 26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 27 | isa = PBXCopyFilesBuildPhase; 28 | buildActionMask = 2147483647; 29 | dstPath = ""; 30 | dstSubfolderSpec = 10; 31 | files = ( 32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 34 | ); 35 | name = "Embed Frameworks"; 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXCopyFilesBuildPhase section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 43 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | 9740EEB11CF90186004384FC /* Flutter */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, 77 | 3B80C3931E831B6300D905FE /* App.framework */, 78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 79 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 83 | ); 84 | name = Flutter; 85 | sourceTree = ""; 86 | }; 87 | 97C146E51CF9000F007C117D = { 88 | isa = PBXGroup; 89 | children = ( 90 | 9740EEB11CF90186004384FC /* Flutter */, 91 | 97C146F01CF9000F007C117D /* Runner */, 92 | 97C146EF1CF9000F007C117D /* Products */, 93 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, 94 | ); 95 | sourceTree = ""; 96 | }; 97 | 97C146EF1CF9000F007C117D /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 97C146EE1CF9000F007C117D /* Runner.app */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 97C146F01CF9000F007C117D /* Runner */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 109 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 110 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 111 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 112 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 113 | 97C147021CF9000F007C117D /* Info.plist */, 114 | 97C146F11CF9000F007C117D /* Supporting Files */, 115 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 116 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 117 | ); 118 | path = Runner; 119 | sourceTree = ""; 120 | }; 121 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 97C146F21CF9000F007C117D /* main.m */, 125 | ); 126 | name = "Supporting Files"; 127 | sourceTree = ""; 128 | }; 129 | /* End PBXGroup section */ 130 | 131 | /* Begin PBXNativeTarget section */ 132 | 97C146ED1CF9000F007C117D /* Runner */ = { 133 | isa = PBXNativeTarget; 134 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 135 | buildPhases = ( 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = Runner; 148 | productName = Runner; 149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | 97C146E61CF9000F007C117D /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | LastUpgradeCheck = 0910; 159 | ORGANIZATIONNAME = "The Chromium Authors"; 160 | TargetAttributes = { 161 | 97C146ED1CF9000F007C117D = { 162 | CreatedOnToolsVersion = 7.3.1; 163 | }; 164 | }; 165 | }; 166 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 167 | compatibilityVersion = "Xcode 3.2"; 168 | developmentRegion = English; 169 | hasScannedForEncodings = 0; 170 | knownRegions = ( 171 | en, 172 | Base, 173 | ); 174 | mainGroup = 97C146E51CF9000F007C117D; 175 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 176 | projectDirPath = ""; 177 | projectRoot = ""; 178 | targets = ( 179 | 97C146ED1CF9000F007C117D /* Runner */, 180 | ); 181 | }; 182 | /* End PBXProject section */ 183 | 184 | /* Begin PBXResourcesBuildPhase section */ 185 | 97C146EC1CF9000F007C117D /* Resources */ = { 186 | isa = PBXResourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 190 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 191 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 193 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputPaths = ( 207 | ); 208 | name = "Thin Binary"; 209 | outputPaths = ( 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | shellPath = /bin/sh; 213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 214 | }; 215 | 9740EEB61CF901F6004384FC /* Run Script */ = { 216 | isa = PBXShellScriptBuildPhase; 217 | buildActionMask = 2147483647; 218 | files = ( 219 | ); 220 | inputPaths = ( 221 | ); 222 | name = "Run Script"; 223 | outputPaths = ( 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | shellPath = /bin/sh; 227 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 228 | }; 229 | /* End PBXShellScriptBuildPhase section */ 230 | 231 | /* Begin PBXSourcesBuildPhase section */ 232 | 97C146EA1CF9000F007C117D /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 237 | 97C146F31CF9000F007C117D /* main.m in Sources */, 238 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXSourcesBuildPhase section */ 243 | 244 | /* Begin PBXVariantGroup section */ 245 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 97C146FB1CF9000F007C117D /* Base */, 249 | ); 250 | name = Main.storyboard; 251 | sourceTree = ""; 252 | }; 253 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 254 | isa = PBXVariantGroup; 255 | children = ( 256 | 97C147001CF9000F007C117D /* Base */, 257 | ); 258 | name = LaunchScreen.storyboard; 259 | sourceTree = ""; 260 | }; 261 | /* End PBXVariantGroup section */ 262 | 263 | /* Begin XCBuildConfiguration section */ 264 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 265 | isa = XCBuildConfiguration; 266 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 267 | buildSettings = { 268 | ALWAYS_SEARCH_USER_PATHS = NO; 269 | CLANG_ANALYZER_NONNULL = YES; 270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 271 | CLANG_CXX_LIBRARY = "libc++"; 272 | CLANG_ENABLE_MODULES = YES; 273 | CLANG_ENABLE_OBJC_ARC = YES; 274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 275 | CLANG_WARN_BOOL_CONVERSION = YES; 276 | CLANG_WARN_COMMA = YES; 277 | CLANG_WARN_CONSTANT_CONVERSION = YES; 278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN_ENUM_CONVERSION = YES; 281 | CLANG_WARN_INFINITE_RECURSION = YES; 282 | CLANG_WARN_INT_CONVERSION = YES; 283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 287 | CLANG_WARN_STRICT_PROTOTYPES = YES; 288 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 289 | CLANG_WARN_UNREACHABLE_CODE = YES; 290 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 291 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 292 | COPY_PHASE_STRIP = NO; 293 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 294 | ENABLE_NS_ASSERTIONS = NO; 295 | ENABLE_STRICT_OBJC_MSGSEND = YES; 296 | GCC_C_LANGUAGE_STANDARD = gnu99; 297 | GCC_NO_COMMON_BLOCKS = YES; 298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 300 | GCC_WARN_UNDECLARED_SELECTOR = YES; 301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 302 | GCC_WARN_UNUSED_FUNCTION = YES; 303 | GCC_WARN_UNUSED_VARIABLE = YES; 304 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 305 | MTL_ENABLE_DEBUG_INFO = NO; 306 | SDKROOT = iphoneos; 307 | TARGETED_DEVICE_FAMILY = "1,2"; 308 | VALIDATE_PRODUCT = YES; 309 | }; 310 | name = Profile; 311 | }; 312 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 313 | isa = XCBuildConfiguration; 314 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 315 | buildSettings = { 316 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 317 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 318 | DEVELOPMENT_TEAM = S8QB4VV633; 319 | ENABLE_BITCODE = NO; 320 | FRAMEWORK_SEARCH_PATHS = ( 321 | "$(inherited)", 322 | "$(PROJECT_DIR)/Flutter", 323 | ); 324 | INFOPLIST_FILE = Runner/Info.plist; 325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 326 | LIBRARY_SEARCH_PATHS = ( 327 | "$(inherited)", 328 | "$(PROJECT_DIR)/Flutter", 329 | ); 330 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSeekbarExample; 331 | PRODUCT_NAME = "$(TARGET_NAME)"; 332 | VERSIONING_SYSTEM = "apple-generic"; 333 | }; 334 | name = Profile; 335 | }; 336 | 97C147031CF9000F007C117D /* Debug */ = { 337 | isa = XCBuildConfiguration; 338 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 339 | buildSettings = { 340 | ALWAYS_SEARCH_USER_PATHS = NO; 341 | CLANG_ANALYZER_NONNULL = YES; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 347 | CLANG_WARN_BOOL_CONVERSION = YES; 348 | CLANG_WARN_COMMA = YES; 349 | CLANG_WARN_CONSTANT_CONVERSION = YES; 350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 351 | CLANG_WARN_EMPTY_BODY = YES; 352 | CLANG_WARN_ENUM_CONVERSION = YES; 353 | CLANG_WARN_INFINITE_RECURSION = YES; 354 | CLANG_WARN_INT_CONVERSION = YES; 355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 356 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 358 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 359 | CLANG_WARN_STRICT_PROTOTYPES = YES; 360 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 361 | CLANG_WARN_UNREACHABLE_CODE = YES; 362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 364 | COPY_PHASE_STRIP = NO; 365 | DEBUG_INFORMATION_FORMAT = dwarf; 366 | ENABLE_STRICT_OBJC_MSGSEND = YES; 367 | ENABLE_TESTABILITY = YES; 368 | GCC_C_LANGUAGE_STANDARD = gnu99; 369 | GCC_DYNAMIC_NO_PIC = NO; 370 | GCC_NO_COMMON_BLOCKS = YES; 371 | GCC_OPTIMIZATION_LEVEL = 0; 372 | GCC_PREPROCESSOR_DEFINITIONS = ( 373 | "DEBUG=1", 374 | "$(inherited)", 375 | ); 376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 378 | GCC_WARN_UNDECLARED_SELECTOR = YES; 379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 380 | GCC_WARN_UNUSED_FUNCTION = YES; 381 | GCC_WARN_UNUSED_VARIABLE = YES; 382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 383 | MTL_ENABLE_DEBUG_INFO = YES; 384 | ONLY_ACTIVE_ARCH = YES; 385 | SDKROOT = iphoneos; 386 | TARGETED_DEVICE_FAMILY = "1,2"; 387 | }; 388 | name = Debug; 389 | }; 390 | 97C147041CF9000F007C117D /* Release */ = { 391 | isa = XCBuildConfiguration; 392 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 393 | buildSettings = { 394 | ALWAYS_SEARCH_USER_PATHS = NO; 395 | CLANG_ANALYZER_NONNULL = YES; 396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 397 | CLANG_CXX_LIBRARY = "libc++"; 398 | CLANG_ENABLE_MODULES = YES; 399 | CLANG_ENABLE_OBJC_ARC = YES; 400 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 401 | CLANG_WARN_BOOL_CONVERSION = YES; 402 | CLANG_WARN_COMMA = YES; 403 | CLANG_WARN_CONSTANT_CONVERSION = YES; 404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 405 | CLANG_WARN_EMPTY_BODY = YES; 406 | CLANG_WARN_ENUM_CONVERSION = YES; 407 | CLANG_WARN_INFINITE_RECURSION = YES; 408 | CLANG_WARN_INT_CONVERSION = YES; 409 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 413 | CLANG_WARN_STRICT_PROTOTYPES = YES; 414 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 415 | CLANG_WARN_UNREACHABLE_CODE = YES; 416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 418 | COPY_PHASE_STRIP = NO; 419 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 420 | ENABLE_NS_ASSERTIONS = NO; 421 | ENABLE_STRICT_OBJC_MSGSEND = YES; 422 | GCC_C_LANGUAGE_STANDARD = gnu99; 423 | GCC_NO_COMMON_BLOCKS = YES; 424 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 425 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 426 | GCC_WARN_UNDECLARED_SELECTOR = YES; 427 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 428 | GCC_WARN_UNUSED_FUNCTION = YES; 429 | GCC_WARN_UNUSED_VARIABLE = YES; 430 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 431 | MTL_ENABLE_DEBUG_INFO = NO; 432 | SDKROOT = iphoneos; 433 | TARGETED_DEVICE_FAMILY = "1,2"; 434 | VALIDATE_PRODUCT = YES; 435 | }; 436 | name = Release; 437 | }; 438 | 97C147061CF9000F007C117D /* Debug */ = { 439 | isa = XCBuildConfiguration; 440 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 441 | buildSettings = { 442 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 443 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 444 | ENABLE_BITCODE = NO; 445 | FRAMEWORK_SEARCH_PATHS = ( 446 | "$(inherited)", 447 | "$(PROJECT_DIR)/Flutter", 448 | ); 449 | INFOPLIST_FILE = Runner/Info.plist; 450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 451 | LIBRARY_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSeekbarExample; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | VERSIONING_SYSTEM = "apple-generic"; 458 | }; 459 | name = Debug; 460 | }; 461 | 97C147071CF9000F007C117D /* Release */ = { 462 | isa = XCBuildConfiguration; 463 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 464 | buildSettings = { 465 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 466 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 467 | ENABLE_BITCODE = NO; 468 | FRAMEWORK_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "$(PROJECT_DIR)/Flutter", 471 | ); 472 | INFOPLIST_FILE = Runner/Info.plist; 473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 474 | LIBRARY_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "$(PROJECT_DIR)/Flutter", 477 | ); 478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSeekbarExample; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | VERSIONING_SYSTEM = "apple-generic"; 481 | }; 482 | name = Release; 483 | }; 484 | /* End XCBuildConfiguration section */ 485 | 486 | /* Begin XCConfigurationList section */ 487 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 488 | isa = XCConfigurationList; 489 | buildConfigurations = ( 490 | 97C147031CF9000F007C117D /* Debug */, 491 | 97C147041CF9000F007C117D /* Release */, 492 | 249021D3217E4FDB00AE95B9 /* Profile */, 493 | ); 494 | defaultConfigurationIsVisible = 0; 495 | defaultConfigurationName = Release; 496 | }; 497 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 498 | isa = XCConfigurationList; 499 | buildConfigurations = ( 500 | 97C147061CF9000F007C117D /* Debug */, 501 | 97C147071CF9000F007C117D /* Release */, 502 | 249021D4217E4FDB00AE95B9 /* Profile */, 503 | ); 504 | defaultConfigurationIsVisible = 0; 505 | defaultConfigurationName = Release; 506 | }; 507 | /* End XCConfigurationList section */ 508 | }; 509 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 510 | } 511 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_seekbar_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_seekbar/flutter_seekbar.dart' 4 | show SectionTextModel, SeekBar; 5 | 6 | void main() => runApp(Home()); 7 | 8 | class Home extends StatefulWidget { 9 | @override 10 | State createState() { 11 | return _HomeState(); 12 | } 13 | } 14 | 15 | class _HomeState extends State with SingleTickerProviderStateMixin { 16 | List sectionTexts = []; 17 | double v; 18 | @override 19 | void initState() { 20 | super.initState(); 21 | v = 80; 22 | sectionTexts.add( 23 | SectionTextModel(position: 0, text: 'bad', progressColor: Colors.red)); 24 | sectionTexts.add(SectionTextModel( 25 | position: 2, text: 'good', progressColor: Colors.yellow)); 26 | sectionTexts.add(SectionTextModel( 27 | position: 4, text: 'great', progressColor: Colors.green)); 28 | } 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return SingleChildScrollView( 33 | child: Container( 34 | padding: EdgeInsets.fromLTRB(0, 80, 0, 0), 35 | child: Column( 36 | children: [ 37 | Column( 38 | children: [ 39 | Container( 40 | width: 200, 41 | child: SeekBar( 42 | progresseight: 10, 43 | indicatorRadius: 0.0, 44 | value: v, 45 | isRound: false, 46 | progressColor: Colors.red, 47 | )), 48 | GestureDetector( 49 | onTap: () => { 50 | this.setState(() { 51 | v = 60; 52 | }) 53 | }, 54 | child: Container( 55 | margin: EdgeInsets.fromLTRB(0, 30, 0, 0), 56 | width: 50, 57 | height: 50, 58 | color: Colors.blue, 59 | child: Text( 60 | "直角", 61 | textDirection: TextDirection.ltr, 62 | maxLines: 1, 63 | style: TextStyle(fontSize: 10), 64 | ), 65 | )), 66 | ], 67 | ), 68 | Padding( 69 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 70 | child: Column( 71 | children: [ 72 | Container( 73 | width: 200, 74 | child: SeekBar( 75 | isCanTouch: false, 76 | indicatorRadius: 0.0, 77 | progresseight: 5, 78 | value: 50, 79 | hideBubble: false, 80 | alwaysShowBubble: true, 81 | bubbleRadius: 14, 82 | bubbleColor: Colors.purple, 83 | bubbleTextColor: Colors.white, 84 | bubbleTextSize: 14, 85 | bubbleMargin: 4, 86 | bubbleInCenter: true)), 87 | Text( 88 | "圆角,气泡居中,始终显示气泡", 89 | textDirection: TextDirection.ltr, 90 | maxLines: 1, 91 | style: TextStyle(fontSize: 10), 92 | ), 93 | ], 94 | ), 95 | ), 96 | Padding( 97 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 98 | child: Column( 99 | children: [ 100 | Container( 101 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 102 | width: 200, 103 | child: SeekBar( 104 | progresseight: 5, 105 | value: 20, 106 | )), 107 | Text( 108 | "圆角带指示器", 109 | textDirection: TextDirection.ltr, 110 | style: TextStyle(fontSize: 10), 111 | ), 112 | ], 113 | ), 114 | ), 115 | Padding( 116 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 117 | child: Column( 118 | children: [ 119 | Container( 120 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 121 | width: 200, 122 | child: SeekBar( 123 | progresseight: 5, 124 | value: 50, 125 | sectionCount: 5, 126 | )), 127 | Text( 128 | "带间隔带指示器", 129 | textDirection: TextDirection.ltr, 130 | style: TextStyle(fontSize: 10), 131 | ) 132 | ], 133 | ), 134 | ), 135 | Padding( 136 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 137 | child: Column( 138 | children: [ 139 | Container( 140 | padding: EdgeInsets.fromLTRB(0, 0, 0, 6), 141 | width: 200, 142 | child: SeekBar( 143 | progresseight: 5, 144 | value: 50, 145 | sectionCount: 4, 146 | sectionRadius: 6, 147 | sectionColor: Colors.red, 148 | )), 149 | Text( 150 | "带间隔画间隔的指示器", 151 | textDirection: TextDirection.ltr, 152 | style: TextStyle(fontSize: 10), 153 | ) 154 | ], 155 | ), 156 | ), 157 | Padding( 158 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 159 | child: Column( 160 | children: [ 161 | Row( 162 | crossAxisAlignment: CrossAxisAlignment.center, 163 | mainAxisSize: MainAxisSize.min, 164 | textDirection: TextDirection.ltr, 165 | children: [ 166 | Text( 167 | '-10', 168 | textDirection: TextDirection.ltr, 169 | ), 170 | Container( 171 | margin: EdgeInsets.fromLTRB(10, 0, 10, 4), 172 | width: 200, 173 | child: SeekBar( 174 | progresseight: 5, 175 | value: 58, 176 | min: -10, 177 | max: 80, 178 | sectionCount: 4, 179 | sectionRadius: 6, 180 | sectionColor: Colors.red, 181 | hideBubble: false, 182 | alwaysShowBubble: true, 183 | bubbleRadius: 14, 184 | bubbleColor: Colors.purple, 185 | bubbleTextColor: Colors.white, 186 | bubbleTextSize: 14, 187 | bubbleMargin: 4, 188 | onValueChanged: (v) { 189 | print('当前进度:${v.progress} ,当前的取值:${v.value}'); 190 | })), 191 | Text( 192 | '80', 193 | textDirection: TextDirection.ltr, 194 | ) 195 | ], 196 | ), 197 | Text( 198 | "带间隔带气泡的指示器,气泡", 199 | textDirection: TextDirection.ltr, 200 | style: TextStyle(fontSize: 10), 201 | ) 202 | ], 203 | ), 204 | ), 205 | Padding( 206 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 207 | child: Column( 208 | children: [ 209 | Container( 210 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 211 | width: 200, 212 | child: SeekBar( 213 | progresseight: 10, 214 | value: 50, 215 | sectionCount: 4, 216 | sectionRadius: 5, 217 | sectionColor: Colors.red, 218 | sectionUnSelecteColor: Colors.red[100], 219 | showSectionText: true, 220 | sectionTextMarginTop: 2, 221 | sectionDecimal: 0, 222 | sectionTextColor: Colors.black, 223 | sectionSelectTextColor: Colors.red, 224 | sectionTextSize: 14, 225 | )), 226 | Text( 227 | "带带刻度的指示器,可设置刻度的样式和选中的刻度的样式", 228 | textDirection: TextDirection.ltr, 229 | style: TextStyle(fontSize: 10), 230 | ) 231 | ], 232 | ), 233 | ), 234 | Padding( 235 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 236 | child: Column( 237 | children: [ 238 | Container( 239 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 240 | width: 200, 241 | child: SeekBar( 242 | progresseight: 10, 243 | value: 50, 244 | sectionCount: 4, 245 | sectionRadius: 5, 246 | sectionColor: Colors.red, 247 | sectionUnSelecteColor: Colors.red[100], 248 | showSectionText: true, 249 | sectionTextMarginTop: 2, 250 | sectionDecimal: 0, 251 | sectionTextColor: Colors.black, 252 | sectionSelectTextColor: Colors.red, 253 | sectionTextSize: 14, 254 | hideBubble: false, 255 | bubbleRadius: 14, 256 | bubbleColor: Colors.purple, 257 | bubbleTextColor: Colors.white, 258 | bubbleTextSize: 14, 259 | bubbleMargin: 4, 260 | afterDragShowSectionText: true, 261 | )), 262 | Text( 263 | "带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 264 | textDirection: TextDirection.ltr, 265 | style: TextStyle(fontSize: 10), 266 | ) 267 | ], 268 | ), 269 | ), 270 | Padding( 271 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 272 | child: Column( 273 | children: [ 274 | Container( 275 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 276 | width: 200, 277 | child: SeekBar( 278 | min: -100, 279 | max: 200, 280 | progresseight: 10, 281 | value: 50, 282 | sectionCount: 4, 283 | sectionRadius: 6, 284 | showSectionText: true, 285 | sectionTexts: [], 286 | sectionTextMarginTop: 2, 287 | sectionDecimal: 0, 288 | sectionTextColor: Colors.black, 289 | sectionSelectTextColor: Colors.red, 290 | sectionTextSize: 14, 291 | hideBubble: false, 292 | bubbleRadius: 14, 293 | bubbleColor: Colors.purple, 294 | bubbleTextColor: Colors.white, 295 | bubbleTextSize: 14, 296 | bubbleMargin: 4, 297 | afterDragShowSectionText: true, 298 | )), 299 | Text( 300 | "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 301 | textDirection: TextDirection.ltr, 302 | style: TextStyle(fontSize: 10), 303 | ) 304 | ], 305 | ), 306 | ), 307 | Padding( 308 | padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 309 | child: Column( 310 | children: [ 311 | Container( 312 | margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 313 | width: 200, 314 | child: SeekBar( 315 | progresseight: 10, 316 | value: 75, 317 | sectionCount: 4, 318 | sectionRadius: 6, 319 | showSectionText: true, 320 | sectionTexts: sectionTexts, 321 | sectionTextMarginTop: 2, 322 | sectionDecimal: 0, 323 | sectionTextColor: Colors.black, 324 | sectionSelectTextColor: Colors.red, 325 | sectionTextSize: 14, 326 | hideBubble: false, 327 | bubbleRadius: 14, 328 | bubbleColor: Colors.purple, 329 | bubbleTextColor: Colors.white, 330 | bubbleTextSize: 14, 331 | bubbleMargin: 4, 332 | afterDragShowSectionText: true, 333 | )), 334 | Text( 335 | "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 336 | textDirection: TextDirection.ltr, 337 | style: TextStyle(fontSize: 10), 338 | ) 339 | ], 340 | ), 341 | ), 342 | ], 343 | )), 344 | ); 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_seekbar_example 2 | description: Demonstrates how to use the flutter_seekbar plugin. 3 | publish_to: 'none' 4 | 5 | environment: 6 | sdk: ">=2.0.0-dev.68.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | 12 | # The following adds the Cupertino Icons font to your application. 13 | # Use with the CupertinoIcons class for iOS style icons. 14 | cupertino_icons: ^0.1.2 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | flutter_seekbar: 21 | path: ../ 22 | 23 | # For information on the generic Dart part of this file, see the 24 | # following page: https://www.dartlang.org/tools/pub/pubspec 25 | 26 | # The following section is specific to Flutter. 27 | flutter: 28 | 29 | # The following line ensures that the Material Icons font is 30 | # included with your application, so that you can use the icons in 31 | # the material Icons class. 32 | uses-material-design: true 33 | 34 | # To add assets to your application, add an assets section, like this: 35 | # assets: 36 | # - images/a_dot_burr.jpeg 37 | # - images/a_dot_ham.jpeg 38 | 39 | # An image asset can refer to one or more resolution-specific "variants", see 40 | # https://flutter.io/assets-and-images/#resolution-aware. 41 | 42 | # For details regarding adding assets from package dependencies, see 43 | # https://flutter.io/assets-and-images/#from-packages 44 | 45 | # To add custom fonts to your application, add a fonts section here, 46 | # in this "flutter" section. Each entry in this list should have a 47 | # "family" key with the font family name, and a "fonts" key with a 48 | # list giving the asset and other descriptors for the font. For 49 | # example: 50 | # fonts: 51 | # - family: Schyler 52 | # fonts: 53 | # - asset: fonts/Schyler-Regular.ttf 54 | # - asset: fonts/Schyler-Italic.ttf 55 | # style: italic 56 | # - family: Trajan Pro 57 | # fonts: 58 | # - asset: fonts/TrajanPro.ttf 59 | # - asset: fonts/TrajanPro_Bold.ttf 60 | # weight: 700 61 | # 62 | # For details regarding fonts from package dependencies, 63 | # see https://flutter.io/custom-fonts/#from-packages 64 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | // import 'package:flutter/material.dart'; 9 | // import 'package:flutter_test/flutter_test.dart'; 10 | 11 | // import 'package:flutter_seekbar_example/main.dart'; 12 | 13 | void main() { 14 | // testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // // Build our app and trigger a frame. 16 | // await tester.pumpWidget(Home()); 17 | 18 | // // // Verify that platform version is retrieved. 19 | // // expect( 20 | // // find.byWidgetPredicate( 21 | // // (Widget widget) => widget is Text && 22 | // // widget.data.startsWith('Running on:'), 23 | // // ), 24 | // // findsOneWidget, 25 | // // ); 26 | // }); 27 | } 28 | -------------------------------------------------------------------------------- /flutter_seekbar.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/FlutterSeekbarPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterSeekbarPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/FlutterSeekbarPlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterSeekbarPlugin.h" 2 | 3 | @implementation FlutterSeekbarPlugin 4 | + (void)registerWithRegistrar:(NSObject*)registrar { 5 | FlutterMethodChannel* channel = [FlutterMethodChannel 6 | methodChannelWithName:@"flutter_seekbar" 7 | binaryMessenger:[registrar messenger]]; 8 | FlutterSeekbarPlugin* instance = [[FlutterSeekbarPlugin alloc] init]; 9 | [registrar addMethodCallDelegate:instance channel:channel]; 10 | } 11 | 12 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 13 | if ([@"getPlatformVersion" isEqualToString:call.method]) { 14 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 15 | } else { 16 | result(FlutterMethodNotImplemented); 17 | } 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /ios/flutter_seekbar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'flutter_seekbar' 6 | s.version = '0.0.1' 7 | s.summary = 'A new flutter plugin project.' 8 | s.description = <<-DESC 9 | A new flutter plugin project. 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | 19 | s.ios.deployment_target = '8.0' 20 | end 21 | 22 | -------------------------------------------------------------------------------- /lib/flutter_seekbar.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 LiuCheng .All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | library flutterseekbar; 6 | 7 | export './seekbar/get_text_width.dart'; 8 | export './seekbar/progress_value.dart'; 9 | export './seekbar/section_text_model.dart'; 10 | export './seekbar/seekbar.dart'; 11 | -------------------------------------------------------------------------------- /lib/seekbar/get_text_width.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 LiuCheng .All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart' 6 | show TextPainter, TextSpan, TextStyle, TextDirection, Size, Color; 7 | import 'dart:ui' as ui; 8 | 9 | ///获取字体的宽高,放在size中 10 | Size getTextWidth({String text, double fontsize}) { 11 | //此���主要是拿到text的宽高,然后给个约束,同时把text准确的放到某个位置上 12 | final textPainter = TextPainter( 13 | textDirection: TextDirection.ltr, 14 | text: TextSpan( 15 | text: text, 16 | style: TextStyle(fontSize: fontsize), 17 | ), 18 | ); 19 | textPainter.layout(); 20 | return Size(textPainter.width, textPainter.height); 21 | } 22 | 23 | ///生成一个字体的形状,来画出来 24 | ui.Paragraph getParagraph( 25 | {String text, double fontsize, Color textColor, Size textSize}) { 26 | //此处��须用ui���������中的,否则会找不到相关的路径 27 | ui.TextStyle ts = ui.TextStyle(color: textColor, fontSize: fontsize); 28 | 29 | //下面的代码是画text 30 | ui.ParagraphBuilder paragraphBuilder = ui.ParagraphBuilder(ui.ParagraphStyle( 31 | textDirection: TextDirection.ltr, 32 | )) 33 | ..pushStyle(ts) 34 | ..addText(text); 35 | ui.Paragraph paragraph = paragraphBuilder.build() 36 | ..layout(ui.ParagraphConstraints(width: textSize.width)); 37 | return paragraph; 38 | } 39 | -------------------------------------------------------------------------------- /lib/seekbar/progress_value.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 LiuCheng .All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | ///回调的返回值 6 | /// SeekBar( 7 | /// progresseight: 5, 8 | /// value: 0.5, 9 | /// min: -10, 10 | /// max: 80, 11 | /// sectionCount: 4, 12 | /// sectionRadius: 6, 13 | /// sectionColor: Colors.red, 14 | /// hideBubble: false, 15 | /// alwaysShowBubble: true, 16 | /// bubbleRadius: 14, 17 | /// bubbleColor: Colors.purple, 18 | /// bubbleTextColor: Colors.white, 19 | /// bubbleTextSize: 14, 20 | /// bubbleMargin: 4, 21 | /// onValueChanged: (v) { 22 | /// print( 23 | /// '当前进度:${v.progress} ,当前的取值:${v.value}'); 24 | /// }) 25 | class ProgressValue { 26 | /// 进度,如0.10,从0-1 27 | final double progress; 28 | 29 | /// 真实的值,给定最小和最大值,否则返回的是宽度的值 30 | final double value; 31 | 32 | const ProgressValue({this.value = 0.0, this.progress = 0.0}); 33 | 34 | @override 35 | String toString() { 36 | return 'ProgressValue{progress: $progress, value: $value}'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/seekbar/section_text_model.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 LiuCheng .All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart' show Color, Colors; 6 | 7 | ///要显示的刻度值 8 | ///如果要自定义刻度值,数组中需要包含这个实体类 9 | /// List sectionTexts = []; 10 | /// sectionTexts.add(SectionTextModel(position: 0, text: 'bad', progressColor: Colors.red)); 11 | /// sectionTexts.add(SectionTextModel(position: 2, text: 'good', progressColor: Colors.yellow)); 12 | /// sectionTexts.add(SectionTextModel( position: 4, text: 'great', progressColor: Colors.green)); 13 | /// Padding( 14 | /// padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 15 | /// child: Column( 16 | /// children: [ 17 | /// Container( 18 | /// margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 19 | /// width: 200, 20 | /// child: SeekBar( 21 | /// progresseight: 10, 22 | /// value: 0.75, 23 | /// sectionCount: 4, 24 | /// sectionRadius: 6, 25 | /// showSectionText: true, 26 | /// sectionTexts: sectionTexts, 27 | /// sectionTextMarginTop: 2, 28 | /// sectionDecimal: 0, 29 | /// sectionTextColor: Colors.black, 30 | /// sectionSelectTextColor: Colors.red, 31 | /// sectionTextSize: 14, 32 | /// hideBubble: false, 33 | /// bubbleRadius: 14, 34 | /// bubbleColor: Colors.purple, 35 | /// bubbleTextColor: Colors.white, 36 | /// bubbleTextSize: 14, 37 | /// bubbleMargin: 4, 38 | /// afterDragShowSectionText: true, 39 | /// )), 40 | /// Text( 41 | /// "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 42 | /// style: TextStyle(fontSize: 10), 43 | /// ) 44 | /// ], 45 | /// ), 46 | /// ), 47 | /// 48 | 49 | class SectionTextModel { 50 | /// 文字要显示的位置,from 0,从0开始 51 | final int position; 52 | 53 | /// 要显示的文字 54 | final String text; 55 | 56 | /// 进度条的这个值之前的颜色 57 | final Color progressColor; 58 | 59 | const SectionTextModel( 60 | {this.position = -1, 61 | this.text = '', 62 | this.progressColor = Colors.transparent}); 63 | 64 | @override 65 | String toString() { 66 | return 'SectionTextModel{position:$position, text: $text, progressColor: $progressColor}'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/seekbar/seekbar.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 LiuCheng .All rights reserved. 2 | // Use of this source code is governed by a Apache license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:math' as math; 6 | import 'dart:ui' as ui; 7 | import 'package:flutter/foundation.dart'; 8 | import 'package:flutter/widgets.dart'; 9 | import 'package:flutter/material.dart'; 10 | import './progress_value.dart'; 11 | import './get_text_width.dart'; 12 | import './section_text_model.dart'; 13 | 14 | ///要显示的刻度值 15 | ///如果要自定义刻度值,数组中需要包含这个实体类 16 | /// List sectionTexts = []; 17 | /// sectionTexts.add(SectionTextModel(position: 0, text: 'bad', progressColor: Colors.red)); 18 | /// sectionTexts.add(SectionTextModel(position: 2, text: 'good', progressColor: Colors.yellow)); 19 | /// sectionTexts.add(SectionTextModel( position: 4, text: 'great', progressColor: Colors.green)); 20 | /// Padding( 21 | /// padding: EdgeInsets.fromLTRB(0, 40, 0, 0), 22 | /// child: Column( 23 | /// children: [ 24 | /// Container( 25 | /// margin: EdgeInsets.fromLTRB(0, 0, 0, 40), 26 | /// width: 200, 27 | /// child: SeekBar( 28 | /// progresseight: 10, 29 | /// value: 75, 30 | /// sectionCount: 4, 31 | /// sectionRadius: 6, 32 | /// showSectionText: true, 33 | /// sectionTexts: sectionTexts, 34 | /// sectionTextMarginTop: 2, 35 | /// sectionDecimal: 0, 36 | /// sectionTextColor: Colors.black, 37 | /// sectionSelectTextColor: Colors.red, 38 | /// sectionTextSize: 14, 39 | /// hideBubble: false, 40 | /// bubbleRadius: 14, 41 | /// bubbleColor: Colors.purple, 42 | /// bubbleTextColor: Colors.white, 43 | /// bubbleTextSize: 14, 44 | /// bubbleMargin: 4, 45 | /// afterDragShowSectionText: true, 46 | /// )), 47 | /// Text( 48 | /// "自定义刻度值显示,带带刻度的指示器,可设置刻度的样式和选中的刻度的样式,拖拽结束显示刻度值,拖拽开始显示气泡", 49 | /// style: TextStyle(fontSize: 10), 50 | /// ) 51 | /// ], 52 | /// ), 53 | /// ), 54 | /// 55 | 56 | abstract class BasicSeekbar extends StatefulWidget { 57 | ///最小值 58 | final double min; 59 | 60 | ///最大值 61 | final double max; 62 | 63 | ///进度值 64 | final double value; 65 | 66 | /// 高度 67 | final double progresseight; 68 | 69 | /// 总共分几份 70 | final int sectionCount; 71 | 72 | ///间隔圆圈的颜色 73 | final Color sectionColor; 74 | 75 | ///间隔圆圈未选中的颜色 76 | final Color sectionUnSelecteColor; 77 | 78 | ///间隔圆圈的半径 79 | final double sectionRadius; 80 | 81 | ///显示间隔刻度值与否,默认是不显示 82 | final bool showSectionText; 83 | 84 | /// 刻度值的数组 85 | final List sectionTexts; 86 | 87 | ///刻度值的字体大小 88 | final double sectionTextSize; 89 | 90 | /// 是否在拖拽结束显示值 91 | final bool afterDragShowSectionText; 92 | 93 | ///刻度值的字体颜色 94 | final Color sectionTextColor; 95 | 96 | ///刻度值的字体颜色 97 | final Color sectionSelectTextColor; 98 | 99 | ///刻度值的小数点的位数,默认是0位 100 | final int sectionDecimal; 101 | 102 | ///刻度值距离进度条的间距 103 | final double sectionTextMarginTop; 104 | 105 | /// 指示器的半径 106 | final double indicatorRadius; 107 | 108 | ///指示器的颜色 109 | final Color indicatorColor; 110 | 111 | ///进度条背景的颜色 112 | final Color backgroundColor; 113 | 114 | /// 进度条当前进度的颜色 115 | final Color progressColor; 116 | 117 | ///这个是给盲人用的,屏幕阅读器的要读出来的标签 118 | final String semanticsLabel; 119 | 120 | ///这个是给盲人用的,屏幕阅读器的要读出的进度条的值 121 | final String semanticsValue; 122 | 123 | ///进度改变的回调 124 | final ValueChanged onValueChanged; 125 | // final void Function(double) onValueChanged; 126 | 127 | ///进度条是否是圆角的,还是方形的,默认是圆角的 128 | final bool isRound; 129 | 130 | const BasicSeekbar( 131 | {Key key, 132 | this.min, 133 | this.max, 134 | this.value, 135 | this.progresseight, 136 | this.sectionCount, 137 | this.sectionColor, 138 | this.sectionUnSelecteColor, 139 | this.sectionRadius, 140 | this.showSectionText, 141 | this.sectionTexts, 142 | this.sectionTextSize, 143 | this.afterDragShowSectionText, 144 | this.sectionTextColor, 145 | this.sectionSelectTextColor, 146 | this.sectionDecimal, 147 | this.sectionTextMarginTop, 148 | this.backgroundColor, 149 | this.progressColor, 150 | this.semanticsLabel, 151 | this.semanticsValue, 152 | this.indicatorRadius, 153 | this.indicatorColor, 154 | this.onValueChanged, 155 | this.isRound}) 156 | : super(key: key); 157 | 158 | Color _getBackgroundColor(BuildContext context) => 159 | backgroundColor ?? Theme.of(context).backgroundColor; 160 | Color _getProgressColor(BuildContext context) => 161 | progressColor ?? Theme.of(context).accentColor; 162 | 163 | Widget _buildSemanticsWrapper({ 164 | @required BuildContext context, 165 | @required Widget child, 166 | }) { 167 | String expandedSemanticsValue = semanticsValue; 168 | if (value != null) { 169 | expandedSemanticsValue ??= '${(value * 100).round()}%'; 170 | } 171 | return Semantics( 172 | label: semanticsLabel, 173 | value: expandedSemanticsValue, 174 | child: child, 175 | ); 176 | } 177 | 178 | @override 179 | void debugFillProperties(DiagnosticPropertiesBuilder properties) { 180 | super.debugFillProperties(properties); 181 | properties.add(PercentProperty('value', value, 182 | showName: false, ifNull: '')); 183 | } 184 | } 185 | 186 | @immutable 187 | class _SeekBarPainter extends CustomPainter { 188 | ///背景颜色 189 | final Color backgroundColor; 190 | 191 | ///进度条的颜色 192 | final Color progressColor; 193 | 194 | ///进度值 195 | final double value; 196 | 197 | ///最大值 198 | final double min; 199 | 200 | ///最小值 201 | final double max; 202 | 203 | ///指示器的半径,进度条右侧的原点 204 | double indicatorRadius; 205 | 206 | ///最外层的圆角 207 | double radius; 208 | 209 | ///间隔数量 210 | int sectionCount; 211 | 212 | ///间隔圆圈的颜色 213 | Color sectionColor; 214 | 215 | ///间隔圆圈未选中的颜色 216 | final Color sectionUnSelecteColor; 217 | 218 | ///间隔圆圈的半径 219 | double sectionRadius; 220 | 221 | ///显示间隔刻度值与否,默认是不显示 222 | final bool showSectionText; 223 | 224 | /// 刻度值的数组 225 | final List sectionTexts; 226 | 227 | ///刻度值的字体大小 228 | final double sectionTextSize; 229 | final bool afterDragShowSectionText; 230 | 231 | ///刻度值的字体颜色 232 | final Color sectionTextColor; 233 | 234 | ///刻度值的字体颜色 235 | final Color sectionSelectTextColor; 236 | 237 | ///刻度值的小数点的位数,默认是0位 238 | final int sectionDecimal; 239 | 240 | ///刻度值距离进度条的间距 241 | final double sectionTextMarginTop; 242 | 243 | ///进度条的高度 244 | double progresseight; 245 | 246 | ///指示器的颜色 247 | Color indicatorColor; 248 | 249 | ///气泡隐藏与否,默认是true,隐藏 250 | bool hideBubble; 251 | 252 | ///是否是一直显示气泡,默认是false, 253 | bool alwaysShowBubble; 254 | 255 | ///气泡的半径 256 | double bubbleRadius; 257 | 258 | ///气泡的总高度 259 | double bubbleHeight; 260 | 261 | /// 气泡背景颜色 262 | Color bubbleColor; 263 | 264 | /// 气泡中文字的颜色 265 | Color bubbleTextColor; 266 | 267 | /// 气泡中文字的大小 268 | double bubbleTextSize; 269 | 270 | /// 气泡距离底部的高度 271 | double bubbleMargin; 272 | 273 | /// 气泡在进度条的中间显示,而不是在进度条的上方展示,默认是false,在上方显示 274 | bool bubbleInCenter; 275 | _SeekBarPainter( 276 | {this.backgroundColor, 277 | this.progressColor, 278 | this.value, 279 | this.min, 280 | this.max, 281 | this.indicatorRadius, 282 | this.indicatorColor, 283 | this.radius, 284 | this.sectionCount, 285 | this.sectionColor, 286 | this.sectionUnSelecteColor, 287 | this.sectionRadius, 288 | this.showSectionText, 289 | this.sectionTexts, 290 | this.sectionTextSize, 291 | this.afterDragShowSectionText, 292 | this.sectionTextColor, 293 | this.sectionSelectTextColor, 294 | this.sectionDecimal, 295 | this.sectionTextMarginTop, 296 | this.progresseight, 297 | this.hideBubble, 298 | this.alwaysShowBubble, 299 | this.bubbleRadius, 300 | this.bubbleHeight, 301 | this.bubbleColor, 302 | this.bubbleTextColor, 303 | this.bubbleTextSize, 304 | this.bubbleMargin, 305 | this.bubbleInCenter}); 306 | 307 | // 画path 308 | Path drawPath(double progresseight, double x, double totalHeight, double r) { 309 | Path path = new Path(); 310 | //如果间隔存在,而且半径大于0,而且如果进度条的高度大于间隔的直径,半径就取高度的,否则进度条会变形 311 | double R = r; 312 | if (sectionCount > 1 && sectionRadius > 0.0) { 313 | if (progresseight > r * 2) { 314 | R = progresseight; 315 | } else { 316 | R = 0.0; 317 | } 318 | } 319 | double startY = 0.0; 320 | double endY = progresseight; 321 | startY = (-progresseight + totalHeight) / 2; 322 | endY = (progresseight + totalHeight) / 2; 323 | // if (progresseight <= indicatorRadius) { 324 | // startY = indicatorRadius - progresseight / 2; 325 | // endY = indicatorRadius + progresseight / 2; 326 | // } 327 | if (r == null || r == 0.0) { 328 | path 329 | ..moveTo(0.0, startY) 330 | ..lineTo(x, startY) 331 | ..lineTo(x, endY) 332 | ..lineTo(0.0, endY); 333 | } else { 334 | path 335 | ..moveTo(R, startY) 336 | ..lineTo(x - R, startY) 337 | ..arcToPoint(Offset(x - R, endY), 338 | radius: Radius.circular(R), clockwise: true, largeArc: false) 339 | ..lineTo(R, endY) 340 | ..arcToPoint(Offset(R, startY), 341 | radius: Radius.circular(R), clockwise: true, largeArc: true); 342 | } 343 | path..close(); 344 | return path; 345 | } 346 | 347 | @override 348 | void paint(Canvas canvas, Size size) { 349 | final Paint paint = Paint() 350 | ..color = backgroundColor 351 | ..style = PaintingStyle.fill; 352 | 353 | ///1、画刻度值 354 | void drawSectionText() { 355 | if (!showSectionText) return; 356 | double yPosition = sectionTextMarginTop; //sectionTextMarginTop 357 | if (progresseight > 2 * indicatorRadius) { 358 | yPosition += (progresseight + size.height) / 2; 359 | } else { 360 | yPosition += indicatorRadius + size.height / 2; 361 | } 362 | double e = (max - min) / sectionCount; 363 | 364 | for (var i = 0; i < sectionCount + 1; i++) { 365 | String point = (e * i + min).toStringAsFixed(sectionDecimal); 366 | 367 | if (sectionTexts.length > 0) { 368 | Iterable match = sectionTexts.where((item) { 369 | return item.position == i; 370 | }); 371 | 372 | if (match.length > 0) { 373 | SectionTextModel matchModel = match.first; 374 | point = matchModel.text; 375 | } else if (i == value * sectionCount && 376 | afterDragShowSectionText != null && 377 | afterDragShowSectionText) { 378 | } else { 379 | point = ''; 380 | } 381 | } 382 | 383 | Size textSize = getTextWidth(text: point, fontsize: sectionTextSize); 384 | Color textColor = sectionTextColor; 385 | if (sectionSelectTextColor != Colors.transparent && 386 | i == value * sectionCount) { 387 | textColor = sectionSelectTextColor; 388 | } 389 | //为了计算文字和size的偏差 390 | double th = 0; 391 | if (textSize.height > size.height) { 392 | th = -(textSize.height - size.height) / 2; 393 | } 394 | canvas.drawParagraph( 395 | getParagraph( 396 | text: point, 397 | fontsize: sectionTextSize, 398 | textColor: textColor, 399 | textSize: textSize), 400 | Offset(i * size.width / sectionCount - textSize.width / 2, 401 | yPosition + th)); 402 | } 403 | } 404 | 405 | canvas.drawPath( 406 | drawPath(progresseight, size.width, size.height, radius), paint); //画背景 407 | //下面是画矩形 408 | // Size newSize = new Size(size.width - indicatorRadius, size.height); 409 | // canvas.drawRect(Offset.zero & newSize, paint); 410 | 411 | paint.color = progressColor; 412 | 413 | // 画进度条 414 | void drawBar(double x, double progress) { 415 | if (x <= 0.0) return; 416 | //如果是分段,而且有自定义的刻度值 417 | if (sectionCount > 1 && sectionTexts.length > 1) { 418 | sectionTexts.forEach((item) { 419 | if (progress * sectionCount >= item.position) { 420 | if (item.progressColor != null) { 421 | paint.color = indicatorColor = sectionColor = item.progressColor; 422 | } 423 | } 424 | }); 425 | } 426 | 427 | canvas.drawPath(drawPath(progresseight, x, size.height, radius), paint); 428 | // canvas.drawRect(Offset(x, 0.0) & Size(width, size.height), paint); 429 | } 430 | 431 | //画间隔 432 | void drawInterval() { 433 | if (sectionCount <= 1) return; 434 | for (var i = 0; i < sectionCount + 1; i++) { 435 | paint.color = 436 | i > value * sectionCount ? sectionUnSelecteColor : sectionColor; 437 | 438 | canvas.drawCircle( 439 | Offset(i * size.width / sectionCount, size.height / 2), 440 | sectionRadius, 441 | paint); 442 | } 443 | } 444 | 445 | // 画当前显示的值的指示器 446 | void drawIndicator() { 447 | if (indicatorRadius <= 0.0) return; 448 | if (indicatorColor == null) { 449 | indicatorColor = progressColor; 450 | } 451 | Paint indicatorPaint = new Paint() 452 | ..style = PaintingStyle.fill 453 | ..color = indicatorColor; 454 | canvas.drawCircle(Offset(value * size.width, size.height / 2), 455 | indicatorRadius, indicatorPaint); 456 | } 457 | 458 | //画顶部的指示器 459 | void drawTopBubble() { 460 | if (hideBubble || !alwaysShowBubble) return; 461 | paint.color = bubbleColor; 462 | double bubbleInCenterY = 0.0; 463 | double newBubbleHeight; 464 | if (bubbleInCenter) { 465 | bubbleMargin = 0.0; 466 | bubbleInCenterY = bubbleHeight - bubbleRadius; 467 | newBubbleHeight = bubbleHeight; 468 | } else { 469 | bubbleInCenterY = indicatorRadius - size.height / 2 + bubbleMargin; 470 | newBubbleHeight = bubbleHeight + bubbleInCenterY; 471 | } 472 | //计算bubble的坐标值,画出bubble, 473 | double x = bubbleRadius / 474 | (newBubbleHeight - bubbleRadius) * 475 | math.sqrt((math.pow(newBubbleHeight - bubbleRadius, 2) - 476 | math.pow(bubbleRadius, 2))); 477 | double y = math.sqrt(math.pow(bubbleRadius, 2) - x * x); 478 | Path bubblePath = new Path() 479 | ..moveTo(value * size.width, 480 | bubbleInCenter ? bubbleInCenterY : -bubbleInCenterY) 481 | ..lineTo( 482 | value * size.width + x, 483 | bubbleInCenter 484 | ? -newBubbleHeight + bubbleRadius + y + bubbleInCenterY 485 | : -newBubbleHeight + bubbleRadius + y) 486 | ..arcToPoint( 487 | Offset( 488 | value * size.width - x, 489 | bubbleInCenter 490 | ? -newBubbleHeight + bubbleRadius + y + bubbleInCenterY 491 | : -newBubbleHeight + bubbleRadius + y), 492 | radius: Radius.circular(bubbleRadius), 493 | clockwise: false, 494 | largeArc: true) 495 | ..close(); 496 | canvas.drawPath(bubblePath, paint); 497 | 498 | double realValue = (max - min) * value + min; 499 | int rv = realValue.ceil(); 500 | String text = '$rv'; 501 | double fontsize = bubbleTextSize; 502 | 503 | //此���主要是拿到text的宽高,然后给个约束,同时把text准确的放到某个位置上 504 | Size textSize = getTextWidth(text: text, fontsize: fontsize); 505 | 506 | canvas.drawParagraph( 507 | getParagraph( 508 | text: text, 509 | fontsize: fontsize, 510 | textColor: bubbleTextColor, 511 | textSize: textSize), 512 | Offset( 513 | value * size.width - textSize.width / 2, 514 | bubbleInCenter 515 | ? -newBubbleHeight + 516 | bubbleRadius - 517 | textSize.height / 2 + 518 | bubbleInCenterY 519 | : -newBubbleHeight + bubbleRadius - textSize.height / 2)); 520 | } 521 | 522 | drawSectionText(); // draw section text 画刻度值 523 | 524 | drawBar(value.clamp(0.0, 1.0) * size.width, value); //画进度 525 | drawInterval(); //画间隔 526 | 527 | drawIndicator(); //draw indicator 528 | drawTopBubble(); //draw top bubble 529 | } 530 | 531 | @override 532 | bool shouldRepaint(_SeekBarPainter oldPainter) { 533 | return oldPainter != this; 534 | } 535 | } 536 | 537 | @immutable 538 | class SeekBar extends BasicSeekbar { 539 | ///显示气泡 ,默认是隐藏的,true 540 | bool hideBubble; 541 | 542 | ///是否是一直显示气泡,默认是false, 543 | bool alwaysShowBubble; 544 | 545 | ///气泡半径 546 | double bubbleRadius; 547 | 548 | ///气泡总高度,包含气泡半径 549 | double bubbleHeight; 550 | 551 | /// 气泡背景颜色 552 | Color bubbleColor; 553 | 554 | /// 气泡中文字的颜色 555 | Color bubbleTextColor; 556 | 557 | /// 气泡中文字的大小 558 | double bubbleTextSize; 559 | 560 | /// 气泡距离底部的高度 561 | double bubbleMargin; 562 | bool bubbleInCenter; 563 | 564 | /// 是否可以触摸响应触摸事件 565 | bool isCanTouch; 566 | SeekBar({ 567 | Key key, 568 | ValueChanged onValueChanged, 569 | double min = 0.0, 570 | double max = 100.0, 571 | double progresseight, 572 | double value = 0.0, 573 | Color backgroundColor, 574 | Color progressColor, 575 | String semanticsLabel, 576 | String semanticsValue, 577 | double indicatorRadius, 578 | Color indicatorColor, 579 | int sectionCount, 580 | Color sectionColor, 581 | 582 | ///间隔圆圈未选中的颜色 583 | final Color sectionUnSelecteColor, 584 | double sectionRadius, 585 | bool showSectionText, 586 | 587 | /// 刻度值的数组 588 | final List sectionTexts, 589 | 590 | ///刻度值的字体大小 591 | final double sectionTextSize = 14.0, 592 | bool afterDragShowSectionText, 593 | 594 | ///刻度值的字体颜色 595 | final Color sectionTextColor, 596 | 597 | ///刻度值的字体颜色 598 | final Color sectionSelectTextColor, 599 | 600 | ///刻度值的小数点的位数,默认是0位 601 | final int sectionDecimal = 0, 602 | 603 | ///刻度值距离进度条的间距 604 | final double sectionTextMarginTop = 4.0, 605 | bool isRound = true, 606 | bool hideBubble, 607 | double bubbleRadius, 608 | this.bubbleHeight, 609 | this.bubbleColor, 610 | this.bubbleTextColor = Colors.white, 611 | this.bubbleTextSize = 14.0, 612 | this.bubbleMargin = 4.0, 613 | this.bubbleInCenter = false, 614 | this.alwaysShowBubble, 615 | this.isCanTouch = true, 616 | }) : this.hideBubble = hideBubble ?? true, 617 | this.bubbleRadius = bubbleRadius ?? 20, 618 | super( 619 | key: key, 620 | onValueChanged: onValueChanged, 621 | min: min, 622 | max: max, 623 | progresseight: progresseight, 624 | value: value, 625 | backgroundColor: backgroundColor, 626 | progressColor: progressColor, 627 | semanticsLabel: semanticsLabel, 628 | semanticsValue: semanticsValue, 629 | indicatorRadius: indicatorRadius, 630 | indicatorColor: indicatorColor, 631 | isRound: isRound, 632 | sectionCount: sectionCount, 633 | sectionColor: sectionColor, 634 | sectionUnSelecteColor: sectionUnSelecteColor, 635 | sectionRadius: sectionRadius, 636 | showSectionText: showSectionText, 637 | sectionTexts: sectionTexts, 638 | sectionTextSize: sectionTextSize, 639 | afterDragShowSectionText: afterDragShowSectionText, 640 | sectionTextColor: sectionTextColor, 641 | sectionSelectTextColor: sectionSelectTextColor, 642 | sectionDecimal: sectionDecimal, 643 | sectionTextMarginTop: sectionTextMarginTop, 644 | ); 645 | 646 | @override 647 | _SeekBarState createState() => _SeekBarState(); 648 | } 649 | 650 | class _SeekBarState extends State { 651 | ///进度值 652 | double _value; 653 | bool _afterDragShowSectionText; 654 | 655 | ///高度 656 | double progresseight; 657 | 658 | ///��高度 659 | double totalHeight; 660 | 661 | ///中间的指示器的圆角 662 | double indicatorRadius; 663 | 664 | ///左右两侧的圆角 665 | bool isRound; 666 | 667 | ///间����� 668 | int sectionCount; 669 | 670 | ///间隔圆圈的颜色 671 | Color sectionColor; 672 | 673 | ///间隔圆圈未选中的颜色 674 | Color sectionUnSelecteColor; 675 | 676 | ///间隔圆圈的半径 677 | double sectionRadius; 678 | 679 | ///气泡的总高度 680 | double bubbleHeight; 681 | bool _alwaysShowBubble; 682 | 683 | double length; 684 | double e; 685 | double start; 686 | double end; 687 | Offset touchPoint = Offset.zero; 688 | ProgressValue v; 689 | 690 | @override 691 | void initState() { 692 | super.initState(); 693 | _value = (widget.value - widget.min) / (widget.max - widget.min); 694 | progresseight = widget.progresseight ?? 5.0; 695 | indicatorRadius = widget.indicatorRadius ?? progresseight + 2; 696 | sectionCount = widget.sectionCount ?? 1; 697 | sectionRadius = widget.sectionRadius ?? 0.0; 698 | bubbleHeight = widget.bubbleHeight ?? widget.bubbleRadius * 3; 699 | _alwaysShowBubble = widget.alwaysShowBubble ?? false; 700 | _afterDragShowSectionText = false; 701 | if (sectionCount > 1) { 702 | e = 1 / sectionCount; //每一份的值 703 | start = 0.0; 704 | end = 0.0; 705 | } 706 | 707 | if (indicatorRadius >= progresseight) { 708 | totalHeight = indicatorRadius * 2; 709 | } else { 710 | totalHeight = progresseight; 711 | } 712 | length = (widget.max - widget.min); //总���小 713 | } 714 | 715 | Widget _buildSeekBar( 716 | BuildContext context, double value, double min, double max) { 717 | return widget._buildSemanticsWrapper( 718 | context: context, 719 | child: Container( 720 | // height: totalHeight, 721 | //下面的可以设置约束 722 | constraints: const BoxConstraints( 723 | minWidth: double.infinity, 724 | minHeight: 10, 725 | ), 726 | child: CustomPaint( 727 | painter: _SeekBarPainter( 728 | backgroundColor: widget._getBackgroundColor(context), 729 | progressColor: widget._getProgressColor(context), 730 | value: value, 731 | min: min, 732 | max: max, 733 | indicatorRadius: indicatorRadius, 734 | progresseight: progresseight, 735 | radius: widget.isRound ? progresseight / 2 : 0.0, 736 | indicatorColor: 737 | widget.indicatorColor ?? widget._getProgressColor(context), 738 | sectionCount: sectionCount, 739 | sectionColor: 740 | widget.sectionColor ?? widget._getProgressColor(context), 741 | sectionUnSelecteColor: widget.sectionUnSelecteColor ?? 742 | widget._getBackgroundColor(context), 743 | sectionRadius: sectionRadius, 744 | showSectionText: widget.showSectionText ?? false, 745 | sectionTexts: widget.sectionTexts ?? [], 746 | sectionTextSize: widget.sectionTextSize, 747 | afterDragShowSectionText: _afterDragShowSectionText, 748 | sectionTextColor: 749 | widget.sectionTextColor ?? widget._getProgressColor(context), 750 | sectionSelectTextColor: 751 | widget.sectionSelectTextColor ?? Colors.transparent, 752 | sectionDecimal: widget.sectionDecimal, 753 | sectionTextMarginTop: widget.sectionTextMarginTop, 754 | hideBubble: widget.hideBubble, 755 | alwaysShowBubble: _alwaysShowBubble, 756 | bubbleRadius: widget.bubbleRadius, 757 | bubbleHeight: bubbleHeight, 758 | bubbleColor: 759 | widget.bubbleColor ?? widget._getProgressColor(context), 760 | bubbleTextColor: widget.bubbleTextColor, 761 | bubbleTextSize: widget.bubbleTextSize, 762 | bubbleMargin: widget.bubbleMargin, 763 | bubbleInCenter: widget.bubbleInCenter, 764 | ), 765 | ), 766 | ), 767 | ); 768 | } 769 | 770 | // Updates height and value when user taps on the SeekBar. 771 | void _onTapUp(TapUpDetails tapDetails) { 772 | RenderBox renderBox = context.findRenderObject(); 773 | setState(() { 774 | touchPoint = new Offset( 775 | renderBox.globalToLocal(tapDetails.globalPosition).dx, 0.0); 776 | _value = touchPoint.dx / context.size.width; 777 | _setValue(); 778 | if (widget.alwaysShowBubble != null && widget.alwaysShowBubble 779 | ? false 780 | : true) { 781 | _alwaysShowBubble = false; 782 | } 783 | if (widget.afterDragShowSectionText ?? false) { 784 | _afterDragShowSectionText = true; 785 | } 786 | }); 787 | } 788 | 789 | void _onPanDown(DragDownDetails details) { 790 | RenderBox box = context.findRenderObject(); 791 | touchPoint = box.globalToLocal(details.globalPosition); 792 | //防止绘画越界 793 | if (touchPoint.dx <= 0) { 794 | touchPoint = new Offset(0, 0.0); 795 | } 796 | if (touchPoint.dx >= context.size.width) { 797 | touchPoint = new Offset(context.size.width, 0); 798 | } 799 | if (touchPoint.dy <= 0) { 800 | touchPoint = new Offset(touchPoint.dx, 0.0); 801 | } 802 | if (touchPoint.dy >= context.size.height) { 803 | touchPoint = new Offset(touchPoint.dx, context.size.height); 804 | } 805 | setState(() { 806 | _value = touchPoint.dx / context.size.width; 807 | _setValue(); 808 | if (widget.alwaysShowBubble != null && widget.alwaysShowBubble 809 | ? false 810 | : true) { 811 | this._alwaysShowBubble = true; 812 | } 813 | if (widget.afterDragShowSectionText ?? false) { 814 | _afterDragShowSectionText = false; 815 | } 816 | }); 817 | } 818 | 819 | // Updates height and value when user drags the SeekBar. 820 | void _onPanUpdate(DragUpdateDetails dragDetails) { 821 | RenderBox box = context.findRenderObject(); 822 | touchPoint = box.globalToLocal(dragDetails.globalPosition); 823 | //防止绘画越界 824 | if (touchPoint.dx <= 0) { 825 | touchPoint = new Offset(0, 0.0); 826 | } 827 | if (touchPoint.dx >= context.size.width) { 828 | touchPoint = new Offset(context.size.width, 0); 829 | } 830 | if (touchPoint.dy <= 0) { 831 | touchPoint = new Offset(touchPoint.dx, 0.0); 832 | } 833 | if (touchPoint.dy >= context.size.height) { 834 | touchPoint = new Offset(touchPoint.dx, context.size.height); 835 | } 836 | setState(() { 837 | _value = touchPoint.dx / context.size.width; 838 | 839 | _setValue(); 840 | }); 841 | } 842 | 843 | void _onPanEnd(DragEndDetails dragDetails) { 844 | setState(() { 845 | if (widget.alwaysShowBubble != null && widget.alwaysShowBubble 846 | ? false 847 | : true) { 848 | this._alwaysShowBubble = false; 849 | } 850 | if (widget.afterDragShowSectionText ?? false) { 851 | _afterDragShowSectionText = true; 852 | } 853 | }); 854 | } 855 | 856 | void _setValue() { 857 | //这个是当前的进度 从0-1 858 | //这个�����值��能在这个地方获取,如果没有指定,就是容器的��度 859 | if (sectionCount > 1) { 860 | for (var i = 0; i < sectionCount; i++) { 861 | if (_value >= i * e && _value <= (i + 1) * e) { 862 | start = i * e; 863 | if (i == sectionCount) { 864 | end = sectionCount * e; 865 | } else { 866 | end = (i + 1) * e; 867 | } 868 | break; 869 | } 870 | } 871 | if (_value >= start + e / 2) { 872 | _value = end; 873 | } else { 874 | _value = start; 875 | } 876 | } 877 | double realValue = length * _value + widget.min; //真实的值 878 | 879 | if (widget.onValueChanged != null) { 880 | ProgressValue v = ProgressValue(progress: _value, value: realValue); 881 | widget.onValueChanged(v); 882 | } 883 | } 884 | 885 | @override 886 | void didUpdateWidget(SeekBar oldWidget) { 887 | super.didUpdateWidget(oldWidget); 888 | setState(() { 889 | _value = (widget.value - widget.min) / (widget.max - widget.min); 890 | }); 891 | } 892 | 893 | @override 894 | Widget build(BuildContext context) { 895 | if (widget.isCanTouch) { 896 | return GestureDetector( 897 | onPanDown: _onPanDown, 898 | onPanUpdate: _onPanUpdate, 899 | onPanEnd: _onPanEnd, 900 | onTapUp: _onTapUp, 901 | child: _buildSeekBar(context, _value, widget.min, widget.max)); 902 | } else { 903 | return _buildSeekBar(context, _value, widget.min, widget.max); 904 | } 905 | } 906 | } 907 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_seekbar 2 | description: A new flutter plugin project. 3 | version: 0.0.3 4 | author: liucheng 5 | homepage: https://github.com/LiuC520/flutter_seekbar 6 | environment: 7 | sdk: ">=2.0.0-dev.68.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # For information on the generic Dart part of this file, see the 14 | # following page: https://www.dartlang.org/tools/pub/pubspec 15 | 16 | # The following section is specific to Flutter. 17 | flutter: 18 | # This section identifies this Flutter project as a plugin project. 19 | # The androidPackage and pluginClass identifiers should not ordinarily 20 | # be modified. They are used by the tooling to maintain consistency when 21 | # adding or updating assets for this project. 22 | plugin: 23 | androidPackage: com.example.flutterseekbar 24 | pluginClass: FlutterSeekbarPlugin 25 | 26 | # To add assets to your plugin package, add an assets section, like this: 27 | # assets: 28 | # - images/a_dot_burr.jpeg 29 | # - images/a_dot_ham.jpeg 30 | # 31 | # For details regarding assets in packages, see 32 | # https://flutter.io/assets-and-images/#from-packages 33 | # 34 | # An image asset can refer to one or more resolution-specific "variants", see 35 | # https://flutter.io/assets-and-images/#resolution-aware. 36 | 37 | # To add custom fonts to your plugin package, add a fonts section here, 38 | # in this "flutter" section. Each entry in this list should have a 39 | # "family" key with the font family name, and a "fonts" key with a 40 | # list giving the asset and other descriptors for the font. For 41 | # example: 42 | # fonts: 43 | # - family: Schyler 44 | # fonts: 45 | # - asset: fonts/Schyler-Regular.ttf 46 | # - asset: fonts/Schyler-Italic.ttf 47 | # style: italic 48 | # - family: Trajan Pro 49 | # fonts: 50 | # - asset: fonts/TrajanPro.ttf 51 | # - asset: fonts/TrajanPro_Bold.ttf 52 | # weight: 700 53 | # 54 | # For details regarding fonts in packages, see 55 | # https://flutter.io/custom-fonts/#from-packages 56 | -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LiuC520/flutter_seekbar/96e16c007f0d9ce02aff90aa8a1a3667ab933dd7/screenshot.gif --------------------------------------------------------------------------------