├── .gitignore ├── .metadata ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── rhyme │ │ │ └── flutterbyrhyme │ │ │ └── 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 │ │ ├── string.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── assets ├── shop.json └── test.json ├── flutterbyrhyme.iml ├── flutterbyrhyme_android.iml ├── fonts └── qlYouYuan.ttf ├── images ├── burgers.jpg ├── chewCrispyChicken.9.jpg ├── gold.png ├── help_search1.png ├── help_search2.png ├── help_search3.png ├── help_theme1.png ├── help_theme2.png ├── help_widget_select1.png ├── help_widget_select2.png ├── help_widget_select3.png └── pazzer.jpg ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── 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 ├── Application.dart ├── about.dart ├── backdrop.dart ├── code │ ├── code_highlighter.dart │ ├── example_code.dart │ └── markdown_dart_code.dart ├── common │ └── Constant.dart ├── design │ ├── ChatRoom.dart │ ├── ShopPage.dart │ ├── aDesignShow.dart │ └── entity │ │ ├── shop.dart │ │ └── shopGet.dart ├── device │ └── temp.dart ├── expand │ ├── FallingWidget.dart │ ├── FallingWidgetDemo.dart │ ├── PowerCircle.dart │ ├── PowerCircleDemo.dart │ ├── PullToRefresh.dart │ ├── RhyRefreshIndicator.dart │ ├── aExpandShow.dart │ └── temp.dart ├── home │ └── home.dart ├── http │ └── httpManager.dart ├── main.dart ├── options │ ├── help.dart │ ├── local.dart │ ├── options.dart │ ├── scales.dart │ └── theme.dart ├── pages.dart ├── search.dart ├── upgrade.dart └── widgets │ ├── access │ ├── aAccessShow.dart │ ├── aSemantics.dart │ ├── bMergeSemantics.dart │ └── cExcludeSemantics.dart │ ├── animated │ ├── aAnimatedContainer.dart │ ├── aaAnimatedShow.dart │ ├── bAnimatedCrossFade.dart │ ├── cHero.dart │ ├── dAnimatedBuilder.dart │ ├── eDecoratedBoxTransition.dart │ ├── fFadeTransition.dart │ ├── gPositionedTransition.dart │ ├── hRotationTransition.dart │ ├── iScaleTransition.dart │ ├── jSizeTransition.dart │ ├── kSlideTransition.dart │ ├── lAnimatedDefaultTextStyle.dart │ ├── mAnimatedListState.dart │ ├── nAnimatedModalBarrier.dart │ ├── oAnimatedOpacity.dart │ ├── pAnimatedPhysicalModel.dart │ ├── qAnimatedPositioned.dart │ ├── rAnimatedSize.dart │ ├── sAnimatedWidget.dart │ └── tAnimatedWidgetBaseState.dart │ ├── assets │ ├── aAssetsShow.dart │ ├── cRawImage.dart │ └── dAssetBundle.dart │ ├── async │ ├── aAsyncShow.dart │ ├── aFutureBuilder.dart │ └── bStreamBuilder.dart │ ├── basics │ ├── aBasicesShow.dart │ ├── aContainer.dart │ ├── bRow.dart │ ├── cColumn.dart │ ├── dImage.dart │ ├── eText.dart │ ├── fIcon.dart │ ├── gRaisedButton.dart │ ├── hScaffold.dart │ ├── iAppBar.dart │ ├── jFlutterLogo.dart │ └── kPlaceholder.dart │ ├── cupertino │ ├── aCupertinoActivityIndicator.dart │ ├── aaCupertinoShow.dart │ ├── bCupertinoAlertDialog.dart │ ├── cCupertinoButton.dart │ ├── dCupertinoDialog.dart │ ├── eCupertinoDialogAction.dart │ ├── fCupertinoSlider.dart │ ├── gCupertinoSwitch.dart │ ├── hCupertinoPageTransition.dart │ ├── iCupertinoFullscreenDialogTransition.dart │ ├── jCupertinoNavigationBar.dart │ ├── kCupertinoTabBar.dart │ ├── lCupertinoPageScaffold.dart │ ├── mCupertinoTabScaffold.dart │ ├── nCupertinoTabView.dart │ ├── oCupertinoActionSheet.dart │ ├── pCupertinoSegmentedControl.dart │ ├── qCupertinoPicker.dart │ └── rCupertinoTimerPicker.dart │ ├── input │ ├── aForm.dart │ ├── aaInputShow.dart │ ├── bFormField.dart │ └── cRawKeyboardListener.dart │ ├── interaction │ ├── aInteractionShow.dart │ ├── aLongPressDraggable.dart │ ├── bGestureDetector.dart │ ├── cDragTarget.dart │ ├── dDismissible.dart │ ├── eIgnorePointer.dart │ ├── fAbsorbPointer.dart │ ├── gNavigator.dart │ └── hScrollable.dart │ ├── layout │ ├── aLayoutShow.dart │ ├── aPadding.dart │ ├── bCenter.dart │ ├── cAlign.dart │ ├── dFittedBox.dart │ ├── eAspectRatio.dart │ ├── fConstrainedBox.dart │ ├── gBaseline.dart │ ├── hFractionallySizedBox.dart │ ├── iIntrinsicHeight.dart │ ├── jIntrinsicWidth.dart │ ├── kLimitedBox.dart │ ├── lOffstage.dart │ ├── mOverflowBox.dart │ ├── nSizedBox.dart │ ├── oSizedOverflowBox.dart │ ├── pTransform.dart │ ├── qCustomSingleChildLayout.dart │ ├── tStack.dart │ ├── uIndexedStack.dart │ ├── vFlow.dart │ ├── wTable.dart │ ├── xWrap.dart │ ├── yListBody.dart │ ├── zaListView.dart │ ├── zbCustomMultiChildLayout.dart │ └── zcLayoutBuilder.dart │ ├── material │ ├── aMaterialShow.dart │ ├── cBottomNavigationBar.dart │ ├── dTabBar.dart │ ├── eTabBarView.dart │ ├── fMaterialApp.dart │ ├── gWidgetsApp.dart │ ├── hDrawer.dart │ ├── jFloatingActionButton.dart │ ├── kFlatButton.dart │ ├── lIconButton.dart │ ├── mPopupMenuButton.dart │ ├── nButtonBar.dart │ ├── oTextField.dart │ ├── pCheckBox.dart │ ├── qRadio.dart │ ├── rSwitch.dart │ ├── sSlider.dart │ ├── tDate&TimePickers.dart │ ├── uSimpleDialog.dart │ ├── vAlertDialog.dart │ ├── wBottomSheet.dart │ ├── xExpansionPanel.dart │ ├── ySnackBar.dart │ ├── zcChip.dart │ ├── zdTooltip.dart │ ├── zeDataTable.dart │ ├── zfCard.dart │ ├── zgLinearProgressIndicator.dart │ ├── zhListTile.dart │ ├── ziStepper.dart │ └── zjDivider.dart │ ├── painting │ ├── aOpacity.dart │ ├── aaPaintingShow.dart │ ├── cDecoratedBox.dart │ ├── dFractionalTranslation.dart │ ├── eRotatedBox.dart │ ├── fClipOval.dart │ ├── gClipPath.dart │ ├── hClipRect.dart │ ├── iCustomPaint.dart │ └── jBackdropFilter.dart │ ├── paramWidgets.dart │ ├── params.dart │ ├── scrolling │ ├── aScrollingShow.dart │ ├── bNestedScrollView.dart │ ├── cGridView.dart │ ├── dSingleChildScrollView.dart │ ├── fScrollbar.dart │ ├── gCustomScrollView.dart │ ├── hNotificationListener.dart │ ├── iScrollConfiguration.dart │ └── jRefreshIndicator.dart │ ├── styling │ ├── aStylingShow.dart │ ├── bTheme.dart │ └── cMediaQuery.dart │ └── text │ ├── aRichText.dart │ ├── aaTextShow.dart │ └── bDefaultTextStyle.dart ├── pubspec.lock ├── pubspec.yaml ├── screenshot └── screenshot.png └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | *.properties 9 | .flutter-plugins 10 | -------------------------------------------------------------------------------- /.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: c7ea3ca377e909469c68f2ab878a5bc53d3cf66b 8 | channel: beta 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutterbyrhyme 2 | 3 | A Flutter course. 4 | 5 | ## ScreenShot 6 | 7 | 8 | ## Downloading Apk 9 | 10 | null 11 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.class 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | GeneratedPluginRegistrant.java 11 | -------------------------------------------------------------------------------- /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 | apply plugin: 'com.android.application' 15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 16 | 17 | android { 18 | signingConfigs{ 19 | release{ 20 | storeFile file(APK_KEY_FILE) 21 | storePassword APK_KEY_PASSWORD 22 | keyAlias APK_KEY_ALIAS 23 | keyPassword APK_KEY_ALIAS_PASSWORD 24 | } 25 | } 26 | compileSdkVersion 27 27 | 28 | lintOptions { 29 | disable 'InvalidPackage' 30 | } 31 | 32 | defaultConfig { 33 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 34 | applicationId "com.rhyme.flutterbyrhyme" 35 | minSdkVersion 16 36 | targetSdkVersion 27 37 | versionCode 7 38 | versionName "0.0.7" 39 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 40 | } 41 | 42 | 43 | buildTypes { 44 | release { 45 | // TODO: Add your own signing config for the release build. 46 | // Signing with the debug keys for now, so `flutter run --release` works. 47 | signingConfig signingConfigs.release 48 | } 49 | debug{ 50 | signingConfig signingConfigs.release 51 | } 52 | } 53 | } 54 | 55 | flutter { 56 | source '../..' 57 | } 58 | 59 | dependencies { 60 | testImplementation 'junit:junit:4.12' 61 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 62 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 63 | } 64 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/string.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Flutter教程 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.0.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 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | APK_KEY_FILE=C\:\\Users\\Public\\flutter_course.jks 4 | APK_KEY_PASSWORD=flutter123 5 | APK_KEY_ALIAS=rhyme 6 | APK_KEY_ALIAS_PASSWORD=flutter123 7 | android.enableR8=true 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /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.1-all.zip 7 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /assets/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": "0", 3 | "msg": "成功", 4 | "data": "测试" 5 | } -------------------------------------------------------------------------------- /flutterbyrhyme.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /flutterbyrhyme_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /fonts/qlYouYuan.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/fonts/qlYouYuan.ttf -------------------------------------------------------------------------------- /images/burgers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/burgers.jpg -------------------------------------------------------------------------------- /images/chewCrispyChicken.9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/chewCrispyChicken.9.jpg -------------------------------------------------------------------------------- /images/gold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/gold.png -------------------------------------------------------------------------------- /images/help_search1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_search1.png -------------------------------------------------------------------------------- /images/help_search2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_search2.png -------------------------------------------------------------------------------- /images/help_search3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_search3.png -------------------------------------------------------------------------------- /images/help_theme1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_theme1.png -------------------------------------------------------------------------------- /images/help_theme2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_theme2.png -------------------------------------------------------------------------------- /images/help_widget_select1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_widget_select1.png -------------------------------------------------------------------------------- /images/help_widget_select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_widget_select2.png -------------------------------------------------------------------------------- /images/help_widget_select3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/help_widget_select3.png -------------------------------------------------------------------------------- /images/pazzer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/images/pazzer.jpg -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/app.flx 37 | /Flutter/app.zip 38 | /Flutter/flutter_assets/ 39 | /Flutter/App.framework 40 | /Flutter/Flutter.framework 41 | /Flutter/Generated.xcconfig 42 | /ServiceDefinitions.json 43 | 44 | Pods/ 45 | .symlinks/ 46 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | flutterbyrhyme 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/common/Constant.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019-present the rhyme_lph authors. All Rights Reserved. 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. 14 | 15 | 16 | const Constant constant=const Constant(); 17 | class Constant{ 18 | const Constant(); 19 | 20 | static const Map cnMap={ 21 | "app_name":"Flutter Do", 22 | "show":"显示", 23 | }; 24 | 25 | String get app_name=>cnMap['app_name']; 26 | 27 | String get show => cnMap['show']; 28 | 29 | 30 | } -------------------------------------------------------------------------------- /lib/design/aDesignShow.dart: -------------------------------------------------------------------------------- 1 | 2 | export 'ChatRoom.dart'; 3 | export 'ShopPage.dart'; -------------------------------------------------------------------------------- /lib/design/entity/shop.dart: -------------------------------------------------------------------------------- 1 | import 'package:html/parser.dart'; 2 | import 'dart:convert' show json; 3 | 4 | class Shop { 5 | final String num_iid; //数字标识 6 | final String commission_rate; //佣金率 7 | final String sign; //签名 8 | 9 | final String name; //名字 10 | final String image; //图片 11 | final String sourcePrice; //原价 12 | final String nowPrice; //现价 13 | final String sale; //折扣 14 | final String address;//地址,跳转链接 15 | 16 | Shop({ 17 | this.num_iid, 18 | this.commission_rate, 19 | this.sign, 20 | this.name, 21 | this.image, 22 | this.sourcePrice, 23 | this.nowPrice, 24 | this.sale, 25 | this.address, 26 | }); 27 | 28 | factory Shop.formatFromJson(dynamic itemsJson){ 29 | 30 | return new Shop(num_iid: itemsJson['num_iid'], 31 | commission_rate: itemsJson['commission_rate'], 32 | sign: itemsJson['sign'], 33 | name: itemsJson['name'], 34 | image: itemsJson['image'], 35 | sourcePrice: itemsJson['sourcePrice'], 36 | nowPrice: itemsJson['nowPrice'], 37 | sale: itemsJson['sale'], 38 | address: itemsJson['address'],); 39 | } 40 | @override 41 | String toString() { 42 | // TODO: implement toString 43 | return '{"num_iid":"$num_iid","commission_rate":"$commission_rate","sign":"$sign","name":"$name","image":"$image","sourcePrice":"$sourcePrice","nowPrice":"$nowPrice","sale":"$sale","address":"$address"}'; 44 | } 45 | 46 | static String encode(String html){ 47 | var doc=parse(html); 48 | var a=doc.getElementById('divList'); 49 | var b=a.getElementsByClassName('tb-zx-item'); 50 | List shops=[]; 51 | for(var c in b){ 52 | String info=c.attributes['onclick']; 53 | String image=c.getElementsByTagName('img')[0].attributes['src']; 54 | String name=c.getElementsByClassName('cf_itemname')[0].text.trim(); 55 | String nowPrice=c.getElementsByClassName('tb-cfprice')[0].text.trim(); 56 | String sourcePrice=c.getElementsByClassName('item-cf_flegg')[0].text.trim(); 57 | String sale=c.getElementsByClassName('cf_saler')[0].text.trim().replaceAll(' ', ''); 58 | 59 | String address=info.substring(info.indexOf('http'),info.indexOf('\');')); 60 | List clickLogs=info.substring(info.indexOf('clicklogs(')+10,info.lastIndexOf(')')).replaceAll('\'', '').split(','); 61 | 62 | 63 | String numIid=''; 64 | String commissionRate=''; 65 | String sign=''; 66 | if(clickLogs.length==3){ 67 | numIid=clickLogs[0]; 68 | commissionRate=clickLogs[1]; 69 | sign=clickLogs[2]; 70 | } 71 | shops.add(new Shop(num_iid: numIid,commission_rate: commissionRate,sign: sign,name: name,image: image,sourcePrice: sourcePrice,nowPrice: nowPrice,sale: sale,address: address,)); 72 | } 73 | String content=''; 74 | for(Shop shop in shops){ 75 | content+=shop.toString()+","; 76 | } 77 | print('[${content.substring(0,content.length-1)}]'); 78 | return '[${content.substring(0,content.length-1)}]'; 79 | } 80 | 81 | static List decode(Object jsonContnet){ 82 | 83 | var decode = json.decode(jsonContnet.toString()); 84 | 85 | List shops=[]; 86 | for(var info in decode){ 87 | shops.add(new Shop.formatFromJson(info)); 88 | } 89 | return shops; 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/device/temp.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Temp extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Scaffold( 7 | body: Center( 8 | child: Text('暂无'), 9 | ), 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/expand/FallingWidgetDemo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'FallingWidget.dart'; 3 | 4 | 5 | class FallingWidgetDemo extends StatefulWidget { 6 | static const String routeName = 'expand/FallingWidgetDemo'; 7 | 8 | @override 9 | _FallingWidgetDemoState createState() => _FallingWidgetDemoState(); 10 | } 11 | 12 | class _FallingWidgetDemoState extends State { 13 | 14 | @override 15 | void initState() { 16 | // Image.asset(name) 17 | super.initState(); 18 | } 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: AppBar( 23 | title: Text('飘雪'), 24 | ), 25 | backgroundColor: Colors.grey, 26 | body: FallingWidget( 27 | count: 50, 28 | // imagePath: 'images/gold.png', 29 | ), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/expand/PowerCircleDemo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'PowerCircle.dart'; 3 | 4 | 5 | class PowerCircleDemo extends StatefulWidget { 6 | static const String routeName = 'expand/PowerCircleDemo'; 7 | 8 | @override 9 | _PowerCircleDemoState createState() => _PowerCircleDemoState(); 10 | } 11 | 12 | class _PowerCircleDemoState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | appBar: AppBar( 17 | title: Text('能量球'), 18 | ), 19 | body: Center( 20 | child: PowerCircle( 21 | circleColor: Colors.white, 22 | progress: 0.4, 23 | child: Center( 24 | child: Text('40%'), 25 | ), 26 | ), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /lib/expand/PullToRefresh.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'RhyRefreshIndicator.dart'; 4 | import 'dart:async'; 5 | //import 'PullDown2.dart'; 6 | 7 | class PullToRefreshDemo extends StatefulWidget { 8 | static const String routeName = 'expand/PullToRefreshDemo'; 9 | 10 | @override 11 | _PullToRefreshDemoState createState() => _PullToRefreshDemoState(); 12 | } 13 | 14 | class _PullToRefreshDemoState extends State { 15 | List bodyList; 16 | 17 | @override 18 | void initState() { 19 | // TODO: implement initState 20 | bodyList = []; 21 | for (int i = 0; i < 5; i++) { 22 | bodyList.add('This item is $i'); 23 | } 24 | print('initState'); 25 | 26 | super.initState(); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return Scaffold( 32 | appBar: AppBar( 33 | title: Text('上拉下拉'), 34 | ), 35 | body: body, 36 | ); 37 | } 38 | 39 | get body => RhyRefreshIndicator( 40 | refreshHeight: 60.0, 41 | header: RefreshMyBody(), 42 | child: ListView.builder( 43 | itemCount: bodyList.length, 44 | itemBuilder: (BuildContext context, int index) { 45 | return ListTile( 46 | title: Text(bodyList[index]), 47 | ); 48 | }, 49 | ), 50 | onRefresh: () { 51 | final Completer comparator = new Completer(); 52 | 53 | new Timer(Duration(seconds: 2), () { 54 | setState(() { 55 | bodyList.insert(0, '新增'); 56 | }); 57 | comparator.complete(null); 58 | }); 59 | return comparator.future; 60 | }, 61 | footer: new RefreshMyBody2(), 62 | onLoading: () { 63 | final Completer comparator = new Completer(); 64 | 65 | new Timer(Duration(seconds: 2), () { 66 | setState(() { 67 | bodyList.add('新加'); 68 | }); 69 | comparator.complete(null); 70 | }); 71 | 72 | return comparator.future; 73 | }, 74 | ); 75 | } 76 | 77 | class RefreshMyBody extends RefreshBody { 78 | @override 79 | Widget onArmed() { 80 | return Text('松开刷新',style: TextStyle(color: Colors.white),); 81 | } 82 | 83 | @override 84 | Widget onCancel() { 85 | return Text('刷新取消',style: TextStyle(color: Colors.white),); 86 | } 87 | 88 | @override 89 | Widget onDone() { 90 | return Text('刷新完成',style: TextStyle(color: Colors.white),); 91 | } 92 | 93 | @override 94 | Widget onDrag() { 95 | return Text('下拉刷新',style: TextStyle(color: Colors.white),); 96 | } 97 | 98 | @override 99 | Widget onRefresh() { 100 | return Text('刷新中',style: TextStyle(color: Colors.white),); 101 | } 102 | 103 | @override 104 | Widget onSnap() { 105 | return Text('松开状态',style: TextStyle(color: Colors.white),); 106 | } 107 | } 108 | 109 | class RefreshMyBody2 extends RefreshBody { 110 | @override 111 | Widget onArmed() { 112 | return Text('松开加载',style: TextStyle(color: Colors.white),); 113 | } 114 | 115 | @override 116 | Widget onCancel() { 117 | return Text('加载取消',style: TextStyle(color: Colors.white),); 118 | } 119 | 120 | @override 121 | Widget onDone() { 122 | return Text('加载完成',style: TextStyle(color: Colors.white),); 123 | } 124 | 125 | @override 126 | Widget onDrag() { 127 | return Text('上拉加载',style: TextStyle(color: Colors.white),); 128 | } 129 | 130 | @override 131 | Widget onRefresh() { 132 | return Text('加载中',style: TextStyle(color: Colors.white),); 133 | } 134 | 135 | @override 136 | Widget onSnap() { 137 | return Text('松开状态',style: TextStyle(color: Colors.white),); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /lib/expand/aExpandShow.dart: -------------------------------------------------------------------------------- 1 | 2 | export 'PullToRefresh.dart'; 3 | export 'PowerCircleDemo.dart'; 4 | export 'FallingWidgetDemo.dart'; -------------------------------------------------------------------------------- /lib/expand/temp.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Temp extends StatelessWidget { 4 | static const String routeName='widgets/network/temp'; 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | body: Center( 10 | child: Text('暂无'), 11 | ), 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/http/httpManager.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:http/http.dart' as http; 3 | import 'dart:io'; 4 | 5 | typedef InterceptorCallback(); 6 | typedef InterceptorErrorCallback(dynamic e); 7 | typedef InterceptorsSuccessCallback(dynamic body); 8 | typedef InterceptorDoneCallback(dynamic done); 9 | 10 | get( 11 | {@required String url, 12 | Map headers, 13 | InterceptorCallback onSend, 14 | InterceptorsSuccessCallback onSuccess, 15 | InterceptorErrorCallback onError}) async { 16 | onSend(); 17 | try { 18 | await http.get(url, headers: headers).then( 19 | (http.Response response) { 20 | onSuccess(response.body); 21 | }, 22 | ).catchError(() { 23 | onError(null); 24 | }); 25 | } catch (e) { 26 | onError(e); 27 | } 28 | } 29 | 30 | post( 31 | {@required String url, 32 | Map headers, 33 | dynamic body, 34 | InterceptorCallback onSend, 35 | InterceptorsSuccessCallback onSuccess, 36 | InterceptorErrorCallback onError}) { 37 | onSend(); 38 | try { 39 | http.post(url, body: body).then( 40 | (http.Response response) { 41 | onSuccess(response.body); 42 | }, 43 | ).catchError((error, stack) { 44 | onError(error); 45 | }); 46 | } catch (e) { 47 | onError(e); 48 | } 49 | } 50 | 51 | webSocket( 52 | {@required String url, 53 | Map headers, 54 | Iterable protocols, 55 | InterceptorCallback onSend, 56 | InterceptorsSuccessCallback onSuccess, 57 | InterceptorErrorCallback onError, 58 | InterceptorDoneCallback onDone}) { 59 | onSend(); 60 | try { 61 | WebSocket.connect(url, protocols: protocols, headers: headers) 62 | .then((WebSocket webSocket) { 63 | onSuccess(webSocket); 64 | webSocket.done.then(onDone); 65 | }).catchError((error, stack) { 66 | onError(error); 67 | }); 68 | } catch (e) { 69 | onError(e); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'Application.dart'; 3 | import 'package:flutter/services.dart'; 4 | void main() { 5 | SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( 6 | statusBarIconBrightness: Brightness.light, 7 | systemNavigationBarColor: Colors.black, 8 | )); 9 | runApp(new Application()); 10 | } 11 | -------------------------------------------------------------------------------- /lib/options/local.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:async'; 4 | class MyLocalizationsDelegates extends LocalizationsDelegate{ 5 | @override 6 | bool isSupported(Locale locale) { 7 | return true; 8 | } 9 | 10 | @override 11 | Future load(Locale locale) =>SynchronousFuture(_MyLocalizations()); 12 | 13 | 14 | @override 15 | bool shouldReload(LocalizationsDelegate old) =>false; 16 | } 17 | 18 | class _MyLocalizations extends DefaultMaterialLocalizations{ 19 | 20 | @override 21 | String get searchFieldLabel => '搜索'; 22 | 23 | } -------------------------------------------------------------------------------- /lib/options/scales.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | ///字体大小 4 | class MyTextValueScale { 5 | final double scale; 6 | final String label; 7 | const MyTextValueScale(this.scale, this.label); 8 | @override //判断是否相等 9 | bool operator ==(other) { 10 | if (runtimeType != other.runtimeType) return false; 11 | final MyTextValueScale typeother = other; 12 | return scale == typeother.scale && label == typeother.label; 13 | } 14 | @override //获取hashcode 15 | int get hashCode => hashValues(scale, label); 16 | @override//输出当前大小标签 17 | String toString() { 18 | return '$runtimeType($label)'; 19 | } 20 | } 21 | 22 | const List kAllMyTextValue = const [ 23 | const MyTextValueScale(null, '默认'), 24 | const MyTextValueScale(0.7, '小号'), 25 | const MyTextValueScale(1.0, '正常'), 26 | const MyTextValueScale(1.1, '中号'), 27 | const MyTextValueScale(1.2, '大号'), 28 | ]; 29 | 30 | 31 | class ListStyleValue{ 32 | final int listStyle; 33 | final String label; 34 | const ListStyleValue(this.listStyle, this.label); 35 | 36 | @override //判断是否相等 37 | bool operator ==(other) { 38 | if (runtimeType != other.runtimeType) return false; 39 | final ListStyleValue typeother = other; 40 | return listStyle == typeother.listStyle && label == typeother.label; 41 | } 42 | @override //获取hashcode 43 | int get hashCode => hashValues(listStyle, label); 44 | @override//输出当前大小标签 45 | String toString() { 46 | return '$runtimeType($label)'; 47 | } 48 | } 49 | 50 | const List kAllListStyleValue=const [ 51 | const ListStyleValue(1, 'Grid'), 52 | const ListStyleValue(2, 'List'), 53 | ]; 54 | 55 | 56 | class MyThemeMode{ 57 | final int themeMode; 58 | final String label; 59 | 60 | const MyThemeMode(this.themeMode, this.label); 61 | 62 | @override 63 | bool operator ==(Object other) => 64 | identical(this, other) || 65 | other is MyThemeMode && 66 | runtimeType == other.runtimeType && 67 | themeMode == other.themeMode && 68 | label == other.label; 69 | 70 | @override 71 | int get hashCode => 72 | themeMode.hashCode ^ 73 | label.hashCode; 74 | 75 | @override 76 | String toString() { 77 | return 'MyThemeMode{themeMode: $themeMode, label: $label}'; 78 | } 79 | 80 | 81 | } 82 | const List kAllThemeModeValue = const [ 83 | MyThemeMode(0, '跟随系统'), 84 | MyThemeMode(1, '明亮模式'), 85 | MyThemeMode(2, '黑暗模式'), 86 | ]; -------------------------------------------------------------------------------- /lib/options/theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | ///App主题 4 | class MyTheme { 5 | final String name; 6 | final ThemeData data; 7 | 8 | const MyTheme._(this.name, this.data); 9 | 10 | MyTheme copyWith({ThemeData data}){ 11 | return MyTheme._(name, data??this.data); 12 | } 13 | @override 14 | bool operator ==(other) { 15 | if(identical(this, other)){ 16 | return true; 17 | } 18 | if(runtimeType!=other.runtimeType){ 19 | return false; 20 | } 21 | MyTheme typeOther=other; 22 | return name==typeOther.name; 23 | } 24 | @override 25 | // TODO: implement hashCode 26 | int get hashCode => hashValues(name, data); 27 | } 28 | 29 | MyTheme kDarkTheme = MyTheme._('Dark', _buildDarkTheme()); 30 | MyTheme kLightTheme = MyTheme._('Light', _buildLightTheme()); 31 | 32 | TextTheme _buildTextTheme(TextTheme base) { 33 | return base.copyWith( 34 | title: base.title.copyWith( 35 | fontFamily: 'qlYouYuan', 36 | ), 37 | subhead: base.subhead.copyWith(fontFamily: 'qlYouYuan'), 38 | ); 39 | } 40 | 41 | ThemeData _buildDarkTheme() { 42 | const Color primaryColor = const Color(0xFF002D75); 43 | final ThemeData base = new ThemeData.dark(); 44 | return base.copyWith( 45 | primaryColor: primaryColor, 46 | buttonColor: primaryColor, 47 | indicatorColor: Colors.white, 48 | accentColor: const Color(0xFF13B9FD), 49 | canvasColor: const Color(0xFF202124), 50 | scaffoldBackgroundColor: const Color(0xFF202124), 51 | backgroundColor: const Color(0xFF202124), 52 | errorColor: const Color(0xFFB00020), 53 | buttonTheme: const ButtonThemeData( 54 | textTheme: ButtonTextTheme.primary, 55 | ), 56 | textTheme: _buildTextTheme(base.textTheme), 57 | primaryTextTheme: _buildTextTheme(base.primaryTextTheme), 58 | accentTextTheme: _buildTextTheme(base.accentTextTheme), 59 | ); 60 | } 61 | 62 | ThemeData _buildLightTheme() { 63 | const Color primaryColor = Colors.blue; 64 | final ThemeData base = new ThemeData.light(); 65 | return base.copyWith( 66 | primaryColor: primaryColor, 67 | buttonColor: primaryColor, 68 | indicatorColor: Colors.white, 69 | splashColor: Colors.white24, 70 | splashFactory: InkRipple.splashFactory, 71 | accentColor: const Color(0xFF002D75), 72 | canvasColor: Colors.grey[200], 73 | scaffoldBackgroundColor: Colors.grey[200], 74 | backgroundColor: Colors.grey[200], 75 | errorColor: const Color(0xFFB00020), 76 | buttonTheme: const ButtonThemeData( 77 | textTheme: ButtonTextTheme.primary, 78 | ), 79 | textTheme: _buildTextTheme(base.textTheme), 80 | primaryTextTheme: _buildTextTheme(base.primaryTextTheme), 81 | accentTextTheme: _buildTextTheme(base.accentTextTheme), 82 | ); 83 | } 84 | -------------------------------------------------------------------------------- /lib/widgets/access/aAccessShow.dart: -------------------------------------------------------------------------------- 1 | export 'aSemantics.dart'; 2 | export 'bMergeSemantics.dart'; 3 | export 'cExcludeSemantics.dart'; -------------------------------------------------------------------------------- /lib/widgets/access/aSemantics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class SemanticsDemo extends StatefulWidget { 4 | static const String routeName='widgets/access/Semantics'; 5 | final String detail='''## 简介 6 | 一个小部件,用小部件含义的描述来注释小部件树。 7 | 由可访问性工具,搜索引擎和其他语义分析软件使用,以确定应用程序的含义。 8 | 9 | ## 参数 10 | 11 | > 五个参数 12 | 13 | | 类型 | 参数 | 介绍 | 14 | | - | - | - | 15 | | Widget | child | 子部件 | 16 | | bool | container | 为true,则此小部件将在语义树中引入新节点 | 17 | | bool | explicitChildNodes | 是否允许此窗口小部件的后代将语义信息添加SemanticsNode到此窗口小部件的注释中 | 18 | | bool | excludeSemantics | 是否用此节点替换所有子语义 | 19 | | SemanticsProperties | properties | 包含辅助技术使用的属性,以使应用程序更易于访问 | 20 | 21 | ## properties 22 | 23 | |类型|参数|介绍(非null情况下)| 24 | |-|-|-| 25 | |bool|enabled|处于启用或禁用状态| 26 | |bool|checked|具有“已检查”或“未检查”状态的复选框或类似窗口小部件| 27 | |bool|selected|处于选定或未选择状态的内容| 28 | |bool|toggled|具有切换的开关| 29 | |bool|button|表示按钮| 30 | |bool|header|表示标题| 31 | |bool|textField|是否表示文本字段的内容| 32 | |bool|focused|是否保持输入焦点| 33 | |bool|inMutuallyExclusiveGroup|若是否处于互斥组中| 34 | |bool|obscured|是否value应该被遮盖| 35 | |bool|scopesRoute|以遍历排序顺序确定此节点在其兄弟节点中的位置| 36 | |bool|namesRoute|是否包含路由的语义标签| 37 | |bool|hidden|是否隐藏| 38 | |bool|image|是否表示图像| 39 | |bool|liveRegion|是否应被视为活动区域| 40 | |String|label|标签| 41 | |String|value|提供窗口小部件值的文本描述| 42 | |String|increasedValue|增加值| 43 | |String|decreasedValue|在此窗口小部件上执行操作value后将变为 的值SemanticsAction.decrease| 44 | |String|hint|提供对窗口小部件执行的操作结果的简要文本描述| 45 | |String|onTapHint|已过期| 46 | |String|onLongPressHint|处理程序SemanticsAction.longPress| 47 | |TextDirection|textDirection|所述的阅读方向label,value,hint,increasedValue,和decreasedValue| 48 | |SemanticsSortKey|sortKey|以遍历排序顺序确定此节点在其兄弟节点中的位置| 49 | |VoidCallback|onTap|处理程序SemanticsAction.tap| 50 | |VoidCallback|onLongPress|处理程序SemanticsAction.longPress| 51 | |VoidCallback|onScrollLeft|处理程序SemanticsAction.scrollLeft| 52 | |VoidCallback|onScrollRight|处理程序SemanticsAction.scrollRight| 53 | |VoidCallback|onScrollUp|处理程序SemanticsAction.scrollUp| 54 | |VoidCallback|onScrollDown|处理程序SemanticsAction.scrollDown| 55 | |VoidCallback|onIncrease|处理程序SemanticsAction.increase| 56 | |VoidCallback|onDecrease|处理程序SemanticsAction.decrease| 57 | |VoidCallback|onCopy|处理程序SemanticsAction.copy| 58 | |VoidCallback|onCut|处理程序SemanticsAction.cut| 59 | |VoidCallback|onPaste|处理程序SemanticsAction.paste| 60 | |VoidCallback|onDismiss|处理程序SemanticsAction.dismiss| 61 | |MoveCursorHandler|onMoveCursorForwardByCharacter|处理程序SemanticsAction.onMoveCursorForwardByCharacter| 62 | |MoveCursorHandler|onMoveCursorBackwardByCharacter|处理程序SemanticsAction.onMoveCursorBackwardByCharacter| 63 | |SetSelectionHandler|onSetSelection|处理程序SemanticsAction.setSelection| 64 | |VoidCallback|onDidGainAccessibilityFocus|处理程序SemanticsAction.didGainAccessibilityFocus| 65 | |VoidCallback|onDidLoseAccessibilityFocus|处理程序SemanticsAction.didLoseAccessibilityFocus| 66 | |Map|customSemanticsActions|从每个支持CustomSemanticsAction到提供的处理程序的映射| 67 | 68 | ## 使用 69 | 使用暂未明,猜测用于新系统Fuchsia 70 | '''; 71 | 72 | @override 73 | _SemanticsDemoState createState() => _SemanticsDemoState(); 74 | } 75 | 76 | class _SemanticsDemoState extends MarkdownState { 77 | 78 | @override 79 | String getMarkdownSource() { 80 | return widget.detail; 81 | } 82 | 83 | @override 84 | String getTitle() { 85 | return 'Semantics'; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /lib/widgets/access/bMergeSemantics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class MergeSemanticsDemo extends StatefulWidget { 4 | static const String routeName='widgets/access/MergeSemantics'; 5 | final String detail='''## 介绍 6 | 一个合并其后代语义的小部件。 7 | 使在这个节点上根植的子树的所有语义合并到语义树中的一个节点中。例如,如果在复选框小部件旁边有一个带有Text节点的小部件,则可以使用这个小部件将具有复选框的“选中”语义状态的Text节点中的标签合并到具有标签和选中状态的单个节点中。否则,标签将作为与复选框不同的独立特性呈现,并且用户将不能确定它们是否相关。 8 | 请注意,如果子树中的两个节点具有语义冲突,则结果可能是无意义的。例如,带有选中的复选框和未选中复选框的子树将被呈现为选中。所有的标签将被合并成一个单一的字符串(新线分隔每个标签从另一个)。如果合并的子树中的多个节点能够处理语义手势,那么按照树顺序的第一个节点将是接收回调的节点。 9 | 10 | ## 使用 11 | ```dart 12 | MergeSemantics( 13 | child: Column( 14 | children: [ 15 | Semantics( 16 | value: 'Hello', 17 | child: Text('Hello'), 18 | ), 19 | Semantics( 20 | label: 'World', 21 | child: Text('World'), 22 | ) 23 | ], 24 | ), 25 | ); 26 | ```'''; 27 | 28 | @override 29 | _MergeSemanticsDemoState createState() => _MergeSemanticsDemoState(); 30 | } 31 | class _MergeSemanticsDemoState extends MarkdownState { 32 | 33 | 34 | @override 35 | String getMarkdownSource() { 36 | return widget.detail; 37 | } 38 | 39 | @override 40 | String getTitle() { 41 | return 'MergeSemantics'; 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /lib/widgets/access/cExcludeSemantics.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class ExcludeSemanticsDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/access/ExcludeSemantics'; 6 | final String detail = '''## 介绍 7 | 一个删除所有后代的语义的小部件。 8 | 9 | 当排除为真时,该小部件(及其子树)被排除在语义树之外。 10 | 11 | 这可以用来隐藏否则会被报告但只会混淆的后代小部件。例如,素材库的芯片小部件隐藏了化身,因为它与芯片标签是冗余的。 12 | 13 | ## 使用 14 | ```dart 15 | ExcludeSemantics( 16 | excluding: true, 17 | child: Semantics( 18 | value: 'Hello', 19 | child: Text('Hello'), 20 | ), 21 | ); 22 | ```'''; 23 | 24 | @override 25 | _ExcludeSemanticsDemoState createState() => _ExcludeSemanticsDemoState(); 26 | } 27 | 28 | class _ExcludeSemanticsDemoState extends MarkdownState { 29 | 30 | @override 31 | String getMarkdownSource() { 32 | return widget.detail; 33 | } 34 | 35 | @override 36 | String getTitle() { 37 | return 'ExcludeSemantics'; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/widgets/animated/aaAnimatedShow.dart: -------------------------------------------------------------------------------- 1 | export 'aAnimatedContainer.dart'; 2 | export 'bAnimatedCrossFade.dart'; 3 | export 'cHero.dart'; 4 | export 'dAnimatedBuilder.dart'; 5 | export 'eDecoratedBoxTransition.dart'; 6 | export 'fFadeTransition.dart'; 7 | export 'gPositionedTransition.dart'; 8 | export 'hRotationTransition.dart'; 9 | export 'iScaleTransition.dart'; 10 | export 'jSizeTransition.dart'; 11 | export 'kSlideTransition.dart'; 12 | export 'lAnimatedDefaultTextStyle.dart'; 13 | export 'mAnimatedListState.dart'; 14 | export 'nAnimatedModalBarrier.dart'; 15 | export 'oAnimatedOpacity.dart'; 16 | export 'pAnimatedPhysicalModel.dart'; 17 | export 'qAnimatedPositioned.dart'; 18 | export 'rAnimatedSize.dart'; 19 | export 'sAnimatedWidget.dart'; 20 | export 'tAnimatedWidgetBaseState.dart'; -------------------------------------------------------------------------------- /lib/widgets/animated/dAnimatedBuilder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | import 'dart:math'; 4 | 5 | class AnimatedBuilderDemo extends StatefulWidget { 6 | static const String routeName = 'widgets/assets/AnimatedBuilder'; 7 | final String detail = ''''''; 8 | 9 | @override 10 | _AnimatedBuilderDemoState createState() => _AnimatedBuilderDemoState(); 11 | } 12 | 13 | class _AnimatedBuilderDemoState extends ExampleState 14 | with SingleTickerProviderStateMixin { 15 | AnimatedBuilderSetting setting; 16 | AnimationController _controller; 17 | 18 | @override 19 | void initState() { 20 | _controller = 21 | AnimationController(duration: Duration(seconds: 2), vsync: this); 22 | setting = AnimatedBuilderSetting( 23 | animation: Value( 24 | value: _controller, 25 | label: '_controller', 26 | ), 27 | child: Value( 28 | value: Image.asset('images/burgers.jpg'), 29 | label: "Image.asset('images/burgers.jpg')", 30 | ), 31 | builder: Value( 32 | value: (BuildContext context, Widget child) { 33 | return new Transform.rotate( 34 | angle: _controller.value * 2 * pi, 35 | child: child, 36 | ); 37 | }, 38 | label: '''(BuildContext context, Widget child) { 39 | return new Transform.rotate( 40 | angle: _controller.value * 2 * pi, 41 | child: child, 42 | ); 43 | }''')); 44 | super.initState(); 45 | } 46 | 47 | @override 48 | void dispose() { 49 | if (_controller != null) { 50 | _controller.dispose(); 51 | } 52 | super.dispose(); 53 | } 54 | 55 | @override 56 | String getDetail() { 57 | return widget.detail; 58 | } 59 | 60 | @override 61 | String getExampleCode() { 62 | return '''//vsync: this 需要 with SingleTickerProviderStateMixin 63 | AnimationController _controller = 64 | AnimationController(duration: Duration(seconds: 2), vsync: this); 65 | 66 | AnimatedBuilder( 67 | animation: ${setting.animation?.label??''}, 68 | builder: ${setting.builder?.label??''}, 69 | child: ${setting.child?.label??''}, 70 | ) 71 | 72 | //动画启动 73 | _controller.forward();'''; 74 | } 75 | 76 | @override 77 | List getSetting() { 78 | return [ 79 | ValueTitleButtonWidget(title:'动画启动',onPressed: (){ 80 | _controller.reset(); 81 | _controller.forward(); 82 | },) 83 | ]; 84 | } 85 | 86 | @override 87 | String getTitle() { 88 | return 'AnimatedBuilder'; 89 | } 90 | 91 | @override 92 | Widget getWidget() { 93 | return AnimatedBuilder( 94 | animation: setting.animation?.value, 95 | builder: setting.builder?.value, 96 | child: setting.child?.value, 97 | ); 98 | } 99 | } 100 | 101 | class AnimatedBuilderSetting { 102 | final Value animation; 103 | final Value builder; 104 | final Value child; 105 | 106 | AnimatedBuilderSetting({ 107 | this.animation, 108 | this.builder, 109 | this.child, 110 | }); 111 | 112 | AnimatedBuilderSetting copyWith({ 113 | final Value animation, 114 | final Value builder, 115 | final Value child, 116 | }) { 117 | return AnimatedBuilderSetting( 118 | animation: animation ?? this.animation, 119 | builder: builder ?? this.builder, 120 | child: child ?? this.child, 121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/widgets/animated/fFadeTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class FadeTransitionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/assets/FadeTransition'; 6 | final String detail = ''''''; 7 | 8 | @override 9 | _FadeTransitionDemoState createState() => _FadeTransitionDemoState(); 10 | } 11 | 12 | class _FadeTransitionDemoState extends ExampleState 13 | with SingleTickerProviderStateMixin { 14 | FadeTransitionSetting setting; 15 | AnimationController _controller; 16 | 17 | @override 18 | void initState() { 19 | _controller = 20 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 21 | setting = FadeTransitionSetting( 22 | opacity: Value( 23 | value: _controller, 24 | label: '_controller', 25 | ), 26 | alwaysIncludeSemantics: boolValues[0], 27 | child: Value( 28 | value: Image.asset('images/burgers.jpg'), 29 | label: "Image.asset('images/burgers.jpg')", 30 | ), 31 | ); 32 | super.initState(); 33 | } 34 | 35 | @override 36 | String getDetail() { 37 | return widget.detail; 38 | } 39 | 40 | @override 41 | String getExampleCode() { 42 | return '''//vsync: this 需要 with SingleTickerProviderStateMixin 43 | AnimationController _controller = 44 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 45 | 46 | FadeTransition( 47 | opacity: ${setting.opacity?.label ?? ''}, 48 | alwaysIncludeSemantics: ${setting.alwaysIncludeSemantics?.label ?? ''}, 49 | child: ${setting.child?.label ?? ''}, 50 | ) 51 | 52 | //动画启动 53 | _controller.forward();'''; 54 | } 55 | 56 | @override 57 | List getSetting() { 58 | return [ 59 | ValueTitleButtonWidget( 60 | title: '动画启动', 61 | onPressed: () { 62 | _controller.reset(); 63 | _controller.forward(); 64 | }, 65 | ), 66 | SwitchValueTitleWidget( 67 | title: StringParams.kAlwaysIncludeSemantics, 68 | value: setting.alwaysIncludeSemantics, 69 | onChanged: (value) { 70 | setState(() { 71 | setting = setting.copyWith(alwaysIncludeSemantics: value); 72 | }); 73 | }) 74 | ]; 75 | } 76 | 77 | @override 78 | String getTitle() { 79 | return 'FadeTransition'; 80 | } 81 | 82 | @override 83 | Widget getWidget() { 84 | return FadeTransition( 85 | opacity: setting.opacity?.value, 86 | alwaysIncludeSemantics: setting.alwaysIncludeSemantics?.value, 87 | child: setting.child?.value, 88 | ); 89 | } 90 | } 91 | 92 | class FadeTransitionSetting { 93 | final Value> opacity; 94 | final Value alwaysIncludeSemantics; 95 | final Value child; 96 | 97 | FadeTransitionSetting({ 98 | this.opacity, 99 | this.alwaysIncludeSemantics, 100 | this.child, 101 | }); 102 | 103 | FadeTransitionSetting copyWith({ 104 | Value> opacity, 105 | Value alwaysIncludeSemantics, 106 | Value child, 107 | }) { 108 | return FadeTransitionSetting( 109 | opacity: opacity ?? this.opacity, 110 | alwaysIncludeSemantics: 111 | alwaysIncludeSemantics ?? this.alwaysIncludeSemantics, 112 | child: child ?? this.child, 113 | ); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/widgets/animated/gPositionedTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class PositionedTransitionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/assets/PositionedTransition'; 6 | final String detail = ''''''; 7 | 8 | @override 9 | _PositionedTransitionDemoState createState() => 10 | _PositionedTransitionDemoState(); 11 | } 12 | 13 | class _PositionedTransitionDemoState 14 | extends ExampleState 15 | with SingleTickerProviderStateMixin { 16 | PositionedTransitionSetting setting; 17 | AnimationController _controller; 18 | 19 | @override 20 | void initState() { 21 | _controller = 22 | new AnimationController(vsync: this, duration: Duration(seconds: 2)); 23 | setting = PositionedTransitionSetting( 24 | rect: Value( 25 | value: RelativeRectTween( 26 | begin: RelativeRect.fromLTRB(20.0, 20.0, 200.0, 200.0), 27 | end: RelativeRect.fromLTRB(0.0, 0.0, 150.0, 150.0), 28 | ).animate(_controller), 29 | label: '''RelativeRectTween( 30 | begin: RelativeRect.fromLTRB(20.0, 20.0, 200.0, 200.0), 31 | end: RelativeRect.fromLTRB(0.0, 0.0, 150.0, 150.0), 32 | ).animate(_controller)''', 33 | ), 34 | child: Value( 35 | value: Image.asset('images/burgers.jpg'), 36 | label: "Image.asset('images/burgers.jpg')", 37 | ), 38 | ); 39 | super.initState(); 40 | } 41 | 42 | @override 43 | void dispose() { 44 | if (_controller != null) { 45 | _controller.dispose(); 46 | } 47 | super.dispose(); 48 | } 49 | 50 | @override 51 | String getDetail() { 52 | return widget.detail; 53 | } 54 | 55 | @override 56 | String getExampleCode() { 57 | return '''//vsync: this 需要 with SingleTickerProviderStateMixin 58 | AnimationController _controller = 59 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 60 | 61 | Stack( 62 | children: [ 63 | PositionedTransition( 64 | child: ${setting.child?.label ?? ''}, 65 | rect: ${setting.rect?.label ?? ''}, 66 | ) 67 | ], 68 | ) 69 | 70 | //动画启动 71 | _controller.forward();'''; 72 | } 73 | 74 | @override 75 | List getSetting() { 76 | return [ 77 | ValueTitleButtonWidget( 78 | title: '动画启动', 79 | onPressed: () { 80 | _controller.reset(); 81 | _controller.forward(); 82 | }, 83 | ), 84 | ]; 85 | } 86 | 87 | @override 88 | String getTitle() { 89 | return 'PositionedTransition'; 90 | } 91 | 92 | @override 93 | Widget getWidget() { 94 | return Stack( 95 | children: [ 96 | PositionedTransition( 97 | child: setting.child?.value, 98 | rect: setting.rect?.value, 99 | ) 100 | ], 101 | ); 102 | } 103 | } 104 | 105 | class PositionedTransitionSetting { 106 | final Value> rect; 107 | final Value child; 108 | 109 | PositionedTransitionSetting({ 110 | this.rect, 111 | this.child, 112 | }); 113 | 114 | PositionedTransitionSetting copyWith({ 115 | Value> rect, 116 | Value child, 117 | }) { 118 | return PositionedTransitionSetting( 119 | rect: rect ?? this.rect, 120 | child: child ?? this.child, 121 | ); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/widgets/animated/hRotationTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class RotationTransitionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/assets/RotationTransition'; 6 | final String detail = '''动画小部件的旋转。'''; 7 | 8 | @override 9 | _RotationTransitionDemoState createState() => _RotationTransitionDemoState(); 10 | } 11 | 12 | class _RotationTransitionDemoState extends ExampleState 13 | with SingleTickerProviderStateMixin { 14 | RotationTransitionSetting setting; 15 | AnimationController _controller; 16 | 17 | @override 18 | void initState() { 19 | _controller = new AnimationController( 20 | vsync: this, duration: Duration(seconds: 1)); 21 | setting = RotationTransitionSetting( 22 | turns: Value(value: _controller, label: '_controller'), 23 | child: Value( 24 | value: Image.asset('images/burgers.jpg'), 25 | label: "Image.asset('images/burgers.jpg')", 26 | ), 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | void dispose() { 33 | if (_controller != null) { 34 | _controller.dispose(); 35 | } 36 | super.dispose(); 37 | } 38 | 39 | @override 40 | String getDetail() { 41 | return widget.detail; 42 | } 43 | 44 | @override 45 | String getExampleCode() { 46 | return '''//vsync: this 需要 with SingleTickerProviderStateMixin 47 | AnimationController _controller = 48 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 49 | 50 | RotationTransition( 51 | turns: ${setting.turns?.label ?? ''}, 52 | child: ${setting.child?.label ?? ''}, 53 | ) 54 | 55 | //动画启动 56 | _controller.forward();'''; 57 | } 58 | 59 | @override 60 | List getSetting() { 61 | return [ 62 | ValueTitleButtonWidget( 63 | title: '动画启动', 64 | onPressed: () { 65 | _controller.reset(); 66 | _controller.forward(); 67 | }, 68 | ), 69 | ]; 70 | } 71 | 72 | @override 73 | String getTitle() { 74 | return 'RotationTransition'; 75 | } 76 | 77 | @override 78 | Widget getWidget() { 79 | return RotationTransition( 80 | turns: setting.turns?.value, 81 | child: setting.child?.value, 82 | ); 83 | } 84 | } 85 | 86 | class RotationTransitionSetting { 87 | final Value> turns; 88 | final Value child; 89 | 90 | RotationTransitionSetting({ 91 | this.turns, 92 | this.child, 93 | }); 94 | 95 | RotationTransitionSetting copyWith({ 96 | Value> turns, 97 | Value child, 98 | }) { 99 | return RotationTransitionSetting( 100 | turns: turns ?? this.turns, 101 | child: child ?? this.child, 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widgets/animated/iScaleTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class ScaleTransitionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/assets/ScaleTransition'; 6 | final String detail = '动画转换小部件的比例。'; 7 | 8 | @override 9 | _ScaleTransitionDemoState createState() => _ScaleTransitionDemoState(); 10 | } 11 | 12 | class _ScaleTransitionDemoState extends ExampleState 13 | with SingleTickerProviderStateMixin { 14 | ScaleTransitionSetting setting; 15 | AnimationController _controller; 16 | 17 | @override 18 | void initState() { 19 | _controller = 20 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 21 | setting = ScaleTransitionSetting( 22 | scale: Value(value: _controller, label: '_controller'), 23 | child: Value( 24 | value: Image.asset('images/burgers.jpg'), 25 | label: "Image.asset('images/burgers.jpg')", 26 | ), 27 | ); 28 | super.initState(); 29 | } 30 | @override 31 | void dispose() { 32 | if (_controller != null) { 33 | _controller.dispose(); 34 | } 35 | super.dispose(); 36 | } 37 | @override 38 | String getDetail() { 39 | return widget.detail; 40 | } 41 | 42 | @override 43 | String getExampleCode() { 44 | return '''//vsync: this 需要 with SingleTickerProviderStateMixin 45 | AnimationController _controller = 46 | new AnimationController(vsync: this, duration: Duration(seconds: 1)); 47 | 48 | ScaleTransition( 49 | scale: ${setting.scale?.label ?? ''}, 50 | alignment: ${setting.alignment?.label ?? ''}, 51 | child: ${setting.child?.label ?? ''}, 52 | ) 53 | 54 | //动画启动 55 | _controller.forward();'''; 56 | } 57 | 58 | @override 59 | List getSetting() { 60 | return [ 61 | ValueTitleButtonWidget( 62 | title: '动画启动', 63 | onPressed: () { 64 | _controller.reset(); 65 | _controller.forward(); 66 | }, 67 | ), 68 | ValueTitleWidget(StringParams.kAlignment), 69 | RadioGroupWidget(setting.alignment, alignmentValues, 70 | (value) { 71 | setState(() { 72 | setting = setting.copyWith(alignment: value); 73 | }); 74 | }), 75 | ]; 76 | } 77 | 78 | @override 79 | String getTitle() { 80 | return 'ScaleTransition'; 81 | } 82 | 83 | @override 84 | Widget getWidget() { 85 | return ScaleTransition( 86 | scale: setting.scale?.value, 87 | alignment: setting.alignment?.value, 88 | child: setting.child?.value, 89 | ); 90 | } 91 | } 92 | 93 | class ScaleTransitionSetting { 94 | final Value> scale; 95 | final Value alignment; 96 | final Value child; 97 | 98 | ScaleTransitionSetting({this.scale, this.alignment, this.child}); 99 | 100 | ScaleTransitionSetting copyWith({ 101 | Value> scale, 102 | Value alignment, 103 | Value child, 104 | }) { 105 | return ScaleTransitionSetting( 106 | scale: scale ?? this.scale, 107 | alignment: alignment ?? this.alignment, 108 | child: child ?? this.child, 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /lib/widgets/animated/oAnimatedOpacity.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class AnimatedOpacityDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/assets/AnimatedOpacity'; 6 | final String detail = '''不透明度的动画版本,只要给定的不透明度发生变化,就会自动转换孩子在给定持续时间内的不透明度。 7 | 8 | 动画不透明度相对昂贵,因为它需要将子画面绘制到中间缓冲区中。'''; 9 | 10 | @override 11 | _AnimatedOpacityDemoState createState() => _AnimatedOpacityDemoState(); 12 | } 13 | 14 | class _AnimatedOpacityDemoState extends ExampleState { 15 | AnimatedOpacitySetting setting; 16 | 17 | @override 18 | void initState() { 19 | setting = AnimatedOpacitySetting( 20 | child: Value( 21 | value: Image.asset('images/burgers.jpg'), 22 | label: "Image.asset('images/burgers.jpg')", 23 | ), 24 | opacity: doubleOneValues[1], 25 | curve: curveValues[0], 26 | duration: durationValues[0], 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | String getDetail() { 33 | return widget.detail; 34 | } 35 | 36 | @override 37 | String getExampleCode() { 38 | return '''AnimatedOpacity( 39 | child: ${setting.child?.label ?? ''}, 40 | opacity: ${setting.opacity?.label ?? ''}, 41 | curve: ${setting.curve?.label ?? ''}, 42 | duration: ${setting.duration?.label ?? ''}, 43 | )'''; 44 | } 45 | 46 | @override 47 | List getSetting() { 48 | return [ 49 | ValueTitleWidget(StringParams.kDuration), 50 | RadioGroupWidget(setting.duration, durationValues, (value) { 51 | setState(() { 52 | setting = setting.copyWith(duration: value); 53 | }); 54 | }), 55 | ValueTitleWidget(StringParams.kCurve), 56 | RadioGroupWidget(setting.curve, curveValues, (value) { 57 | setState(() { 58 | setting = setting.copyWith(curve: value); 59 | }); 60 | }), 61 | 62 | ValueTitleWidget(StringParams.kOpacity), 63 | SeekBarGroupWidget(setting.opacity, (value){ 64 | setState(() { 65 | setState(() { 66 | setting = setting.copyWith(opacity: value); 67 | }); 68 | }); 69 | }), 70 | ]; 71 | } 72 | 73 | @override 74 | String getTitle() { 75 | return 'AnimatedOpacity'; 76 | } 77 | 78 | @override 79 | Widget getWidget() { 80 | return AnimatedOpacity( 81 | child: setting.child?.value, 82 | opacity: setting.opacity?.value, 83 | curve: setting.curve?.value, 84 | duration: setting.duration?.value, 85 | ); 86 | } 87 | } 88 | 89 | class AnimatedOpacitySetting { 90 | final Value child; 91 | final Value opacity; 92 | final Value curve; 93 | final Value duration; 94 | 95 | AnimatedOpacitySetting({ 96 | this.child, 97 | this.opacity, 98 | this.curve, 99 | this.duration, 100 | }); 101 | 102 | AnimatedOpacitySetting copyWith({ 103 | Value child, 104 | Value opacity, 105 | Value curve, 106 | Value duration, 107 | }) { 108 | return AnimatedOpacitySetting( 109 | child: child ?? this.child, 110 | opacity: opacity ?? this.opacity, 111 | curve: curve ?? this.curve, 112 | duration: duration ?? this.duration, 113 | ); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lib/widgets/assets/aAssetsShow.dart: -------------------------------------------------------------------------------- 1 | export 'cRawImage.dart'; 2 | export 'dAssetBundle.dart'; -------------------------------------------------------------------------------- /lib/widgets/assets/dAssetBundle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class AssetBundleDemo extends StatefulWidget { 4 | static const String routeName='widgets/assets/AssetBundle'; 5 | static const String detail='''> AssetBundle是一个抽象类,主要有以下方法 6 | 7 | ```dart 8 | //加载图片,返回二进制图片 9 | Future load(String key) 10 | //加载文本,cache是否使用缓存,返回String类型 11 | Future loadString(String key, { bool cache = true }) 12 | //加载结构化数据,parser进行检索值 13 | Future loadStructuredData(String key, Future parser(String value)) 14 | //清除缓存,下次重新在资源包中读取 15 | void evict(String key) 16 | ``` 17 | 18 | > 已实现AssetBundle的类有 19 | 20 | - NetworkAssetBundle 21 | 22 | - CachingAssetBundle -> PlatformAssetBundle 23 | 24 | ## NetworkAssetBundle 25 | > 用于加载网络资源,该类不会缓存任何资源 26 | ```dart 27 | //示例 28 | void loadNetWorkImage() async{ 29 | NetworkAssetBundle networkAssetBundle = NetworkAssetBundle(Uri.parse('http://img.zcool.cn/community/')); 30 | ByteData byteData = await networkAssetBundle.load('0117e2571b8b246ac72538120dd8a4.jpg@1280w_1l_2o_100sh.jpg'); 31 | } 32 | //上述最后会加载http://img.zcool.cn/community/0117e2571b8b246ac72538120dd8a4.jpg@1280w_1l_2o_100sh.jpg 33 | ``` 34 | 35 | ## CachingAssetBundle 36 | > 该类也是一个抽象类,封装了缓存方法,继承于AssetBundle ,实现于PlatformAssetBundle,只会缓存loadString()方法的字符串内容 37 | 38 | ## PlatformAssetBundle 39 | > 该类继承了CachingAssetBundle,重写了AssetBundle的一个方法load() 40 | ```dart 41 | //示例 42 | void loadCacheString() async{ 43 | PlatformAssetBundle platformAssetBundle=new PlatformAssetBundle(); 44 | ByteData byteData = await platformAssetBundle.load('images/burgers.jpg'); 45 | } 46 | //会加载项目下的images/burgers.jpg 文件,该文件需要在pubspec.yaml文件中声明 47 | ``` 48 | ## 注意 49 | 使用AssetBundle需要导入package:flutter/services.dart 包,rootBundle其实就是PlatformAssetBundle类的对象. 50 | '''; 51 | @override 52 | _AssetBundleDemoState createState() => _AssetBundleDemoState(); 53 | } 54 | 55 | class _AssetBundleDemoState extends MarkdownState { 56 | @override 57 | String getMarkdownSource() { 58 | return AssetBundleDemo.detail; 59 | } 60 | 61 | @override 62 | String getTitle() { 63 | return 'AssetBundle'; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /lib/widgets/async/aAsyncShow.dart: -------------------------------------------------------------------------------- 1 | export 'aFutureBuilder.dart'; 2 | export 'bStreamBuilder.dart'; 3 | -------------------------------------------------------------------------------- /lib/widgets/async/bStreamBuilder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | import 'dart:async'; 4 | import 'dart:math'; 5 | class StreamBuilderDemo extends StatefulWidget { 6 | static const String routeName = 'widgets/async/StreamBuilder'; 7 | final String detail = ''''''; 8 | 9 | @override 10 | _StreamBuilderDemoState createState() => _StreamBuilderDemoState(); 11 | } 12 | 13 | class _StreamBuilderDemoState extends ExampleState { 14 | final StreamController _controller = StreamController(); 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | } 20 | 21 | @override 22 | void dispose() { 23 | _controller.close(); 24 | super.dispose(); 25 | } 26 | 27 | @override 28 | String getDetail() { 29 | return widget.detail; 30 | } 31 | 32 | @override 33 | String getExampleCode() { 34 | return r''' final StreamController _controller = StreamController(); 35 | 36 | StreamBuilder( 37 | initialData: '', 38 | stream: _controller.stream, 39 | builder: (BuildContext context, AsyncSnapshot snapshot) { 40 | switch (snapshot.connectionState) { 41 | case ConnectionState.none: 42 | return Text('none:${snapshot.data}'); 43 | case ConnectionState.active: 44 | return Text('active:${snapshot.data}'); 45 | case ConnectionState.waiting: 46 | return Text('waiting:${snapshot.data}'); 47 | case ConnectionState.done: 48 | return Text('done:${snapshot.data}'); 49 | } 50 | }, 51 | ) 52 | 53 | //发送一条数据 54 | _controller.sink.add('data');'''; 55 | } 56 | 57 | List randomSeek=[ 58 | 'Flutter', 59 | 'IOS', 60 | 'Android', 61 | 'Dart', 62 | 'Java', 63 | 'Kotlin', 64 | 'Swift', 65 | 'Object-C', 66 | ]; 67 | @override 68 | List getSetting() { 69 | return [ 70 | ValueTitleButtonWidget( 71 | title: '点击发送一条数据', 72 | onPressed: () { 73 | _controller.sink.add(randomSeek[Random().nextInt(randomSeek.length)]); 74 | }, 75 | ) 76 | ]; 77 | } 78 | 79 | @override 80 | String getTitle() { 81 | return 'StreamBuilder'; 82 | } 83 | 84 | @override 85 | Widget getWidget() { 86 | return Center( 87 | child: StreamBuilder( 88 | initialData: '', 89 | stream: _controller.stream, 90 | builder: (BuildContext context, AsyncSnapshot snapshot) { 91 | switch (snapshot.connectionState) { 92 | case ConnectionState.none: 93 | return Text('none:${snapshot.data}'); 94 | case ConnectionState.active: 95 | return Text('active:${snapshot.data}'); 96 | case ConnectionState.waiting: 97 | return Text('waiting:${snapshot.data}'); 98 | case ConnectionState.done: 99 | return Text('done:${snapshot.data}'); 100 | } 101 | }, 102 | ), 103 | ); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/widgets/basics/aBasicesShow.dart: -------------------------------------------------------------------------------- 1 | export 'aContainer.dart'; 2 | export 'bRow.dart'; 3 | export 'cColumn.dart'; 4 | export 'dImage.dart'; 5 | export 'eText.dart'; 6 | export 'fIcon.dart'; 7 | export 'gRaisedButton.dart'; 8 | export 'hScaffold.dart'; 9 | export 'iAppBar.dart'; 10 | export 'jFlutterLogo.dart'; 11 | export 'kPlaceholder.dart'; -------------------------------------------------------------------------------- /lib/widgets/basics/fIcon.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class IconDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/basics/Icon'; 6 | final String detail = 7 | '''图形图标插件与来自于所述的字体的字形绘制IconData如材料的预定IconData以s 图标。 8 | 9 | 图标不是交互式的。对于交互式图标,请考虑材质的 IconButton。 10 | 11 | 使用Icon时必须有环境Directionality小部件。通常,这是由WidgetsApp或 MaterialApp自动引入的.'''; 12 | 13 | @override 14 | _IconDemoState createState() => _IconDemoState(); 15 | } 16 | 17 | class _IconDemoState extends ExampleState { 18 | IconSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = IconSetting( 23 | icon: Icons.arrow_back, 24 | semanticLabel: 'Icon Label', 25 | ); 26 | super.initState(); 27 | } 28 | 29 | @override 30 | String getDetail() { 31 | return widget.detail; 32 | } 33 | 34 | @override 35 | String getExampleCode() { 36 | return '''Icon( 37 | Icons.arrow_back, 38 | size: ${setting.size?.label??''}, 39 | color: ${setting.color?.label??''}, 40 | semanticLabel: 'Icon Label', 41 | textDirection: ${setting.textDirection?.label??''}, 42 | )'''; 43 | } 44 | 45 | @override 46 | List getSetting() { 47 | return [ 48 | ValueTitleWidget(StringParams.kTextDirection), 49 | RadioGroupWidget(setting.textDirection, textDirectionValues, (value){ 50 | setState(() { 51 | setting = setting.copyWith(textDirection: value); 52 | }); 53 | }), 54 | ValueTitleWidget(StringParams.kColor), 55 | ColorGroupWidget(setting.color, (value){ 56 | setState(() { 57 | setting = setting.copyWith(color: value); 58 | }); 59 | }), 60 | DropDownValueTitleWidget( 61 | selectList: sizeValues, 62 | title: StringParams.kSize, 63 | value: setting.size, 64 | onChanged: (value) { 65 | setState(() { 66 | setting = setting.copyWith(size: value); 67 | }); 68 | }, 69 | ), 70 | ]; 71 | } 72 | 73 | @override 74 | String getTitle() { 75 | return 'Icon'; 76 | } 77 | 78 | @override 79 | Widget getWidget() { 80 | return Center( 81 | child: Icon( 82 | setting.icon, 83 | size: setting.size?.value, 84 | color: setting.color?.value, 85 | semanticLabel: setting.semanticLabel, 86 | textDirection: setting.textDirection?.value, 87 | ), 88 | ); 89 | } 90 | } 91 | 92 | class IconSetting { 93 | final IconData icon; 94 | final String semanticLabel; 95 | Value size; 96 | Value color; 97 | Value textDirection; 98 | 99 | IconSetting( 100 | {this.icon, 101 | this.size, 102 | this.color, 103 | this.semanticLabel, 104 | this.textDirection}); 105 | 106 | IconSetting copyWith({ 107 | IconData icon, 108 | Value size, 109 | Value color, 110 | Value textDirection, 111 | String semanticLabel, 112 | }) { 113 | return IconSetting( 114 | icon: icon ?? this.icon, 115 | size: size ?? this.size, 116 | color: color ?? this.color, 117 | semanticLabel: semanticLabel ?? this.semanticLabel, 118 | textDirection: textDirection ?? this.textDirection, 119 | ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/aCupertinoActivityIndicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutterbyrhyme/code/example_code.dart'; 4 | class CupertinoActivityIndicatorDemo extends StatefulWidget { 5 | static const String routeName='widgets/cupertino/CupertinoActivityIndicator'; 6 | final String detail=''''iOS风格的活动指示器。'''; 7 | 8 | @override 9 | _CupertinoActivityIndicatorDemoState createState() => _CupertinoActivityIndicatorDemoState(); 10 | } 11 | 12 | class _CupertinoActivityIndicatorDemoState extends ExampleState { 13 | CupertinoActivityIndicatorSetting setting; 14 | 15 | @override 16 | void initState() { 17 | setting = CupertinoActivityIndicatorSetting( 18 | animating: boolValues[1], 19 | radius: doubleXlargeValues[0], 20 | ); 21 | super.initState(); 22 | } 23 | @override 24 | String getDetail() { 25 | return widget.detail; 26 | } 27 | 28 | @override 29 | String getExampleCode() { 30 | return '''CupertinoActivityIndicator( 31 | animating: ${setting.animating?.label??''}, 32 | radius: ${setting.radius?.label??''}, 33 | )'''; 34 | } 35 | 36 | @override 37 | List getSetting() { 38 | return [ 39 | SwitchValueTitleWidget(title: StringParams.kAnimating, value: setting.animating, onChanged: (value){ 40 | setState(() { 41 | setting=setting.copyWith(animating: value); 42 | }); 43 | }), 44 | DropDownValueTitleWidget(selectList: doubleXlargeValues, title: StringParams.kRadius, value: setting.radius, 45 | onChanged: (value){ 46 | setState(() { 47 | setting=setting.copyWith(radius: value); 48 | 49 | }); 50 | },) 51 | ]; 52 | } 53 | 54 | @override 55 | String getTitle() { 56 | return 'CupertinoActivityIndicator'; 57 | } 58 | 59 | @override 60 | Widget getWidget() { 61 | return Center( 62 | child: CupertinoActivityIndicator( 63 | animating: setting.animating?.value, 64 | radius: setting.radius?.value, 65 | ), 66 | ); 67 | } 68 | } 69 | 70 | class CupertinoActivityIndicatorSetting{ 71 | final Value animating ; 72 | final Value radius ; 73 | CupertinoActivityIndicatorSetting({this.animating, this.radius, }); 74 | 75 | CupertinoActivityIndicatorSetting copyWith({ 76 | Value animating , 77 | Value radius , 78 | }){ 79 | return CupertinoActivityIndicatorSetting( 80 | animating: animating??this.animating, 81 | radius: radius??this.radius, 82 | 83 | ); 84 | } 85 | } -------------------------------------------------------------------------------- /lib/widgets/cupertino/aaCupertinoShow.dart: -------------------------------------------------------------------------------- 1 | library cupertino; 2 | 3 | export 'aCupertinoActivityIndicator.dart'; 4 | export 'bCupertinoAlertDialog.dart'; 5 | export 'cCupertinoButton.dart'; 6 | export 'dCupertinoDialog.dart'; 7 | export 'eCupertinoDialogAction.dart'; 8 | export 'fCupertinoSlider.dart'; 9 | export 'gCupertinoSwitch.dart'; 10 | export 'hCupertinoPageTransition.dart'; 11 | export 'iCupertinoFullscreenDialogTransition.dart'; 12 | export 'jCupertinoNavigationBar.dart'; 13 | export 'kCupertinoTabBar.dart'; 14 | export 'lCupertinoPageScaffold.dart'; 15 | export 'mCupertinoTabScaffold.dart'; 16 | export 'nCupertinoTabView.dart'; 17 | export 'oCupertinoActionSheet.dart'; 18 | export 'pCupertinoSegmentedControl.dart'; 19 | export 'qCupertinoPicker.dart'; 20 | export 'rCupertinoTimerPicker.dart'; -------------------------------------------------------------------------------- /lib/widgets/cupertino/dCupertinoDialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoDialogDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoDialog'; 6 | final String detail = '''OS风格的对话框。 7 | 8 | 此对话框小部件对对话框的内容没有任何意见。不要直接使用这个小部件,而应考虑使用 CupertinoAlertDialog,它实现了一种特定的对话框。 9 | 10 | Navigator.of(..., rootNavigator: true)使用CupertinoTabScaffold时 按下以确保对话框出现在选项卡上方。'''; 11 | 12 | @override 13 | _CupertinoDialogDemoState createState() => _CupertinoDialogDemoState(); 14 | } 15 | 16 | class _CupertinoDialogDemoState extends ExampleState { 17 | CupertinoDialogSetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = CupertinoDialogSetting( 22 | child: Value( 23 | value: CupertinoActivityIndicator(radius: 25.0,), 24 | label: 'CupertinoActivityIndicator(radius: 25.0,)', 25 | ), 26 | barrierDismissible: boolValues[0], 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | String getDetail() { 33 | return widget.detail; 34 | } 35 | 36 | @override 37 | String getExampleCode() { 38 | return '''FlatButton( 39 | onPressed: () { 40 | showDialog( 41 | context: context, 42 | barrierDismissible: ${setting.barrierDismissible?.label??''}, 43 | builder: (BuildContext context) { 44 | return _getDialog(); 45 | }, 46 | ); 47 | }, 48 | child: Text('Show CupertinoDialog'), 49 | ) 50 | 51 | Widget _getDialog() { 52 | return CupertinoDialog( 53 | child: ${setting.child?.label??''}, 54 | ); 55 | }'''; 56 | } 57 | 58 | @override 59 | List getSetting() { 60 | return [ 61 | SwitchValueTitleWidget( 62 | title: StringParams.kBarrierDismissible, 63 | value: setting.barrierDismissible, 64 | onChanged: (value) { 65 | setState(() { 66 | setting = setting.copyWith(barrierDismissible: value); 67 | }); 68 | }), 69 | ]; 70 | } 71 | 72 | @override 73 | String getTitle() { 74 | return 'CupertinoDialog'; 75 | } 76 | 77 | Widget _getDialog() { 78 | return CupertinoDialog( 79 | child: setting.child?.value, 80 | ); 81 | } 82 | 83 | @override 84 | Widget getWidget() { 85 | return Center( 86 | child: FlatButton( 87 | onPressed: () { 88 | showDialog( 89 | context: context, 90 | barrierDismissible: setting.barrierDismissible?.value, 91 | builder: (BuildContext context) { 92 | return _getDialog(); 93 | }, 94 | ); 95 | }, 96 | child: Text('Show CupertinoDialog'), 97 | ), 98 | ); 99 | } 100 | } 101 | 102 | class CupertinoDialogSetting { 103 | final Value barrierDismissible; 104 | final Value child; 105 | 106 | CupertinoDialogSetting({ 107 | this.barrierDismissible, 108 | this.child, 109 | }); 110 | 111 | CupertinoDialogSetting copyWith({ 112 | Value barrierDismissible, 113 | Value child, 114 | }) { 115 | return CupertinoDialogSetting( 116 | barrierDismissible: barrierDismissible??this.barrierDismissible, 117 | child: child??this.child, 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/eCupertinoDialogAction.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoDialogActionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoDialogAction'; 6 | final String detail = '''通常用于CupertinoAlertDialog的按钮。'''; 7 | 8 | @override 9 | _CupertinoDialogActionDemoState createState() => 10 | _CupertinoDialogActionDemoState(); 11 | } 12 | 13 | class _CupertinoDialogActionDemoState 14 | extends ExampleState { 15 | CupertinoDialogActionSetting setting; 16 | 17 | @override 18 | void initState() { 19 | setting = CupertinoDialogActionSetting( 20 | onPressed: onPressValues[0], 21 | child: Value( 22 | value: Text('Action'), 23 | label: "Text('Action')", 24 | ), 25 | isDestructiveAction: boolValues[0], 26 | isDefaultAction: boolValues[0], 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | String getDetail() { 33 | return widget.detail; 34 | } 35 | 36 | @override 37 | String getExampleCode() { 38 | return '''CupertinoDialogAction( 39 | child: ${setting.child?.label??''}, 40 | onPressed: ${setting.onPressed?.label??''}, 41 | isDefaultAction: ${setting.isDefaultAction?.label??''}, 42 | isDestructiveAction: ${setting.isDestructiveAction?.label??''}, 43 | )'''; 44 | } 45 | 46 | @override 47 | List getSetting() { 48 | return [ 49 | ValueTitleWidget(StringParams.konPressed), 50 | RadioGroupWidget(setting.onPressed, onPressValues, (value){ 51 | setState(() { 52 | setting=setting.copyWith(onPressed: value); 53 | }); 54 | }), 55 | SwitchValueTitleWidget( 56 | title: StringParams.kIsDefaultAction, 57 | value: setting.isDefaultAction, 58 | onChanged: (value) { 59 | setState(() { 60 | setting = setting.copyWith(isDefaultAction: value); 61 | }); 62 | }), 63 | SwitchValueTitleWidget( 64 | title: StringParams.kIsDestructiveAction, 65 | value: setting.isDestructiveAction, 66 | onChanged: (value) { 67 | setState(() { 68 | setting = setting.copyWith(isDestructiveAction: value); 69 | }); 70 | }), 71 | ]; 72 | } 73 | 74 | @override 75 | String getTitle() { 76 | return 'CupertinoDialogAction'; 77 | } 78 | 79 | @override 80 | Widget getWidget() { 81 | return CupertinoDialogAction( 82 | child: setting.child?.value, 83 | onPressed: setting.onPressed?.value == null 84 | ? setting.onPressed?.value 85 | : () { 86 | setting.onPressed?.value(scaffoldKey); 87 | }, 88 | isDefaultAction: setting.isDefaultAction?.value, 89 | isDestructiveAction: setting.isDestructiveAction?.value, 90 | ); 91 | } 92 | } 93 | 94 | class CupertinoDialogActionSetting { 95 | final Value child; 96 | final Value>> onPressed; 97 | final Value isDefaultAction; 98 | final Value isDestructiveAction; 99 | 100 | CupertinoDialogActionSetting({ 101 | this.child, 102 | this.onPressed, 103 | this.isDefaultAction, 104 | this.isDestructiveAction, 105 | }); 106 | 107 | CupertinoDialogActionSetting copyWith({ 108 | Value child, 109 | Value>> onPressed, 110 | Value isDefaultAction, 111 | Value isDestructiveAction, 112 | }) { 113 | return CupertinoDialogActionSetting( 114 | child: child ?? this.child, 115 | onPressed: onPressed ?? this.onPressed, 116 | isDefaultAction: isDefaultAction ?? this.isDefaultAction, 117 | isDestructiveAction: isDestructiveAction ?? this.isDestructiveAction, 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/gCupertinoSwitch.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoSwitchDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoSwitch'; 6 | final String detail = '''iOS风格的开关。 7 | 8 | 用于切换单个设置的开/关状态。 9 | 10 | 交换机本身不保持任何状态。相反,当交换机的状态发生变化时,小部件会调用onChanged回调。大多数使用交换机的小部件将侦听onChanged回调并使用新值重建交换机以更新交换机的可视外观。'''; 11 | 12 | @override 13 | _CupertinoSwitchDemoState createState() => 14 | _CupertinoSwitchDemoState(); 15 | } 16 | 17 | class _CupertinoSwitchDemoState 18 | extends ExampleState { 19 | CupertinoSwitchSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = CupertinoSwitchSetting( 24 | value: boolValues[0], 25 | activeColor: Value( 26 | value: CupertinoColors.activeGreen, 27 | label: 'CupertinoColors.activeGreen', 28 | ), 29 | onChanged: Value( 30 | name: 'onChanged', 31 | value: (value) { 32 | setState(() { 33 | setting = setting.copyWith(value: boolValues[value ? 1 : 0]); 34 | }); 35 | }, 36 | label: '''(value) { 37 | setState(() { 38 | _value=value; 39 | }); 40 | }'''), 41 | ); 42 | super.initState(); 43 | } 44 | 45 | @override 46 | String getDetail() { 47 | return widget.detail; 48 | } 49 | 50 | @override 51 | String getExampleCode() { 52 | return '''bool _value=false; 53 | CupertinoSwitch( 54 | value: ${setting.value?.label??''}, 55 | onChanged: ${setting.onChanged?.label??''}, 56 | activeColor: ${setting.activeColor?.label??''}, 57 | )'''; 58 | } 59 | 60 | @override 61 | List getSetting() { 62 | return [ 63 | ValueTitleWidget(StringParams.kActiveColor), 64 | ColorGroupWidget(setting.activeColor, (value) { 65 | setState(() { 66 | setting = setting.copyWith(activeColor: value); 67 | }); 68 | }), 69 | SwitchValueTitleWidget( 70 | value: setting.value, 71 | title: StringParams.kValue, 72 | onChanged: (value) { 73 | setState(() { 74 | setting = setting.copyWith(value: value); 75 | }); 76 | }, 77 | ), 78 | ]; 79 | } 80 | 81 | @override 82 | String getTitle() { 83 | return 'CupertinoSwitch'; 84 | } 85 | 86 | 87 | @override 88 | Widget getWidget() { 89 | return Center( 90 | child: CupertinoSwitch( 91 | value: setting.value?.value, 92 | onChanged: setting.onChanged?.value, 93 | activeColor: setting.activeColor?.value, 94 | ), 95 | ); 96 | } 97 | } 98 | 99 | class CupertinoSwitchSetting { 100 | final Value value; 101 | final Value> onChanged; 102 | final Value activeColor; 103 | CupertinoSwitchSetting({ 104 | this.value, 105 | this.onChanged, 106 | this.activeColor, 107 | }); 108 | 109 | CupertinoSwitchSetting copyWith({ 110 | Value value, 111 | Value> onChanged, 112 | Value activeColor, 113 | }) { 114 | return CupertinoSwitchSetting( 115 | value: value ?? this.value, 116 | onChanged: onChanged ?? this.onChanged, 117 | activeColor: activeColor ?? this.activeColor, 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/hCupertinoPageTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoPageTransitionDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoPageTransition'; 6 | final String detail = '''提供iOS样式的页面过渡动画。 7 | 8 | 页面从右侧滑入,然后反向退出。当另一页进入以覆盖它时,它也以视差运动向左移动。'''; 9 | 10 | @override 11 | _CupertinoPageTransitionDemoState createState() => 12 | _CupertinoPageTransitionDemoState(); 13 | } 14 | 15 | class _CupertinoPageTransitionDemoState 16 | extends ExampleState 17 | with TickerProviderStateMixin { 18 | CupertinoPageTransitionSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = CupertinoPageTransitionSetting( 23 | child: Value( 24 | value: Text('CupertinoPageTransition'), 25 | label: "Text('CupertinoPageTransition')", 26 | ), 27 | primaryRouteAnimation: Value( 28 | value: kAlwaysCompleteAnimation, 29 | label: 'kAlwaysCompleteAnimation', 30 | ), 31 | secondaryRouteAnimation: Value( 32 | value: kAlwaysCompleteAnimation, 33 | label: 'kAlwaysCompleteAnimation', 34 | ), 35 | linearTransition: boolValues[0], 36 | ); 37 | super.initState(); 38 | } 39 | 40 | @override 41 | String getDetail() { 42 | return widget.detail; 43 | } 44 | 45 | @override 46 | String getExampleCode() { 47 | return '''CupertinoPageTransition( 48 | primaryRouteAnimation: ${setting.primaryRouteAnimation?.label??''}, 49 | secondaryRouteAnimation: ${setting.secondaryRouteAnimation?.label??''}, 50 | child: ${setting.child?.label??''}, 51 | linearTransition: ${setting.linearTransition?.label??''}, 52 | )'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return [ 58 | SwitchValueTitleWidget( 59 | value: setting.linearTransition, 60 | title: StringParams.kLinearTransition, 61 | onChanged: (value) { 62 | setState(() { 63 | setting = setting.copyWith(linearTransition: value); 64 | }); 65 | }, 66 | ), 67 | ]; 68 | } 69 | 70 | @override 71 | String getTitle() { 72 | return 'CupertinoPageTransition'; 73 | } 74 | 75 | @override 76 | Widget getWidget() { 77 | return Center( 78 | child: CupertinoPageTransition( 79 | primaryRouteAnimation: setting.primaryRouteAnimation?.value, 80 | secondaryRouteAnimation: setting.secondaryRouteAnimation?.value, 81 | child: setting.child?.value, 82 | linearTransition: setting.linearTransition?.value, 83 | ), 84 | ); 85 | } 86 | } 87 | 88 | class CupertinoPageTransitionSetting { 89 | final Value> primaryRouteAnimation; 90 | final Value> secondaryRouteAnimation; 91 | final Value child; 92 | final Value linearTransition; 93 | 94 | CupertinoPageTransitionSetting({ 95 | this.primaryRouteAnimation, 96 | this.secondaryRouteAnimation, 97 | this.child, 98 | this.linearTransition, 99 | }); 100 | 101 | CupertinoPageTransitionSetting copyWith({ 102 | Value> primaryRouteAnimation, 103 | Value> secondaryRouteAnimation, 104 | Value child, 105 | Value linearTransition, 106 | }) { 107 | return CupertinoPageTransitionSetting( 108 | primaryRouteAnimation: 109 | primaryRouteAnimation ?? this.primaryRouteAnimation, 110 | secondaryRouteAnimation: 111 | secondaryRouteAnimation ?? this.secondaryRouteAnimation, 112 | child: child ?? this.child, 113 | linearTransition: linearTransition ?? this.linearTransition, 114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/iCupertinoFullscreenDialogTransition.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoFullscreenDialogTransitionDemo extends StatefulWidget { 5 | static const String routeName = 6 | 'widgets/cupertino/CupertinoFullscreenDialogTransition'; 7 | final String detail = '''用于召唤全屏对话框的iOS风格转换。 8 | 9 | 例如,通过从底部引入下一个屏幕来创建新日历事件时使用。'''; 10 | 11 | @override 12 | _CupertinoFullscreenDialogTransitionDemoState createState() => 13 | _CupertinoFullscreenDialogTransitionDemoState(); 14 | } 15 | 16 | class _CupertinoFullscreenDialogTransitionDemoState 17 | extends ExampleState { 18 | CupertinoFullscreenDialogTransitionSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = CupertinoFullscreenDialogTransitionSetting( 23 | primaryRouteAnimation: Value( 24 | value: kAlwaysCompleteAnimation, 25 | label: 'kAlwaysCompleteAnimation', 26 | ), 27 | secondaryRouteAnimation: Value( 28 | value: kAlwaysCompleteAnimation, 29 | label: 'kAlwaysCompleteAnimation', 30 | ), 31 | linearTransition: Value( 32 | name: 'true', 33 | value: true, 34 | label: 'true', 35 | ), 36 | child: Value( 37 | value: Text('FullscreenDialog'), 38 | label: "Text('FullscreenDialog')", 39 | )); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | String getDetail() { 45 | return widget.detail; 46 | } 47 | 48 | @override 49 | String getExampleCode() { 50 | return '''CupertinoFullscreenDialogTransition( 51 | secondaryRouteAnimation: ${setting.secondaryRouteAnimation?.label ?? ''}, 52 | primaryRouteAnimation: ${setting.primaryRouteAnimation?.label ?? ''}, 53 | linearTransition: ${setting.linearTransition?.label ?? ''}, 54 | child: ${setting.child?.label ?? ''}, 55 | )'''; 56 | } 57 | 58 | @override 59 | List getSetting() { 60 | return []; 61 | } 62 | 63 | @override 64 | String getTitle() { 65 | return 'CupertinoFullscreenDialogTransition'; 66 | } 67 | 68 | @override 69 | Widget getWidget() { 70 | return Center( 71 | child: CupertinoFullscreenDialogTransition( 72 | secondaryRouteAnimation: setting.secondaryRouteAnimation?.value, 73 | primaryRouteAnimation: setting.primaryRouteAnimation?.value, 74 | linearTransition: setting.linearTransition?.value, 75 | child: setting.child?.value, 76 | ), 77 | ); 78 | } 79 | } 80 | 81 | class CupertinoFullscreenDialogTransitionSetting { 82 | final Value> secondaryRouteAnimation; 83 | final Value> primaryRouteAnimation; 84 | final Value linearTransition; 85 | final Value child; 86 | 87 | CupertinoFullscreenDialogTransitionSetting( 88 | {this.secondaryRouteAnimation, 89 | this.primaryRouteAnimation, 90 | this.linearTransition, 91 | this.child}); 92 | 93 | CupertinoFullscreenDialogTransitionSetting copyWith({ 94 | Value> secondaryRouteAnimation, 95 | Value> primaryRouteAnimation, 96 | bool linearTransition, 97 | Value child, 98 | }) { 99 | return CupertinoFullscreenDialogTransitionSetting( 100 | secondaryRouteAnimation: 101 | secondaryRouteAnimation ?? this.secondaryRouteAnimation, 102 | primaryRouteAnimation: 103 | primaryRouteAnimation ?? this.primaryRouteAnimation, 104 | linearTransition: linearTransition ?? this.linearTransition, 105 | child: child ?? this.child, 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/lCupertinoPageScaffold.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoPageScaffoldDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoPageScaffold'; 6 | final String detail = '''实现单个iOS应用程序页面的布局。 7 | 8 | 脚手架在顶部布置导航栏,在导航栏之间或之后布置内容。 9 | '''; 10 | 11 | @override 12 | _CupertinoPageScaffoldDemoState createState() => 13 | _CupertinoPageScaffoldDemoState(); 14 | } 15 | 16 | class _CupertinoPageScaffoldDemoState 17 | extends ExampleState { 18 | CupertinoPageScaffoldSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = CupertinoPageScaffoldSetting( 23 | child: Value( 24 | value: Center(child: Text('Body')), 25 | label: "Center(child: Text('Body'))", 26 | ) , 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | String getDetail() { 33 | return widget.detail; 34 | } 35 | 36 | @override 37 | String getExampleCode() { 38 | return '''CupertinoPageScaffold( 39 | child: ${setting.child?.label??''}, 40 | navigationBar: ${setting.navigationBar?.label??''}, 41 | backgroundColor: ${setting.backgroundColor?.label??''}, 42 | )'''; 43 | } 44 | 45 | @override 46 | List getSetting() { 47 | return [ 48 | ValueTitleButtonWidget( 49 | title: StringParams.kNavigationBar, 50 | onPressed: () async { 51 | dynamic changeValue= await Navigator.pushNamed(context, 'widgets/cupertino/CupertinoNavigationBar'); 52 | if(changeValue!=null){ 53 | setState(() { 54 | setting=setting.copyWith(navigationBar: changeValue); 55 | }); 56 | } 57 | }, 58 | ), 59 | ValueTitleWidget(StringParams.kBackgroundColor), 60 | ColorGroupWidget(setting.backgroundColor, (value) { 61 | setState(() { 62 | setting = setting.copyWith(backgroundColor: value); 63 | }); 64 | }), 65 | ]; 66 | } 67 | 68 | @override 69 | String getTitle() { 70 | return 'CupertinoPageScaffold'; 71 | } 72 | 73 | @override 74 | Widget getWidget() { 75 | return CupertinoPageScaffold( 76 | child: setting.child?.value, 77 | navigationBar: setting.navigationBar?.value, 78 | backgroundColor: setting.backgroundColor?.value, 79 | ); 80 | } 81 | } 82 | 83 | class CupertinoPageScaffoldSetting { 84 | final Value navigationBar; 85 | final Value backgroundColor; 86 | final Value child; 87 | 88 | CupertinoPageScaffoldSetting({ 89 | this.navigationBar, 90 | this.backgroundColor, 91 | this.child, 92 | }); 93 | 94 | CupertinoPageScaffoldSetting copyWith({ 95 | Value navigationBar, 96 | Value backgroundColor, 97 | Value child, 98 | }) { 99 | return CupertinoPageScaffoldSetting( 100 | navigationBar: navigationBar??this.navigationBar, 101 | backgroundColor: backgroundColor??this.backgroundColor, 102 | child: child??this.child, 103 | ); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/widgets/cupertino/mCupertinoTabScaffold.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CupertinoTabScaffoldDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/CupertinoTabScaffold'; 6 | final String detail = '''实现选项卡式iOS应用程序的根布局和行为结构。 7 | 8 | 支架布置底部的标签栏和标签栏之间或之后的内容。 9 | 10 | 需要tabBar和tabBuilder。该CupertinoTabScaffold 会自动监听提供CupertinoTabBar的自来水回调更改活动标签。 11 | 12 | 选项卡的内容是使用活动选项卡索引处提供的tabBuilder构建的。该tabBuilder必须能够建立相同数量的网页,因为有tabBar.items。非活动选项卡将移至Offstage, 并禁用其动画。 13 | 14 | 使用CupertinoTabView作为每个选项卡的内容,以支持具有并行导航状态和历史记录的选项卡。'''; 15 | 16 | @override 17 | _CupertinoTabScaffoldDemoState createState() => 18 | _CupertinoTabScaffoldDemoState(); 19 | } 20 | 21 | class _CupertinoTabScaffoldDemoState 22 | extends ExampleState { 23 | CupertinoTabScaffoldSetting setting; 24 | 25 | @override 26 | void initState() { 27 | setting = CupertinoTabScaffoldSetting( 28 | tabBar: Value( 29 | value: CupertinoTabBar( 30 | items: bottomNavigationBarItemValues[0].value, 31 | currentIndex: 0, 32 | ), 33 | label: '''CupertinoTabBar( 34 | items: bottomNavigationBarItemValues[0].value, 35 | currentIndex: 0, 36 | )'''), 37 | tabBuilder: Value( 38 | value: (BuildContext context, int index) { 39 | return Center( 40 | child: Text('Tab No. $index'), 41 | ); 42 | }, 43 | label: '''(BuildContext context, int index) { 44 | return Center( 45 | child: Text('Tab No. \$index'), 46 | ); 47 | }''', 48 | )); 49 | super.initState(); 50 | } 51 | 52 | @override 53 | String getDetail() { 54 | return widget.detail; 55 | } 56 | 57 | @override 58 | String getExampleCode() { 59 | return '''CupertinoTabScaffold( 60 | tabBuilder: ${setting.tabBuilder?.label??''}, 61 | tabBar: ${setting.tabBar?.label??''}, 62 | )'''; 63 | } 64 | 65 | @override 66 | List getSetting() { 67 | return [ 68 | Center(child: Text('无参数选,请看示例代码!')), 69 | ]; 70 | } 71 | 72 | @override 73 | String getTitle() { 74 | return 'CupertinoTabScaffold'; 75 | } 76 | 77 | @override 78 | Widget getWidget() { 79 | return CupertinoTabScaffold( 80 | tabBuilder: setting.tabBuilder?.value, 81 | tabBar: setting.tabBar?.value, 82 | ); 83 | } 84 | } 85 | 86 | class CupertinoTabScaffoldSetting { 87 | final Value tabBar; 88 | final Value tabBuilder; 89 | 90 | CupertinoTabScaffoldSetting({ 91 | this.tabBar, 92 | this.tabBuilder, 93 | }); 94 | 95 | CupertinoTabScaffoldSetting copyWith({ 96 | Value tabBar, 97 | Value tabBuilder, 98 | }) { 99 | return CupertinoTabScaffoldSetting( 100 | tabBar: tabBar ?? this.tabBar, 101 | tabBuilder: tabBuilder ?? this.tabBuilder, 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widgets/input/aaInputShow.dart: -------------------------------------------------------------------------------- 1 | export 'aForm.dart'; 2 | export 'bFormField.dart'; 3 | export 'cRawKeyboardListener.dart'; -------------------------------------------------------------------------------- /lib/widgets/interaction/aInteractionShow.dart: -------------------------------------------------------------------------------- 1 | export 'aLongPressDraggable.dart'; 2 | export 'bGestureDetector.dart'; 3 | export 'cDragTarget.dart'; 4 | export 'dDismissible.dart'; 5 | export 'eIgnorePointer.dart'; 6 | export 'fAbsorbPointer.dart'; 7 | export 'gNavigator.dart'; 8 | export 'hScrollable.dart'; -------------------------------------------------------------------------------- /lib/widgets/interaction/eIgnorePointer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class IgnorePointerDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/interaction/IgnorePointer'; 6 | final String detail = '''在命中测试期间不可见的小部件。 7 | 8 | 如果忽略为true,则此窗口小部件(及其子树)对于命中测试是不可见的。它仍然会在布局过程中消耗空间并像往常一样对孩子进行绘画。它只是不能成为找到事件的目标,因为它从RenderBox.hitTest返回false 。 9 | 10 | 当忽略语义为真时,子树对于语义层是不可见的(因此例如可访问性工具)。如果 ignoringSemantics为null,它使用的值忽略。'''; 11 | 12 | @override 13 | _IgnorePointerDemoState createState() => _IgnorePointerDemoState(); 14 | } 15 | 16 | class _IgnorePointerDemoState extends ExampleState { 17 | IgnorePointerSetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = IgnorePointerSetting( 22 | child: Value( 23 | value: GestureDetector(onTap:(){exampleKey.currentState.showToast('点击');},child: Image.asset('images/burgers.jpg')), 24 | label: "GestureDetector(onTap:(){exampleKey.currentState.showToast('点击');},child: Image.asset('images/burgers.jpg'))", 25 | ), 26 | ignoring: boolValues[0], 27 | ignoringSemantics: boolValues[0], 28 | ); 29 | super.initState(); 30 | } 31 | 32 | @override 33 | String getDetail() { 34 | return widget.detail; 35 | } 36 | 37 | @override 38 | String getExampleCode() { 39 | return '''IgnorePointer( 40 | ignoring: ${setting.ignoring?.label??''}, 41 | ignoringSemantics: ${setting.ignoringSemantics?.label??''}, 42 | child: ${setting.child?.label??''}, 43 | )'''; 44 | } 45 | 46 | @override 47 | List getSetting() { 48 | 49 | return [ 50 | SwitchValueTitleWidget( 51 | title: StringParams.kIgnoring, 52 | value: setting.ignoring, 53 | onChanged: (value) { 54 | setState(() { 55 | setting = setting.copyWith(ignoring: value); 56 | }); 57 | }), 58 | SwitchValueTitleWidget( 59 | title: StringParams.kIgnoringSemantics, 60 | value: setting.ignoringSemantics, 61 | onChanged: (value) { 62 | setState(() { 63 | setting = setting.copyWith(ignoringSemantics: value); 64 | }); 65 | }), 66 | ]; 67 | } 68 | 69 | @override 70 | String getTitle() { 71 | return 'IgnorePointer'; 72 | } 73 | 74 | @override 75 | Widget getWidget() { 76 | return IgnorePointer( 77 | ignoring: setting.ignoring?.value, 78 | ignoringSemantics: setting.ignoringSemantics?.value, 79 | child: setting.child?.value, 80 | ); 81 | } 82 | } 83 | 84 | class IgnorePointerSetting { 85 | final Value ignoring; 86 | final Value ignoringSemantics; 87 | final Value child; 88 | 89 | IgnorePointerSetting({this.ignoring, this.ignoringSemantics, this.child}); 90 | 91 | IgnorePointerSetting copyWith({ 92 | Value ignoring, 93 | Value ignoringSemantics, 94 | Value child, 95 | }) { 96 | return IgnorePointerSetting( 97 | ignoring: ignoring ?? this.ignoring, 98 | ignoringSemantics: ignoringSemantics ?? this.ignoringSemantics, 99 | child: child ?? this.child, 100 | ); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /lib/widgets/interaction/fAbsorbPointer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class AbsorbPointerDemo extends StatefulWidget { 4 | static const String routeName = 'widgets/interaction/AbsorbPointer'; 5 | final String detail = '''在命中测试期间吸收指针的小部件。 6 | 7 | 当吸收为真时,此小部件通过终止命中测试来阻止其子树接收指针事件。它仍然会在布局过程中消耗空间并像往常一样对孩子进行绘画。它只是阻止它的子节点成为定位事件的目标,因为它从RenderBox.hitTest返回true 。'''; 8 | 9 | @override 10 | _AbsorbPointerDemoState createState() => 11 | _AbsorbPointerDemoState(); 12 | } 13 | 14 | class _AbsorbPointerDemoState 15 | extends ExampleState { 16 | AbsorbPointerSetting setting; 17 | 18 | @override 19 | void initState() { 20 | setting = AbsorbPointerSetting(child: Value( 21 | value: GestureDetector(onTap:(){exampleKey.currentState.showToast('点击');},child: Image.asset('images/burgers.jpg')), 22 | label: "GestureDetector(onTap:(){exampleKey.currentState.showToast('点击');},child: Image.asset('images/burgers.jpg'))", 23 | ), 24 | absorbing: boolValues[0], 25 | ignoringSemantics: boolValues[0],); 26 | super.initState(); 27 | } 28 | 29 | @override 30 | String getDetail() { 31 | return widget.detail; 32 | } 33 | 34 | @override 35 | String getExampleCode() { 36 | return '''AbsorbPointer( 37 | ignoring: ${setting.absorbing?.label??''}, 38 | ignoringSemantics: ${setting.ignoringSemantics?.label??''}, 39 | child: ${setting.child?.label??''}, 40 | )'''; 41 | } 42 | 43 | @override 44 | List getSetting() { 45 | return [ 46 | SwitchValueTitleWidget( 47 | title: StringParams.kAbsorbing, 48 | value: setting.absorbing, 49 | onChanged: (value) { 50 | setState(() { 51 | setting = setting.copyWith(absorbing: value); 52 | }); 53 | }), 54 | SwitchValueTitleWidget( 55 | title: StringParams.kIgnoringSemantics, 56 | value: setting.ignoringSemantics, 57 | onChanged: (value) { 58 | setState(() { 59 | setting = setting.copyWith(ignoringSemantics: value); 60 | }); 61 | }), 62 | ]; 63 | } 64 | 65 | @override 66 | String getTitle() { 67 | return 'AbsorbPointer'; 68 | } 69 | 70 | 71 | @override 72 | Widget getWidget() { 73 | return AbsorbPointer( 74 | absorbing: setting.absorbing?.value, 75 | ignoringSemantics: setting.ignoringSemantics?.value, 76 | child: setting.child?.value,); 77 | } 78 | } 79 | 80 | class AbsorbPointerSetting { 81 | final Value absorbing; 82 | final Value ignoringSemantics; 83 | final Value child; 84 | 85 | AbsorbPointerSetting({this.absorbing, this.ignoringSemantics, this.child}); 86 | 87 | AbsorbPointerSetting copyWith({ 88 | Value absorbing, 89 | Value ignoringSemantics, 90 | Value child, 91 | }) { 92 | 93 | return AbsorbPointerSetting( 94 | absorbing: absorbing ?? this.absorbing, 95 | ignoringSemantics: ignoringSemantics ?? this.ignoringSemantics, 96 | child: child ?? this.child, 97 | ); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/widgets/layout/aLayoutShow.dart: -------------------------------------------------------------------------------- 1 | export 'aPadding.dart'; 2 | export 'bCenter.dart'; 3 | export 'cAlign.dart'; 4 | export 'dFittedBox.dart'; 5 | export 'eAspectRatio.dart'; 6 | export 'fConstrainedBox.dart'; 7 | export 'gBaseline.dart'; 8 | export 'hFractionallySizedBox.dart'; 9 | export 'iIntrinsicHeight.dart'; 10 | export 'jIntrinsicWidth.dart'; 11 | export 'kLimitedBox.dart'; 12 | export 'lOffstage.dart'; 13 | export 'mOverflowBox.dart'; 14 | export 'nSizedBox.dart'; 15 | export 'oSizedOverflowBox.dart'; 16 | export 'pTransform.dart'; 17 | export 'qCustomSingleChildLayout.dart'; 18 | 19 | 20 | export 'tStack.dart'; 21 | export 'uIndexedStack.dart'; 22 | export 'vFlow.dart'; 23 | export 'wTable.dart'; 24 | export 'xWrap.dart'; 25 | export 'yListBody.dart'; 26 | export 'zaListView.dart'; 27 | export 'zbCustomMultiChildLayout.dart'; 28 | export 'zcLayoutBuilder.dart'; -------------------------------------------------------------------------------- /lib/widgets/layout/aPadding.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class PaddingDemo extends StatefulWidget { 4 | static const String routeName = 'widgets/layout/Padding'; 5 | final String detail = '''> Padding的构造方法 6 | ```dart 7 | const Padding({ 8 | Key key, 9 | @required this.padding, 10 | Widget child, 11 | }) : assert(padding != null), 12 | super(key: key, child: child); 13 | ``` 14 | |类型| 参数 | 解析| 15 | |-|-|-| 16 | | Key|key|传递给父类| 17 | |EdgeInsetsGeometry|padding| 必传的参数,内边距| 18 | |Widget | child | 传递给父类,需要添加内边距的子widget| 19 | 20 | > EdgeInsetsGeometry使用内置的方法添加内边距 21 | 22 | ```dart 23 | //1 24 | const EdgeInsets.symmetric({ double vertical = 0.0, 25 | double horizontal = 0.0 }); 26 | //2 27 | const EdgeInsets.only({ 28 | this.left = 0.0, 29 | this.top = 0.0, 30 | this.right = 0.0, 31 | this.bottom = 0.0 32 | }); 33 | //3 34 | const EdgeInsets.all(double value); 35 | //4 36 | const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom); 37 | //5 38 | EdgeInsets.fromWindowPadding(ui.WindowPadding padding, double devicePixelRatio) 39 | //6 40 | EdgeInsets.lerp(EdgeInsets a, EdgeInsets b, double t) 41 | //7 42 | EdgeInsets.zero 43 | //8 44 | const EdgeInsetsDirectional.fromSTEB(start, top, end, bottom); 45 | //9 46 | const EdgeInsetsDirectional.only({ 47 | this.start = 0.0, 48 | this.top = 0.0, 49 | this.end = 0.0, 50 | this.bottom = 0.0 51 | }); 52 | ```'''; 53 | 54 | @override 55 | _PaddingDemoState createState() => 56 | _PaddingDemoState(); 57 | } 58 | 59 | class _PaddingDemoState 60 | extends MarkdownState { 61 | 62 | @override 63 | String getMarkdownSource() { 64 | return widget.detail; 65 | } 66 | 67 | @override 68 | String getTitle() { 69 | return 'Padding'; 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /lib/widgets/layout/bCenter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CenterDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/Center'; 6 | final String detail = '''一个小孩,它将孩子置于其中心。 7 | 8 | 如果它的尺寸受到约束并且widthFactor和heightFactor为null,则此窗口小部件将尽可能大 。如果维度不受约束且相应的大小因子为null,则窗口小部件将匹配其在该维度中的子项大小。如果尺寸因子为非null,则此窗口小部件的相应尺寸将是子尺寸和尺寸因子的乘积。例如,如果widthFactor是2.0,那么此小部件的宽度将始终是其子宽度的两倍。'''; 9 | 10 | @override 11 | _CenterDemoState createState() => _CenterDemoState(); 12 | } 13 | 14 | class _CenterDemoState extends ExampleState { 15 | CenterSetting setting; 16 | 17 | @override 18 | void initState() { 19 | setting = CenterSetting( 20 | widthFactor: doubleMiniValues[0], 21 | heightFactor: doubleMiniValues[0], 22 | child: _formatValue(), 23 | ); 24 | super.initState(); 25 | } 26 | 27 | 28 | Widget _formatWidget(){ 29 | return Center( 30 | widthFactor: setting?.widthFactor?.value??null, 31 | heightFactor: setting?.heightFactor?.value??null, 32 | child: Container( 33 | alignment: Alignment.center, 34 | color: Colors.grey, 35 | child: SizedBox( 36 | width: 35.0, 37 | height: 35.0, 38 | child: DecoratedBox( 39 | decoration: BoxDecoration(color: Colors.blue), 40 | ), 41 | ), 42 | ), 43 | ); 44 | } 45 | 46 | String _formatLabel(){ 47 | return '''Center( 48 | widthFactor: ${setting?.widthFactor?.label??''}, 49 | heightFactor: ${setting?.heightFactor?.label??''}, 50 | child: Container( 51 | alignment: Alignment.center, 52 | color: Colors.grey, 53 | child: SizedBox( 54 | width: 35.0, 55 | height: 35.0, 56 | child: DecoratedBox( 57 | decoration: BoxDecoration(color: Colors.blue), 58 | ), 59 | ), 60 | ), 61 | )'''; 62 | } 63 | 64 | Value _formatValue(){ 65 | return Value( 66 | value: _formatWidget(), 67 | label: _formatLabel(), 68 | ); 69 | } 70 | 71 | @override 72 | String getDetail() { 73 | return widget.detail; 74 | } 75 | 76 | @override 77 | String getExampleCode() { 78 | return setting?.child?.label; 79 | } 80 | 81 | @override 82 | List getSetting() { 83 | return [ 84 | ValueTitleWidget(StringParams.kWidthFactor), 85 | SeekBarGroupWidget(setting.widthFactor, (value){ 86 | setting=setting.copyWith(widthFactor: value); 87 | setState(() { 88 | setting=setting.copyWith(child: _formatValue()); 89 | }); 90 | },max: 2.0,min: 0.0,), 91 | ValueTitleWidget(StringParams.kHeightFactor), 92 | SeekBarGroupWidget(setting.heightFactor, (value){ 93 | setting=setting.copyWith(heightFactor: value); 94 | setState(() { 95 | setting=setting.copyWith(child: _formatValue()); 96 | }); 97 | },max: 2.0,min: 0.0,), 98 | ]; 99 | } 100 | 101 | @override 102 | String getTitle() { 103 | return 'Center'; 104 | } 105 | 106 | 107 | @override 108 | Widget getWidget() { 109 | return setting.child?.value; 110 | } 111 | } 112 | 113 | class CenterSetting { 114 | final Value widthFactor; 115 | final Value heightFactor; 116 | final Value child; 117 | 118 | CenterSetting({ 119 | this.heightFactor, 120 | this.widthFactor, 121 | this.child, 122 | }); 123 | 124 | CenterSetting copyWith({ 125 | Value widthFactor, 126 | Value heightFactor, 127 | Value child, 128 | 129 | }) { 130 | return CenterSetting( 131 | widthFactor: widthFactor ?? this.widthFactor, 132 | heightFactor: heightFactor ?? this.heightFactor, 133 | child: child??this.child, 134 | ); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /lib/widgets/layout/dFittedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class FittedBoxDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/FittedBox'; 6 | final String detail = 7 | '''秤,并根据自身内部定位其子契合。'''; 8 | 9 | @override 10 | _FittedBoxDemoState createState() => _FittedBoxDemoState(); 11 | } 12 | 13 | class _FittedBoxDemoState extends ExampleState { 14 | FittedBoxSetting setting; 15 | 16 | @override 17 | void initState() { 18 | setting = FittedBoxSetting( 19 | fit: fitValues[0], 20 | alignment: alignmentValues[0], 21 | child: Value( 22 | value: SizedBox( 23 | width: 35.0, 24 | height: 35.0, 25 | child: DecoratedBox( 26 | decoration: BoxDecoration(color: Colors.blue), 27 | ), 28 | ), 29 | label: '''SizedBox( 30 | width: 35.0, 31 | height: 35.0, 32 | child: DecoratedBox( 33 | decoration: BoxDecoration(color: Theme.of(context).primaryColor), 34 | ), 35 | )''', 36 | ), 37 | ); 38 | super.initState(); 39 | } 40 | 41 | @override 42 | String getDetail() { 43 | return widget.detail; 44 | } 45 | 46 | @override 47 | String getExampleCode() { 48 | return '''FittedBox( 49 | fit: ${setting.fit?.label ?? ''}, 50 | alignment: ${setting.alignment?.label ?? ''}, 51 | child: ${setting.child?.label ?? ''}, 52 | );'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return [ 58 | ValueTitleWidget(StringParams.kFit), 59 | RadioGroupWidget(setting.fit, fitValues, (value) { 60 | setState(() { 61 | setting = setting.copyWith(fit: value); 62 | }); 63 | }), 64 | ValueTitleWidget(StringParams.kAlignment), 65 | RadioGroupWidget(setting.alignment, alignmentValues, (value) { 66 | setState(() { 67 | setting = setting.copyWith(alignment: value); 68 | }); 69 | }), 70 | ]; 71 | } 72 | 73 | @override 74 | String getTitle() { 75 | return 'FittedBox'; 76 | } 77 | 78 | @override 79 | Widget getWidget() { 80 | return FittedBox( 81 | fit: setting.fit?.value, 82 | alignment: setting.alignment?.value, 83 | child: setting.child?.value, 84 | ); 85 | } 86 | } 87 | 88 | class FittedBoxSetting { 89 | final Value fit; 90 | final Value alignment; 91 | final Value child; 92 | 93 | FittedBoxSetting({ 94 | this.fit, 95 | this.alignment, 96 | this.child, 97 | }); 98 | 99 | FittedBoxSetting copyWith({ 100 | Value fit, 101 | Value alignment, 102 | Value child, 103 | }) { 104 | return FittedBoxSetting( 105 | fit: fit ?? this.fit, 106 | alignment: alignment ?? this.alignment, 107 | child: child ?? this.child, 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/widgets/layout/eAspectRatio.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class AspectRatioDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/cupertino/AspectRatio'; 6 | final String detail = '''尝试将子项调整为特定宽高比的小部件。 7 | 8 | 小部件首先尝试布局约束允许的最大宽度。小部件的高度通过将给定的宽高比应用于宽度来确定,表示为宽度与高度的比率。 9 | 10 | 例如,16:9宽度:高度纵横比的值为16.0 / 9.0。如果最大宽度为无穷大,则通过将纵横比应用于最大高度来确定初始宽度。 11 | 12 | 现在考虑第二个例子,这次宽高比为2.0,布局约束要求宽度介于0.0和100.0之间,高度介于0.0和100.0之间。我们将选择宽度为100.0(允许的最大值)和50.0的高度(以匹配宽高比)。 13 | 14 | 在相同的情况下,如果纵横比为0.5,我们还将选择宽度100.0(仍然是允许的最大值),我们将尝试使用200.0的高度。不幸的是,这违反了限制,因为孩子的身高最高可达100.0像素。然后,窗口小部件将获取该值并再次应用宽高比以获得50.0的宽度。约束允许该宽度,子项的宽度为50.0,高度为100.0。如果不允许宽度,则窗口小部件将继续迭代约束。如果在查阅每个约束之后窗口小部件找不到可行的大小,则窗口小部件最终将选择满足布局约束但不满足宽高比约束的子窗口的大小。'''; 15 | 16 | @override 17 | _AspectRatioDemoState createState() => 18 | _AspectRatioDemoState(); 19 | } 20 | 21 | class _AspectRatioDemoState 22 | extends ExampleState { 23 | AspectRatioSetting setting; 24 | 25 | @override 26 | void initState() { 27 | setting = AspectRatioSetting( 28 | aspectRatio: doubleAspectValue[0], 29 | child: Value( 30 | value: SizedBox( 31 | width: 35.0, 32 | height: 35.0, 33 | child: DecoratedBox( 34 | decoration: BoxDecoration(color: Colors.blue), 35 | ), 36 | ), 37 | label: '''SizedBox( 38 | width: 35.0, 39 | height: 35.0, 40 | child: DecoratedBox( 41 | decoration: BoxDecoration(color: Theme.of(context).primaryColor), 42 | ), 43 | )''', 44 | ), 45 | ); 46 | super.initState(); 47 | } 48 | 49 | @override 50 | String getDetail() { 51 | return widget.detail; 52 | } 53 | 54 | @override 55 | String getExampleCode() { 56 | return '''AspectRatio( 57 | aspectRatio: ${setting.aspectRatio?.label??''}, 58 | child: ${setting.child?.label??''}, 59 | )'''; 60 | } 61 | 62 | @override 63 | List getSetting() { 64 | return [ 65 | ValueTitleWidget(StringParams.kAspectRatio), 66 | RadioGroupWidget(setting.aspectRatio, doubleAspectValue, (value) { 67 | setState(() { 68 | setting = setting.copyWith(aspectRatio: value); 69 | }); 70 | }), 71 | ]; 72 | } 73 | 74 | @override 75 | String getTitle() { 76 | return 'AspectRatio'; 77 | } 78 | 79 | 80 | @override 81 | Widget getWidget() { 82 | return AspectRatio( 83 | aspectRatio: setting.aspectRatio?.value, 84 | child: setting.child?.value, 85 | ); 86 | } 87 | } 88 | 89 | class AspectRatioSetting { 90 | final Value aspectRatio; 91 | final Value child; 92 | 93 | AspectRatioSetting({ 94 | this.aspectRatio, 95 | this.child, 96 | }); 97 | AspectRatioSetting copyWith({ 98 | Value aspectRatio, 99 | Value child, 100 | }) { 101 | return AspectRatioSetting( 102 | aspectRatio: aspectRatio??this.aspectRatio, 103 | child: child??this.child, 104 | ); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /lib/widgets/layout/fConstrainedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class ConstrainedBoxDemo extends StatefulWidget { 4 | static const String routeName = 'widgets/layout/ConstrainedBox'; 5 | final String detail = '''一个小部件,对其子级施加其他约束。 6 | 7 | 例如,如果您希望子级的最小高度为50.0逻辑像素,则可以将其const BoxConstraints(minHeight: 50.0)用作 约束。'''; 8 | 9 | @override 10 | _ConstrainedBoxDemoState createState() => 11 | _ConstrainedBoxDemoState(); 12 | } 13 | 14 | class _ConstrainedBoxDemoState 15 | extends ExampleState { 16 | ConstrainedBoxSetting setting; 17 | 18 | @override 19 | void initState() { 20 | setting = ConstrainedBoxSetting( 21 | constraints: constraintValues[0], 22 | child: _formatValue(), 23 | ); 24 | super.initState(); 25 | } 26 | 27 | Widget _formatWidget(){ 28 | return ConstrainedBox( 29 | constraints: setting?.constraints?.value??constraintValues[0].value, 30 | child: SizedBox( 31 | width: 35.0, 32 | height: 35.0, 33 | child: DecoratedBox( 34 | decoration: BoxDecoration(color: Colors.blue), 35 | ), 36 | ), 37 | ); 38 | } 39 | 40 | String _formatLabel(){ 41 | return '''ConstrainedBox( 42 | constraints: ${setting?.constraints?.label??constraintValues[0].label}, 43 | child: SizedBox( 44 | width: 35.0, 45 | height: 35.0, 46 | child: DecoratedBox( 47 | decoration: BoxDecoration(color: Colors.blue), 48 | ), 49 | ), 50 | )'''; 51 | } 52 | 53 | Value _formatValue(){ 54 | return Value( 55 | value: _formatWidget(), 56 | label: _formatLabel(), 57 | ); 58 | } 59 | 60 | @override 61 | String getDetail() { 62 | return widget.detail; 63 | } 64 | 65 | @override 66 | String getExampleCode() { 67 | return setting.child?.label; 68 | } 69 | 70 | @override 71 | List getSetting() { 72 | return [ 73 | ValueTitleWidget(StringParams.kConstraints), 74 | RadioGroupWidget(setting.constraints, constraintValues, (value) { 75 | setting = setting.copyWith(constraints: value); 76 | setState(() { 77 | setting=setting.copyWith(child: _formatValue()); 78 | }); 79 | }), 80 | ]; 81 | } 82 | 83 | @override 84 | String getTitle() { 85 | return 'ConstrainedBox'; 86 | } 87 | 88 | 89 | @override 90 | Widget getWidget() { 91 | return ConstrainedBox( 92 | constraints: setting.constraints?.value, 93 | child: setting.child?.value, 94 | ); 95 | } 96 | } 97 | 98 | class ConstrainedBoxSetting { 99 | final Value constraints; 100 | final Value child; 101 | ConstrainedBoxSetting({ 102 | this.constraints, 103 | this.child, 104 | }); 105 | ConstrainedBoxSetting copyWith({ 106 | Value constraints, 107 | Value child, 108 | }) { 109 | return ConstrainedBoxSetting( 110 | constraints: constraints??this.constraints, 111 | child: child??this.child, 112 | ); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /lib/widgets/layout/gBaseline.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class BaselineDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/Baseline'; 6 | final String detail = 7 | '''根据孩子的基线定位孩子的小部件。 8 | 9 | 此窗口小部件将子项向下移动,使子项的基线(或子项的底部,如果子项没有基线)是 此框顶部下方的基线逻辑像素,然后调整此框的大小以包含子项。如果基线小于从孩子的顶部到孩子的基线的距离,则孩子是顶部对齐的。'''; 10 | 11 | @override 12 | _BaselineDemoState createState() => _BaselineDemoState(); 13 | } 14 | 15 | class _BaselineDemoState extends ExampleState { 16 | BaselineSetting setting; 17 | 18 | @override 19 | void initState() { 20 | setting = BaselineSetting( 21 | baseline: doubleXlargeValues[0], 22 | baselineType: TextBaselineValues[0], 23 | child: Value( 24 | value: SizedBox( 25 | width: 35.0, 26 | height: 35.0, 27 | child: DecoratedBox( 28 | decoration: BoxDecoration(color: Colors.blue), 29 | ), 30 | ), 31 | label: '''SizedBox( 32 | width: 35.0, 33 | height: 35.0, 34 | child: DecoratedBox( 35 | decoration: BoxDecoration(color: Theme.of(context).primaryColor), 36 | ), 37 | )''', 38 | ), 39 | ); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | String getDetail() { 45 | return widget.detail; 46 | } 47 | 48 | @override 49 | String getExampleCode() { 50 | return '''Baseline( 51 | baselineType: ${setting.baselineType.label ?? ''}, 52 | baseline: ${setting.baseline?.label ?? ''}, 53 | child: ${setting.child?.label ?? ''}, 54 | )'''; 55 | } 56 | 57 | @override 58 | List getSetting() { 59 | return [ 60 | ValueTitleWidget(StringParams.kTextBaseline), 61 | RadioGroupWidget(setting.baselineType, TextBaselineValues, (value) { 62 | setState(() { 63 | setting = setting.copyWith(baselineType: value); 64 | }); 65 | }), 66 | DropDownValueTitleWidget( 67 | selectList: doubleXlargeValues, 68 | title: StringParams.kBaseline, 69 | value: setting.baseline, 70 | onChanged: (value) { 71 | setState(() { 72 | setting = setting.copyWith(baseline: value); 73 | }); 74 | }, 75 | ), 76 | ]; 77 | } 78 | 79 | @override 80 | String getTitle() { 81 | return 'Baseline'; 82 | } 83 | 84 | @override 85 | Widget getWidget() { 86 | return Baseline( 87 | baselineType: setting.baselineType.value, 88 | baseline: setting.baseline?.value, 89 | child: setting.child?.value, 90 | ); 91 | } 92 | } 93 | 94 | class BaselineSetting { 95 | final Value child; 96 | final Value baselineType; 97 | final Value baseline; 98 | 99 | BaselineSetting( 100 | {@required this.baseline, @required this.baselineType, this.child}); 101 | 102 | BaselineSetting copyWith({ 103 | Value child, 104 | Value baselineType, 105 | Value baseline, 106 | }) { 107 | return BaselineSetting( 108 | child: child ?? this.child, 109 | baseline: baseline ?? this.baseline, 110 | baselineType: baselineType ?? this.baselineType, 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /lib/widgets/layout/iIntrinsicHeight.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class IntrinsicHeightDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/IntrinsicHeight'; 6 | final String detail = '''一个小部件,可以将其子级调整为子级的内在高度。 7 | 8 | 这个类非常有用,例如,当无限高度可用时,你想要一个孩子,否则他们会尝试无限扩展,而不是将自己的大小调整到更合理的高度。 9 | 10 | 这个类相对昂贵,因为它在最终布局阶段之前添加了一个推测布局传递。尽可能避免使用它。在最坏的情况下,这个小部件可以导致树的深度为O(N²)的布局。'''; 11 | 12 | @override 13 | _IntrinsicHeightDemoState createState() => 14 | _IntrinsicHeightDemoState(); 15 | } 16 | 17 | class _IntrinsicHeightDemoState extends ExampleState { 18 | IntrinsicHeightSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = IntrinsicHeightSetting( 23 | child: Value( 24 | value: SizedBox( 25 | width: 35.0, 26 | height: 35.0, 27 | child: DecoratedBox( 28 | decoration: BoxDecoration(color: Colors.blue), 29 | ), 30 | ), 31 | label: '''SizedBox( 32 | width: 35.0, 33 | height: 35.0, 34 | child: DecoratedBox( 35 | decoration: BoxDecoration(color: Theme.of(context).primaryColor), 36 | ), 37 | )''', 38 | ), 39 | ); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | String getDetail() { 45 | return widget.detail; 46 | } 47 | 48 | @override 49 | String getExampleCode() { 50 | return '''IntrinsicHeight( 51 | child: ${setting.child?.label??''}, 52 | )'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return []; 58 | } 59 | 60 | @override 61 | String getTitle() { 62 | return 'IntrinsicHeight'; 63 | } 64 | 65 | 66 | @override 67 | Widget getWidget() { 68 | return IntrinsicHeight( 69 | child: setting.child?.value, 70 | ); 71 | } 72 | } 73 | 74 | class IntrinsicHeightSetting { 75 | final Value child; 76 | 77 | IntrinsicHeightSetting({ 78 | this.child, 79 | }); 80 | 81 | IntrinsicHeightSetting copyWith({ 82 | Value child, 83 | }) { 84 | return IntrinsicHeightSetting( 85 | child: child ?? this.child, 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/widgets/layout/kLimitedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class LimitedBoxDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/LimitedBox'; 6 | final String detail = '''只有当它不受约束时才限制其大小的盒子。 7 | 8 | 如果此窗口小部件的最大宽度不受约束,则其子窗口的宽度将限制为maxWidth。同样,如果此窗口小部件的最大高度不受约束,则其子窗口的高度将限制为maxHeight。 9 | 10 | 这具有使儿童在无界环境中具有自然维度的效果。例如,通过向通常尝试尽可能大的窗口小部件提供maxHeight,窗口小部件通常会调整其大小以适合其父窗口,但是当放置在垂直列表中时,它将采用给定的高度。 11 | 12 | 这在编写通常尝试匹配其父项大小的小部件时很有用,这样它们在列表中是合理的行为(无限制)。'''; 13 | 14 | @override 15 | _LimitedBoxDemoState createState() => 16 | _LimitedBoxDemoState(); 17 | } 18 | 19 | class _LimitedBoxDemoState extends ExampleState { 20 | LimitedBoxSetting setting; 21 | 22 | @override 23 | void initState() { 24 | setting = LimitedBoxSetting( 25 | maxHeight: doubleXlargeValues[0], 26 | maxWidth: doubleXlargeValues[0], 27 | child: Value( 28 | value: SizedBox.expand( 29 | child: DecoratedBox( 30 | decoration: BoxDecoration(color: Colors.blue), 31 | ), 32 | ), 33 | label: '''SizedBox.expand( 34 | child: DecoratedBox( 35 | decoration: BoxDecoration(color: Colors.blue), 36 | ), 37 | )''', 38 | ), 39 | ); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | String getDetail() { 45 | return widget.detail; 46 | } 47 | 48 | @override 49 | String getExampleCode() { 50 | return '''LimitedBox( 51 | maxWidth: ${setting.maxWidth?.label??''}, 52 | maxHeight: ${setting.maxHeight?.label??''}, 53 | child:${setting.child?.label??''}, 54 | )'''; 55 | } 56 | 57 | @override 58 | List getSetting() { 59 | return [ 60 | DropDownValueTitleWidget( 61 | selectList: doubleXlargeValues, 62 | title: StringParams.kMaxWidth, 63 | value: setting.maxWidth, 64 | onChanged: (value) { 65 | setState(() { 66 | setting = setting.copyWith(maxWidth: value); 67 | // setting=setting.copyWith(child: _formatValue()); 68 | }); 69 | }, 70 | ), 71 | DropDownValueTitleWidget( 72 | selectList: doubleXlargeValues, 73 | title: StringParams.kMaxHeight, 74 | value: setting.maxHeight, 75 | onChanged: (value) { 76 | setState(() { 77 | setting = setting.copyWith(maxHeight: value); 78 | // setting=setting.copyWith(child: _formatValue()); 79 | }); 80 | }, 81 | ), 82 | ]; 83 | } 84 | 85 | @override 86 | String getTitle() { 87 | return 'LimitedBox'; 88 | } 89 | 90 | 91 | @override 92 | Widget getWidget() { 93 | return LimitedBox( 94 | maxWidth: setting.maxWidth?.value, 95 | maxHeight: setting.maxHeight?.value, 96 | child:setting.child?.value, 97 | ); 98 | } 99 | } 100 | 101 | class LimitedBoxSetting { 102 | final Value maxWidth; 103 | final Value maxHeight; 104 | final Value child; 105 | 106 | LimitedBoxSetting({this.maxWidth, this.maxHeight, this.child, 107 | }); 108 | 109 | LimitedBoxSetting copyWith 110 | ({ 111 | Value maxWidth, 112 | Value maxHeight, 113 | Value child, 114 | }) { 115 | return LimitedBoxSetting( 116 | maxWidth: maxWidth??this.maxWidth, 117 | maxHeight: maxHeight??this.maxHeight, 118 | child: child??this.child, 119 | ); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /lib/widgets/layout/lOffstage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | class OffstageDemo extends StatefulWidget { 4 | static const String routeName = 'widgets/layout/Offstage'; 5 | final String detail = '''一个小部件,它将孩子放在树中,但没有绘制任何东西,没有让孩子可用于命中测试,也没有占用父母的任何空间。 6 | 7 | 动画继续在舞台上的孩子中运行,因此无论动画最终是否可见,都会使用电池和CPU时间。 8 | 9 | 可以使用Offstage来测量小部件的尺寸,而无需将其带到屏幕上(尚未)。要在不需要的情况下隐藏窗口小部件,请更喜欢从树中完全删除窗口小部件,而不是将其保留在Offstage子树中。'''; 10 | 11 | @override 12 | _OffstageDemoState createState() => 13 | _OffstageDemoState(); 14 | } 15 | 16 | class _OffstageDemoState 17 | extends ExampleState { 18 | OffstageSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = OffstageSetting( 23 | offstage: boolValues[0], 24 | child: Value( 25 | value: SizedBox.fromSize( 26 | size: Size(35.0, 35.0), 27 | child: DecoratedBox( 28 | decoration: BoxDecoration(color: Colors.blue), 29 | ), 30 | ), 31 | label: '''SizedBox.fromSize( 32 | size: Size(35.0, 35.0), 33 | child: DecoratedBox( 34 | decoration: BoxDecoration(color: Colors.blue), 35 | ), 36 | )''', 37 | ), 38 | ); 39 | super.initState(); 40 | } 41 | 42 | @override 43 | String getDetail() { 44 | return widget.detail; 45 | } 46 | 47 | @override 48 | String getExampleCode() { 49 | return '''Offstage( 50 | offstage: ${setting.offstage.label??''}, 51 | child: ${setting.child.label??''}, 52 | )'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return [ 58 | SwitchValueTitleWidget(title: StringParams.kOffstage, value: setting.offstage, onChanged: (value){ 59 | setState(() { 60 | setting=setting.copyWith(offstage: value); 61 | }); 62 | }) 63 | ]; 64 | } 65 | 66 | @override 67 | String getTitle() { 68 | return 'Offstage'; 69 | } 70 | 71 | 72 | @override 73 | Widget getWidget() { 74 | return Center( 75 | child: Offstage( 76 | offstage: setting.offstage.value, 77 | child: setting.child.value, 78 | ), 79 | ); 80 | } 81 | } 82 | 83 | class OffstageSetting { 84 | final Value offstage; 85 | final Value child; 86 | 87 | OffstageSetting({ 88 | this.child, 89 | this.offstage, 90 | }); 91 | 92 | OffstageSetting copyWith({ 93 | Value offstage, 94 | Value child, 95 | }) { 96 | return OffstageSetting( 97 | offstage: offstage??this.offstage, 98 | child: child??this.child, 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/widgets/layout/nSizedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | 5 | class SizedBoxDemo extends StatefulWidget { 6 | static const String routeName = 'widgets/layout/SizedBox'; 7 | final String detail = '''具有指定大小的框。 8 | 9 | 如果给孩子,这个小部件会强制其子项具有特定的宽度和/或高度(假设此小部件的父级允许值)。如果宽度或高度为null,则此窗口小部件将自行调整大小以匹配该维度中子项的大小。 10 | 11 | 如果没有给孩子,这个小部件将自己调整到给定的宽度和高度,将空值视为零。 12 | 13 | 该新SizedBox.expand构造可以用来制造SizedBox该尺寸本身,以适应父。它相当于将宽度和 高度设置为double.infinity。'''; 14 | 15 | @override 16 | _SizedBoxDemoState createState() => 17 | _SizedBoxDemoState(); 18 | } 19 | 20 | class _SizedBoxDemoState 21 | extends ExampleState { 22 | SizedBoxSetting setting; 23 | 24 | @override 25 | void initState() { 26 | setting = SizedBoxSetting( 27 | width: doubleXlargeValues[0], 28 | height: doubleXlargeValues[0], 29 | child: Value( 30 | value: DecoratedBox( 31 | decoration: BoxDecoration(color: Colors.blue), 32 | ), 33 | label: '''DecoratedBox( 34 | decoration: BoxDecoration(color: Colors.blue), 35 | )''', 36 | ) 37 | ); 38 | super.initState(); 39 | } 40 | 41 | @override 42 | String getDetail() { 43 | return widget.detail; 44 | } 45 | 46 | @override 47 | String getExampleCode() { 48 | return '''SizedBox( 49 | width: ${setting.width?.label??''}, 50 | height: ${setting.height?.label??''}, 51 | child: ${setting.child?.label??''}, 52 | )'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return [ 58 | DropDownValueTitleWidget( 59 | selectList: doubleXlargeValues, 60 | title: StringParams.kWidth, 61 | value: setting.width, 62 | onChanged: (value) { 63 | setState(() { 64 | setting = setting.copyWith(width: value); 65 | }); 66 | }, 67 | ), 68 | DropDownValueTitleWidget( 69 | selectList: doubleXlargeValues, 70 | title: StringParams.kHeight, 71 | value: setting.height, 72 | onChanged: (value) { 73 | setState(() { 74 | setting = setting.copyWith(height: value); 75 | }); 76 | }, 77 | ), 78 | ]; 79 | } 80 | 81 | @override 82 | String getTitle() { 83 | return 'SizedBox'; 84 | } 85 | 86 | @override 87 | Widget getWidget() { 88 | return Center( 89 | child: SizedBox( 90 | width: setting.width?.value, 91 | height: setting.height?.value, 92 | child: setting.child?.value, 93 | ), 94 | ); 95 | } 96 | } 97 | 98 | class SizedBoxSetting { 99 | final Value width; 100 | final Value height; 101 | final Value child; 102 | SizedBoxSetting({ 103 | this.width, 104 | this.height, 105 | this.child, 106 | }); 107 | 108 | SizedBoxSetting copyWith({ 109 | Value width, 110 | Value height, 111 | Value child, 112 | }) { 113 | return SizedBoxSetting( 114 | width: width??this.width, 115 | height: height??this.height, 116 | child: child??this.child, 117 | ); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /lib/widgets/layout/qCustomSingleChildLayout.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CustomSingleChildLayoutDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/CustomSingleChildLayout'; 6 | final String detail = '''一个小部件,将其单个子级的布局推迟到委托。 7 | 8 | 代表可以确定孩子的布局约束,并可以决定孩子的位置。委托还可以确定父级的大小,但父级的大小不能取决于子级的大小。'''; 9 | 10 | @override 11 | _CustomSingleChildLayoutDemoState createState() => 12 | _CustomSingleChildLayoutDemoState(); 13 | } 14 | 15 | class _CustomSingleChildLayoutDemoState 16 | extends ExampleState { 17 | CustomSingleChildLayoutSetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = CustomSingleChildLayoutSetting( 22 | delegate: Value( 23 | value: _SingleChildDelegate(), 24 | label: '_SingleChildDelegate()', 25 | ), 26 | child: Value( 27 | value: Text('CustomSingleChildLayout'), 28 | label: "Text('CustomSingleChildLayout')", 29 | ) 30 | ); 31 | super.initState(); 32 | } 33 | 34 | @override 35 | String getDetail() { 36 | return widget.detail; 37 | } 38 | 39 | @override 40 | String getExampleCode() { 41 | return '''CustomSingleChildLayout( 42 | delegate: ${setting.delegate?.label??''}, 43 | child: ${setting.child?.label??''}, 44 | ) 45 | 46 | //自定义布局代理 47 | class _SingleChildDelegate extends SingleChildLayoutDelegate{ 48 | const _SingleChildDelegate(); 49 | 50 | @override //设置子Widget约束 51 | BoxConstraints getConstraintsForChild(BoxConstraints constraints) { 52 | return constraints.tighten(height: kToolbarHeight); 53 | } 54 | 55 | @override//设置大小 56 | Size getSize(BoxConstraints constraints) { 57 | return new Size(constraints.maxWidth, kToolbarHeight); 58 | } 59 | 60 | @override//偏移 61 | Offset getPositionForChild(Size size, Size childSize) { 62 | return new Offset(10.0, size.height - childSize.height); 63 | } 64 | 65 | @override//是否应该重新布局 66 | bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) => false; 67 | }'''; 68 | } 69 | 70 | @override 71 | List getSetting() { 72 | return []; 73 | } 74 | 75 | @override 76 | String getTitle() { 77 | return 'CustomSingleChildLayout'; 78 | } 79 | 80 | @override 81 | Widget getWidget() { 82 | return CustomSingleChildLayout( 83 | delegate: setting.delegate?.value, 84 | child: setting.child?.value, 85 | ); 86 | } 87 | } 88 | 89 | class CustomSingleChildLayoutSetting { 90 | final Value delegate; 91 | final Value child; 92 | 93 | CustomSingleChildLayoutSetting({@required this.delegate, this.child}); 94 | 95 | CustomSingleChildLayoutSetting copyWith({ 96 | Value delegate, 97 | Value child, 98 | }) { 99 | return CustomSingleChildLayoutSetting( 100 | delegate: delegate ?? this.delegate, 101 | child: child ?? this.child, 102 | ); 103 | } 104 | } 105 | 106 | 107 | class _SingleChildDelegate extends SingleChildLayoutDelegate{ 108 | const _SingleChildDelegate(); 109 | 110 | @override //设置子Widget约束 111 | BoxConstraints getConstraintsForChild(BoxConstraints constraints) { 112 | return constraints.tighten(height: kToolbarHeight); 113 | } 114 | 115 | @override//设置大小 116 | Size getSize(BoxConstraints constraints) { 117 | return new Size(constraints.maxWidth, kToolbarHeight); 118 | } 119 | 120 | @override//偏移 121 | Offset getPositionForChild(Size size, Size childSize) { 122 | return new Offset(10.0, size.height - childSize.height); 123 | } 124 | 125 | @override//是否应该重新布局 126 | bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) => false; 127 | } -------------------------------------------------------------------------------- /lib/widgets/layout/vFlow.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class FlowDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/Flow'; 6 | final String detail = '''根据FlowDelegate中的逻辑,可以有效地调整和定位子项的小部件。 7 | 8 | 优化流布局以使用转换矩阵重新定位子项。 9 | 10 | 通过委托的FlowDelegate.getSize函数,流容器的大小独立于子容器 。然后根据FlowDelegate.getConstraintsForChild函数的约束,独立调整子项的大小 。 11 | 12 | 不是在布局期间定位子项,而是使用FlowDelegate.paintChildren函数中的矩阵在绘制阶段使用变换矩阵定位子项。通过简单地重新绘制流动就可以有效地重新定位孩子,这种情况在孩子不再被布置的情况下发生(与Stack相反,在布局期间进行尺寸调整和定位)。 13 | 14 | 触发重绘流的最有效方法是向FlowDelegate的构造函数提供动画。流动将监听此动画并在动画滴答时重新绘制,从而避免管道的构建和布局阶段。'''; 15 | 16 | @override 17 | _FlowDemoState createState() => 18 | _FlowDemoState(); 19 | } 20 | 21 | class _FlowDemoState 22 | extends ExampleState { 23 | FlowSetting setting; 24 | 25 | @override 26 | void initState() { 27 | setting = FlowSetting( 28 | delegate: Value( 29 | value: _MyFlowDelegate(), 30 | label: '_MyFlowDelegate()', 31 | ), 32 | children: Value( 33 | value: [ 34 | Image.asset('images/chewCrispyChicken.9.jpg'), 35 | Image.asset('images/burgers.jpg'), 36 | Image.asset('images/pazzer.jpg'), 37 | ] 38 | ) 39 | ); 40 | super.initState(); 41 | } 42 | 43 | @override 44 | String getDetail() { 45 | return widget.detail; 46 | } 47 | 48 | @override 49 | String getExampleCode() { 50 | return '''Flow(delegate: ${setting.delegate?.label??''}, 51 | children: ${setting.children?.label??''}, 52 | ) 53 | 54 | class _MyFlowDelegate extends FlowDelegate{ 55 | @override 56 | void paintChildren(FlowPaintingContext context) { 57 | //有多少个子Widget 58 | int count=context.childCount; 59 | for(int i=0;i false; 68 | }'''; 69 | } 70 | 71 | @override 72 | List getSetting() { 73 | return []; 74 | } 75 | 76 | @override 77 | String getTitle() { 78 | return 'Flow'; 79 | } 80 | 81 | 82 | @override 83 | Widget getWidget() { 84 | return Flow(delegate: setting.delegate?.value, 85 | children: setting.children?.value, 86 | ); 87 | } 88 | } 89 | 90 | class FlowSetting { 91 | final Value delegate; 92 | final Value> children; 93 | 94 | FlowSetting({ 95 | @required this.delegate, 96 | this.children 97 | }); 98 | 99 | FlowSetting copyWith({ 100 | Value delegate, 101 | Value> children, 102 | }) { 103 | return FlowSetting( 104 | delegate: delegate??this.delegate, 105 | children: children??this.children, 106 | ); 107 | } 108 | } 109 | 110 | class _MyFlowDelegate extends FlowDelegate{ 111 | @override 112 | void paintChildren(FlowPaintingContext context) { 113 | //有多少个子Widget 114 | int count=context.childCount; 115 | for(int i=0;i false; 123 | } -------------------------------------------------------------------------------- /lib/widgets/layout/yListBody.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class ListBodyDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/ListBody'; 6 | final String detail = '''一个小部件,它沿着给定的轴顺序排列它的子节点,强制它们到另一个轴的父节点的维度。 7 | 8 | 这个小部件很少直接使用。相反,可以考虑使用ListView,它将类似的布局算法与滚动行为相结合,或者使用 Column,它可以更灵活地控制垂直方框的布局。'''; 9 | 10 | @override 11 | _ListBodyDemoState createState() => _ListBodyDemoState(); 12 | } 13 | 14 | class _ListBodyDemoState extends ExampleState { 15 | ListBodySetting setting; 16 | 17 | @override 18 | void initState() { 19 | setting = ListBodySetting( 20 | mainAxis: axisValues[1], 21 | reverse: boolValues[0], 22 | children: Value( 23 | value: [ 24 | Text('I'), 25 | Text('❤'), 26 | Text('Love'), 27 | Text('❤'), 28 | Text('Flutter'), 29 | Text('❤'), 30 | Text('And'), 31 | Text('❤'), 32 | Text('Dart'), 33 | ], 34 | ) 35 | ); 36 | super.initState(); 37 | } 38 | 39 | @override 40 | String getDetail() { 41 | return widget.detail; 42 | } 43 | 44 | @override 45 | String getExampleCode() { 46 | return '''SingleChildScrollView( 47 | scrollDirection: ${setting.mainAxis?.label??''}, 48 | child: ListBody( 49 | mainAxis: ${setting.mainAxis?.label??''}, 50 | reverse: ${setting.reverse?.label??''}, 51 | children: ${setting.children?.label??''}, 52 | ), 53 | )'''; 54 | } 55 | 56 | @override 57 | List getSetting() { 58 | return [ 59 | ValueTitleWidget(StringParams.kMainAxis), 60 | RadioGroupWidget(setting.mainAxis, axisValues, (value) { 61 | setState(() { 62 | setting = setting.copyWith(mainAxis: value); 63 | }); 64 | }), 65 | SwitchValueTitleWidget(title: StringParams.kReverse, value: setting.reverse, onChanged: (value){ 66 | setState(() { 67 | setting = setting.copyWith(reverse: value); 68 | }); 69 | }), 70 | 71 | ]; 72 | } 73 | 74 | @override 75 | String getTitle() { 76 | return 'ListBody'; 77 | } 78 | 79 | @override 80 | Widget getWidget() { 81 | return SingleChildScrollView( 82 | scrollDirection: setting.mainAxis?.value, 83 | child: ListBody( 84 | mainAxis: setting.mainAxis?.value, 85 | reverse: setting.reverse?.value, 86 | children: setting.children?.value, 87 | ), 88 | ); 89 | } 90 | } 91 | 92 | class ListBodySetting { 93 | final Value mainAxis; 94 | final Value reverse; 95 | final Value> children; 96 | 97 | ListBodySetting({ 98 | this.mainAxis, 99 | this.reverse, 100 | this.children, 101 | }); 102 | 103 | ListBodySetting copyWith({ 104 | Value mainAxis, 105 | Value reverse, 106 | Value> children, 107 | }) { 108 | return ListBodySetting( 109 | mainAxis: mainAxis ?? this.mainAxis, 110 | reverse: reverse ?? this.reverse, 111 | children: children ?? this.children, 112 | ); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /lib/widgets/layout/zcLayoutBuilder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class LayoutBuilderDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/layout/LayoutBuilder'; 6 | final String detail = '''构建可依赖于父窗口小部件大小的窗口小部件树。 7 | 8 | 与Builder小部件类似,只是框架 在布局时调用构建器函数并提供父小部件的约束。当父约束孩子的大小而不依赖于孩子的内在大小时,这很有用。该LayoutBuilder的最终规模将匹配其孩子的大小。 9 | 10 | 如果子项应小于父项,请考虑将子项包装在“ 对齐”小组件中。如果孩子可能想要变大,可以考虑将其包装在SingleChildScrollView中。'''; 11 | 12 | @override 13 | _LayoutBuilderDemoState createState() => 14 | _LayoutBuilderDemoState(); 15 | } 16 | 17 | class _LayoutBuilderDemoState 18 | extends ExampleState { 19 | LayoutBuilderSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = LayoutBuilderSetting( 24 | builder: Value( 25 | value: (BuildContext context, BoxConstraints constraints) { 26 | //边距 27 | double margin=5.0; 28 | //父容器的大小 29 | Size parentSize=constraints.biggest; 30 | //父容器的宽 31 | double width = parentSize.width; 32 | //父容器的高 33 | double height= parentSize.height; 34 | Widget body=SizedBox( 35 | width: width-margin, 36 | height: height-margin, 37 | child: DecoratedBox(decoration: BoxDecoration( 38 | color: Colors.grey, 39 | )), 40 | ); 41 | return body; 42 | }, 43 | label: '''(BuildContext context, BoxConstraints constraints) { 44 | //边距 45 | double margin=5.0; 46 | //父容器的大小 47 | Size parentSize=constraints.biggest; 48 | //父容器的宽 49 | double width = parentSize.width; 50 | //父容器的高 51 | double height= parentSize.height; 52 | Widget body=SizedBox( 53 | width: width-margin, 54 | height: height-margin, 55 | child: DecoratedBox(decoration: BoxDecoration( 56 | color: Colors.grey, 57 | )), 58 | ); 59 | return body; 60 | }''', 61 | ) 62 | ); 63 | super.initState(); 64 | } 65 | 66 | @override 67 | String getDetail() { 68 | return widget.detail; 69 | } 70 | 71 | @override 72 | String getExampleCode() { 73 | return '''LayoutBuilder( 74 | builder: ${setting.builder?.label??''}, 75 | );'''; 76 | } 77 | 78 | @override 79 | List getSetting() { 80 | return []; 81 | } 82 | 83 | @override 84 | String getTitle() { 85 | return 'LayoutBuilder'; 86 | } 87 | 88 | 89 | @override 90 | Widget getWidget() { 91 | return LayoutBuilder( 92 | builder: setting.builder?.value, 93 | ); 94 | } 95 | } 96 | 97 | class LayoutBuilderSetting { 98 | final Value builder; 99 | 100 | LayoutBuilderSetting({ 101 | this.builder, 102 | }); 103 | 104 | LayoutBuilderSetting copyWith({ 105 | final Value builder, 106 | }) { 107 | return LayoutBuilderSetting( 108 | builder: builder??this.builder, 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /lib/widgets/material/aMaterialShow.dart: -------------------------------------------------------------------------------- 1 | export 'cBottomNavigationBar.dart'; 2 | export 'dTabBar.dart'; 3 | export 'eTabBarView.dart'; 4 | export 'fMaterialApp.dart'; 5 | export 'gWidgetsApp.dart'; 6 | export 'hDrawer.dart'; 7 | export 'jFloatingActionButton.dart'; 8 | export 'kFlatButton.dart'; 9 | export 'lIconButton.dart'; 10 | export 'mPopupMenuButton.dart'; 11 | export 'nButtonBar.dart'; 12 | export 'oTextField.dart'; 13 | export 'pCheckBox.dart'; 14 | export 'qRadio.dart'; 15 | export 'rSwitch.dart'; 16 | export 'sSlider.dart'; 17 | export 'tDate&TimePickers.dart'; 18 | export 'uSimpleDialog.dart'; 19 | export 'vAlertDialog.dart'; 20 | export 'wBottomSheet.dart'; 21 | export 'xExpansionPanel.dart'; 22 | export 'ySnackBar.dart'; 23 | export 'zcChip.dart'; 24 | export 'zdTooltip.dart'; 25 | export 'zeDataTable.dart'; 26 | export 'zfCard.dart'; 27 | export 'zgLinearProgressIndicator.dart'; 28 | export 'zhListTile.dart'; 29 | export 'ziStepper.dart'; 30 | export 'zjDivider.dart'; -------------------------------------------------------------------------------- /lib/widgets/material/eTabBarView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class TabBarViewDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/material/TabBarView'; 6 | final String detail = '''显示与当前所选选项卡对应的窗口小部件的页面视图。通常与TabBar一起使用。 7 | 8 | 如果未提供TabController,则必须有DefaultTabController 祖先。'''; 9 | @override 10 | _TabBarViewDemoState createState() => _TabBarViewDemoState(); 11 | } 12 | 13 | class _TabBarViewDemoState extends ExampleState 14 | with SingleTickerProviderStateMixin { 15 | TabController controller; 16 | 17 | TabBarViewSetting setting; 18 | 19 | @override 20 | void initState() { 21 | controller = TabController( 22 | length: tabValues[0].value.length, 23 | vsync: this, 24 | ); 25 | setting = TabBarViewSetting(); 26 | 27 | super.initState(); 28 | } 29 | 30 | @override 31 | String getDetail() { 32 | return widget.detail; 33 | } 34 | 35 | @override 36 | String getExampleCode() { 37 | return '''class MyTabBarView extends StatefulWidget { 38 | @override 39 | _MyTabBarViewState createState() => _MyTabBarViewState(); 40 | } 41 | 42 | class _MyTabBarViewState extends State 43 | with SingleTickerProviderStateMixin { 44 | TabController controller; 45 | 46 | @override 47 | void initState() { 48 | controller = TabController( 49 | length: 1, 50 | vsync: this, 51 | ); 52 | super.initState(); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | return Scaffold( 58 | appBar: TabBar( 59 | controller: controller, 60 | labelColor: Colors.amber, 61 | unselectedLabelColor: Colors.green, 62 | tabs: [ 63 | Tab(text: '1'), 64 | ], 65 | ), 66 | body: TabBarView( 67 | controller: controller, 68 | children: [ 69 | Text('1'), 70 | ], 71 | physics: ${setting.physics?.label??''}, 72 | ), 73 | ); 74 | } 75 | }'''; 76 | } 77 | 78 | @override 79 | List getSetting() { 80 | return [ 81 | ValueTitleWidget(StringParams.kPhysics), 82 | RadioGroupWidget(setting.physics, physicsValues, (value) { 83 | setState(() { 84 | setting = setting.copyWith(physics: value); 85 | }); 86 | }), 87 | ]; 88 | } 89 | 90 | @override 91 | String getTitle() { 92 | return 'TabBarView'; 93 | } 94 | 95 | _getChildren() { 96 | int i = 0; 97 | return tabValues[0].value.map((v) { 98 | Widget w = Container( 99 | alignment: Alignment.center, 100 | color: colorValues[i].value, 101 | child: Text('Page${i + 1}'), 102 | ); 103 | i++; 104 | return w; 105 | }).toList(); 106 | } 107 | 108 | @override 109 | Widget getWidget() { 110 | return Scaffold( 111 | appBar: TabBar( 112 | controller: controller, 113 | labelColor: Colors.amber, 114 | unselectedLabelColor: Colors.green, 115 | tabs: tabValues[0].value, 116 | ), 117 | body: TabBarView( 118 | controller: controller, 119 | children: _getChildren(), 120 | physics: setting.physics?.value, 121 | ), 122 | ); 123 | } 124 | } 125 | 126 | class TabBarViewSetting { 127 | final Value physics; 128 | 129 | TabBarViewSetting({this.physics}); 130 | 131 | TabBarViewSetting copyWith({ 132 | Value> children, 133 | Value physics, 134 | }) { 135 | return TabBarViewSetting( 136 | physics: physics ?? this.physics, 137 | ); 138 | } 139 | } 140 | 141 | -------------------------------------------------------------------------------- /lib/widgets/material/nButtonBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class ButtonBarDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/material/ButtonBar'; 6 | final String detail = '''按钮的水平排列。 7 | 8 | 根据当前ButtonTheme中的填充水平放置按钮 。 9 | 10 | 由Dialog用于排列对话框底部的操作.'''; 11 | 12 | @override 13 | _ButtonBarDemoState createState() => _ButtonBarDemoState(); 14 | } 15 | 16 | class _ButtonBarDemoState extends ExampleState { 17 | ButtonBarSetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = ButtonBarSetting( 22 | children: buttonValues[0], 23 | alignment: mainAxisAlignmentValues[0], 24 | mainAxisSize: mainAxisSizeValues[0], 25 | 26 | ); 27 | super.initState(); 28 | } 29 | 30 | @override 31 | String getDetail() { 32 | return widget.detail; 33 | } 34 | 35 | @override 36 | String getExampleCode() { 37 | return '''ButtonBar( 38 | alignment: ${setting.alignment?.label??''}, 39 | mainAxisSize: ${setting.mainAxisSize?.label??''}, 40 | children: ${setting.children?.label??''}, 41 | )'''; 42 | } 43 | 44 | @override 45 | List getSetting() { 46 | return [ 47 | ValueTitleWidget(StringParams.kChildren), 48 | RadioGroupWidget(setting.children, buttonValues, (value){ 49 | setState(() { 50 | setting=setting.copyWith(children: value); 51 | }); 52 | }), 53 | ValueTitleWidget(StringParams.kAlignment), 54 | RadioGroupWidget(setting.alignment, mainAxisAlignmentValues, (value){ 55 | setState(() { 56 | setting=setting.copyWith(alignment: value); 57 | }); 58 | }), 59 | ValueTitleWidget(StringParams.kMainAxisSize), 60 | RadioGroupWidget(setting.mainAxisSize, mainAxisSizeValues, (value){ 61 | setState(() { 62 | setting=setting.copyWith(mainAxisSize: value); 63 | }); 64 | }), 65 | ]; 66 | } 67 | 68 | @override 69 | String getTitle() { 70 | return 'ButtonBar'; 71 | } 72 | @override 73 | Widget getWidget() { 74 | return ButtonBar( 75 | alignment: setting.alignment?.value, 76 | mainAxisSize: setting.mainAxisSize?.value, 77 | children: setting.children?.value, 78 | ); 79 | } 80 | } 81 | 82 | class ButtonBarSetting { 83 | final Value alignment; 84 | final Value mainAxisSize; 85 | final Value> children; 86 | 87 | ButtonBarSetting({ 88 | this.alignment, 89 | this.mainAxisSize, 90 | this.children, 91 | }); 92 | 93 | ButtonBarSetting copyWith({ 94 | Value alignment, 95 | Value mainAxisSize, 96 | Value> children, 97 | }) { 98 | return ButtonBarSetting( 99 | alignment: alignment ?? this.alignment, 100 | mainAxisSize: mainAxisSize ?? this.mainAxisSize, 101 | children: children ?? this.children, 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widgets/material/pCheckBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class CheckBoxDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/material/CheckBox'; 6 | final String detail = '''材料设计复选框。 7 | 8 | 复选框本身不保持任何状态。相反,当复选框的状态发生变化时,窗口小部件会调用onChanged回调。大多数使用复选框的小部件将侦听onChanged回调并使用新值重建复选框以更新复选框的可视外观。 9 | 10 | 如果tristate为true ,则复选框可以选择显示三个值 - true,false和null 。当value为null时,将显示破折号。默认情况下, 三态为false,复选框的值必须为true或false。 11 | 12 | 需要其中一个祖先成为Material小部件。'''; 13 | 14 | @override 15 | _CheckBoxDemoState createState() => _CheckBoxDemoState(); 16 | } 17 | 18 | class _CheckBoxDemoState extends ExampleState { 19 | CheckBoxSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = CheckBoxSetting( 24 | value: boolValues[0], 25 | onChanged: Value( 26 | name: 'onChanged', 27 | value: (value) { 28 | setState(() { 29 | setting = setting.copyWith(value: boolValues[value ? 1 : 0]); 30 | }); 31 | }, 32 | label: '''(value) { 33 | setState(() { 34 | _value=value; 35 | }); 36 | }'''), 37 | tristate: boolValues[0],); // TODO: implement initState 38 | super.initState(); 39 | } 40 | 41 | @override 42 | String getDetail() { 43 | return widget.detail; 44 | } 45 | 46 | @override 47 | String getExampleCode() { 48 | return '''bool _value=false; 49 | Checkbox( 50 | value: _value, 51 | onChanged: ${setting.onChanged?.label??''}, 52 | tristate: ${setting.tristate?.label??''}, 53 | activeColor: ${setting.activeColor?.label??''}, 54 | )'''; 55 | } 56 | 57 | @override 58 | List getSetting() { 59 | return [ 60 | ValueTitleWidget(StringParams.kActiveColor), 61 | ColorGroupWidget(setting.activeColor, (value) { 62 | setState(() { 63 | setting = setting.copyWith(activeColor: value); 64 | }); 65 | }), 66 | SwitchValueTitleWidget( 67 | value: setting.value, 68 | title: StringParams.kValue, 69 | onChanged: (value) { 70 | setState(() { 71 | setting = setting.copyWith(value: value); 72 | }); 73 | }, 74 | ), 75 | SwitchValueTitleWidget( 76 | value: setting.tristate, 77 | title: StringParams.kTristate, 78 | onChanged: (value) { 79 | setState(() { 80 | setting = setting.copyWith(tristate: value); 81 | }); 82 | }, 83 | ), 84 | ]; 85 | } 86 | 87 | @override 88 | String getTitle() { 89 | return 'CheckBox'; 90 | } 91 | 92 | @override 93 | Widget getWidget() { 94 | // TODO: implement getWidget 95 | return Center( 96 | child: Checkbox( 97 | value: setting.value?.value, 98 | onChanged: setting.onChanged?.value, 99 | tristate: setting.tristate?.value, 100 | activeColor: setting.activeColor?.value, 101 | ), 102 | ); 103 | } 104 | } 105 | 106 | class CheckBoxSetting { 107 | Value value; 108 | Value tristate; 109 | Value> onChanged; 110 | Value activeColor; 111 | 112 | CheckBoxSetting({ 113 | this.value, 114 | this.tristate, 115 | this.onChanged, 116 | this.activeColor, 117 | }); 118 | 119 | CheckBoxSetting copyWith({ 120 | Value value, 121 | Value tristate, 122 | Value> onChanged, 123 | Value activeColor, 124 | }) { 125 | return CheckBoxSetting( 126 | value: value ?? this.value, 127 | tristate: tristate ?? this.tristate, 128 | onChanged: onChanged ?? this.onChanged, 129 | activeColor: activeColor ?? this.activeColor, 130 | ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /lib/widgets/material/qRadio.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class RadioDemo extends StatefulWidget { 5 | static const String routeName='widgets/material/Radio'; 6 | final String detail='''材料设计单选按钮。 7 | 8 | 用于在多个互斥值之间进行选择。当选择组中的一个单选按钮时,组中的其他单选按钮将不再被选中。值的类型T是Radio 类的类型参数。枚举通常用于此目的。 9 | 10 | 单选按钮本身不保持任何状态。相反,当单选按钮的状态发生变化时,小部件会调用onChanged回调。大多数使用单选按钮的小部件将侦听onChanged 回调并使用新的groupValue重建单选按钮以更新单选按钮的可视外观。 11 | 12 | 需要其中一个祖先成为Material小部件。'''; 13 | 14 | @override 15 | _RadioDemoState createState() => _RadioDemoState(); 16 | } 17 | 18 | class _RadioDemoState extends ExampleState { 19 | RadioSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = RadioSetting( 24 | value: boolValues[0], 25 | groupValue: boolValues[0], 26 | onChanged: Value( 27 | name: 'onChanged', 28 | value: (value) { 29 | setState(() { 30 | setting = setting.copyWith(groupValue: boolValues[value ? 1 : 0]); 31 | }); 32 | }, 33 | label: '''(value) { 34 | setState(() { 35 | _groupValue=value; 36 | }); 37 | }'''), 38 | ); // TODO: implement initState 39 | super.initState(); 40 | } 41 | 42 | @override 43 | String getDetail() { 44 | return widget.detail; 45 | } 46 | 47 | @override 48 | String getExampleCode() { 49 | return '''bool _groupValue=false; 50 | //当groupValue==Value才会选中 51 | Radio( 52 | groupValue: _groupValue, 53 | value: ${setting.value?.label??''}, 54 | onChanged: ${setting.onChanged?.label??''}, 55 | activeColor: ${setting.activeColor?.label??''}, 56 | )'''; 57 | } 58 | 59 | @override 60 | List getSetting() { 61 | return [ 62 | ValueTitleWidget(StringParams.kActiveColor), 63 | ColorGroupWidget(setting.activeColor, (value) { 64 | setState(() { 65 | setting = setting.copyWith(activeColor: value); 66 | }); 67 | }), 68 | SwitchValueTitleWidget( 69 | value: setting.value, 70 | title: StringParams.kValue, 71 | onChanged: (value) { 72 | setState(() { 73 | setting = setting.copyWith(value: value); 74 | }); 75 | }, 76 | ), 77 | SwitchValueTitleWidget( 78 | value: setting.groupValue, 79 | title: StringParams.kGroupValue, 80 | onChanged: (value) { 81 | setState(() { 82 | setting = setting.copyWith(groupValue: value); 83 | }); 84 | }, 85 | ), 86 | ]; 87 | } 88 | 89 | @override 90 | String getTitle() { 91 | return 'CheckBox'; 92 | } 93 | 94 | @override 95 | Widget getWidget() { 96 | // TODO: implement getWidget 97 | return Center( 98 | child: Radio( 99 | groupValue: setting.groupValue?.value, 100 | value: setting.value?.value, 101 | onChanged: setting.onChanged?.value, 102 | activeColor: setting.activeColor?.value, 103 | ), 104 | ); 105 | } 106 | } 107 | 108 | class RadioSetting { 109 | Value value; 110 | Value groupValue; 111 | 112 | Value> onChanged; 113 | Value activeColor; 114 | 115 | RadioSetting({ 116 | this.groupValue, 117 | this.value, 118 | this.onChanged, 119 | this.activeColor, 120 | }); 121 | 122 | RadioSetting copyWith({ 123 | Value value, 124 | Value groupValue, 125 | Value> onChanged, 126 | Value activeColor, 127 | }) { 128 | return RadioSetting( 129 | value: value ?? this.value, 130 | groupValue: groupValue ?? this.groupValue, 131 | onChanged: onChanged ?? this.onChanged, 132 | activeColor: activeColor ?? this.activeColor, 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/widgets/material/zgLinearProgressIndicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class LinearProgressIndicatorDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/material/LinearProgressIndicator'; 6 | final String detail = '''材料设计线性进度指示器,也称为进度条。 7 | 8 | 一个小部件,显示沿线的进度。有两种线性进度指标: 9 | 10 | 确定。确定进度指标在每个时间点都有一个特定的值,并且该值应该从0.0单调增加到1.0,此时指标就完成了。要创建确定的进度指示器,请使用介于0.0和1.0之间的非空值。 11 | 不确定。不确定的进度指标在每个时间点都没有特定的值,而是表明正在取得进展而没有指出仍有多少进展。要创建不确定的进度指示器,请使用空值。'''; 12 | 13 | @override 14 | _LinearProgressIndicatorDemoState createState() => 15 | _LinearProgressIndicatorDemoState(); 16 | } 17 | 18 | class _LinearProgressIndicatorDemoState 19 | extends ExampleState { 20 | LinearProgressIndicatorSetting setting; 21 | 22 | @override 23 | void initState() { 24 | setting = LinearProgressIndicatorSetting(); 25 | super.initState(); 26 | } 27 | 28 | @override 29 | String getDetail() { 30 | return widget.detail; 31 | } 32 | 33 | @override 34 | String getExampleCode() { 35 | return '''LinearProgressIndicator( 36 | value: ${setting.value?.label??''}, 37 | backgroundColor: ${setting.backgroundColor?.label??''}, 38 | valueColor: ${setting.valueColor?.label??''}, 39 | )'''; 40 | } 41 | 42 | @override 43 | List getSetting() { 44 | return [ 45 | ValueTitleWidget(StringParams.kBackgroundColor), 46 | ColorGroupWidget(setting.backgroundColor, (value) { 47 | setState(() { 48 | setting = setting.copyWith(backgroundColor: value); 49 | }); 50 | }), 51 | DropDownValueTitleWidget(selectList: doubleOneValues, title: StringParams.kValue, value: setting.value, 52 | onChanged: (value){ 53 | setState(() { 54 | setting=setting.copyWith(value: value); 55 | }); 56 | },) 57 | ]; 58 | } 59 | 60 | @override 61 | String getTitle() { 62 | return 'LinearProgressIndicator'; 63 | } 64 | 65 | @override 66 | Widget getWidget() { 67 | return LinearProgressIndicator( 68 | value: setting.value?.value, 69 | backgroundColor: setting.backgroundColor?.value, 70 | valueColor: setting.valueColor?.value, 71 | ); 72 | } 73 | } 74 | 75 | class LinearProgressIndicatorSetting { 76 | final Value value; 77 | final Value backgroundColor; 78 | final Value> valueColor; 79 | 80 | LinearProgressIndicatorSetting( 81 | {this.value, this.backgroundColor, this.valueColor}); 82 | 83 | LinearProgressIndicatorSetting copyWith({ 84 | Value value, 85 | Value backgroundColor, 86 | Value> valueColor, 87 | }) { 88 | return LinearProgressIndicatorSetting( 89 | value: value ?? this.value, 90 | backgroundColor: backgroundColor ?? this.backgroundColor, 91 | valueColor: valueColor ?? this.valueColor, 92 | ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/widgets/material/zjDivider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class DividerDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/material/Divider'; 6 | final String detail = '''一个设备像素厚的水平线,两侧有填充。 7 | 8 | 在材料设计语言中,这代表一个分隔符。 9 | 10 | 分隔符可以在列表,抽屉和其他地方使用,以垂直分隔内容。要在列表中的项之间创建一个像素的分隔符,请考虑使用ListTile.divideTiles,它针对此情况进行了优化。 11 | 12 | 盒子的总高度由高度控制。从高度自动计算适当的填充。'''; 13 | 14 | @override 15 | _DividerDemoState createState() => _DividerDemoState(); 16 | } 17 | 18 | class _DividerDemoState extends ExampleState { 19 | DividerSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = DividerSetting( 24 | height: doubleXlargeValues[0], 25 | indent: doubleMiniValues[0], 26 | 27 | ); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | String getDetail() { 33 | return widget.detail; 34 | } 35 | 36 | @override 37 | String getExampleCode() { 38 | return '''Divider( 39 | height: ${setting.height?.label??''}, 40 | indent: ${setting.indent?.label??''}, 41 | color: ${setting.color?.label??''}, 42 | )'''; 43 | } 44 | 45 | @override 46 | List getSetting() { 47 | return [ 48 | ValueTitleWidget(StringParams.kColor), 49 | ColorGroupWidget(setting.color, (value) { 50 | setState(() { 51 | setting = setting.copyWith(color: value); 52 | }); 53 | }), 54 | DropDownValueTitleWidget(selectList: doubleXlargeValues, title: StringParams.kHeight, value: setting.height, 55 | onChanged: (value){ 56 | setState(() { 57 | setting=setting.copyWith(height: value); 58 | }); 59 | },), 60 | DropDownValueTitleWidget(selectList: doubleMiniValues, title: StringParams.kIndent, value: setting.indent, 61 | onChanged: (value){ 62 | setState(() { 63 | setting=setting.copyWith(indent: value); 64 | }); 65 | },), 66 | ]; 67 | } 68 | 69 | @override 70 | String getTitle() { 71 | return 'Divider'; 72 | } 73 | 74 | @override 75 | Widget getWidget() { 76 | return Center( 77 | child: Divider( 78 | height: setting.height?.value, 79 | indent: setting.indent?.value, 80 | color: setting.color?.value, 81 | ), 82 | ); 83 | } 84 | } 85 | 86 | class DividerSetting { 87 | final Value height; 88 | final Value indent; 89 | final Value color; 90 | 91 | DividerSetting({this.height, this.indent, this.color}); 92 | 93 | DividerSetting copyWith({ 94 | Value height, 95 | Value indent, 96 | Value color, 97 | }) { 98 | return DividerSetting( 99 | height: height ?? this.height, 100 | indent: indent ?? this.indent, 101 | color: color ?? this.color, 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/widgets/painting/aOpacity.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class OpacityDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/painting/Opacity'; 6 | final String detail = '''使子项部分透明的小部件。 7 | 8 | 此类将其子绘制到中间缓冲区中,然后将子项重新混合到部分透明的场景中。 9 | 10 | 对于0.0和1.0以外的不透明度值,此类相对较贵,因为它需要将子画面绘制到中间缓冲区中。对于值0.0,孩子根本就没有画过。对于值1.0,将立即绘制子项而不使用中间缓冲区。'''; 11 | 12 | @override 13 | _OpacityDemoState createState() => _OpacityDemoState(); 14 | } 15 | 16 | class _OpacityDemoState extends ExampleState { 17 | OpacitySetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = OpacitySetting( 22 | child: Value( 23 | value: Image.asset('images/burgers.jpg'), 24 | label: "Image.asset('images/burgers.jpg')", 25 | ), 26 | opacity: doubleOneValues[1], 27 | alwaysIncludeSemantics: boolValues[0], 28 | ); 29 | super.initState(); 30 | } 31 | 32 | @override 33 | String getDetail() { 34 | return widget.detail; 35 | } 36 | 37 | @override 38 | String getExampleCode() { 39 | return '''Opacity( 40 | opacity: ${setting.opacity.label??''}, 41 | child: ${setting.child?.label??''}, 42 | alwaysIncludeSemantics: ${setting.alwaysIncludeSemantics?.label??''}, 43 | )'''; 44 | } 45 | 46 | @override 47 | List getSetting() { 48 | return [ 49 | ValueTitleWidget(StringParams.kOpacity), 50 | SeekBarGroupWidget(setting.opacity, (value){ 51 | setState(() { 52 | setState(() { 53 | setting = setting.copyWith(opacity: value); 54 | }); 55 | }); 56 | }), 57 | SwitchValueTitleWidget(title: StringParams.kAlwaysIncludeSemantics, value: setting.alwaysIncludeSemantics, onChanged: (value){ 58 | setState(() { 59 | setting=setting.copyWith(alwaysIncludeSemantics: value); 60 | }); 61 | }) 62 | ]; 63 | } 64 | 65 | @override 66 | String getTitle() { 67 | return 'Opacity'; 68 | } 69 | 70 | @override 71 | Widget getWidget() { 72 | return Opacity( 73 | opacity: setting.opacity.value, 74 | child: setting.child?.value, 75 | alwaysIncludeSemantics: setting.alwaysIncludeSemantics?.value, 76 | ); 77 | } 78 | } 79 | 80 | class OpacitySetting { 81 | final Value child; 82 | final Value opacity; 83 | final Value alwaysIncludeSemantics; 84 | 85 | OpacitySetting({ 86 | this.child, 87 | this.opacity, 88 | this.alwaysIncludeSemantics, 89 | }); 90 | 91 | OpacitySetting copyWith({ 92 | Value child, 93 | Value opacity, 94 | Value alwaysIncludeSemantics, 95 | }) { 96 | return OpacitySetting( 97 | child: child ?? this.child, 98 | opacity: opacity ?? this.opacity, 99 | alwaysIncludeSemantics: 100 | alwaysIncludeSemantics ?? this.alwaysIncludeSemantics, 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /lib/widgets/painting/aaPaintingShow.dart: -------------------------------------------------------------------------------- 1 | export 'aOpacity.dart'; 2 | export 'cDecoratedBox.dart'; 3 | export 'dFractionalTranslation.dart'; 4 | export 'eRotatedBox.dart'; 5 | export 'fClipOval.dart'; 6 | export 'gClipPath.dart'; 7 | export 'hClipRect.dart'; 8 | export 'iCustomPaint.dart'; 9 | export 'jBackdropFilter.dart'; -------------------------------------------------------------------------------- /lib/widgets/painting/cDecoratedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class DecoratedBoxDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/painting/DecoratedBox'; 6 | final String detail = '''在儿童绘画之前或之后绘制装饰的小部件。 7 | 8 | 容器根据边界的宽度对其子进行插入; 这个小部件没有。 9 | 10 | 常用于BoxDecoration。'''; 11 | 12 | @override 13 | _DecoratedBoxDemoState createState() => 14 | _DecoratedBoxDemoState(); 15 | } 16 | 17 | class _DecoratedBoxDemoState 18 | extends ExampleState { 19 | DecoratedBoxSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = DecoratedBoxSetting( 24 | child: Value( 25 | value: Image.asset('images/burgers.jpg'), 26 | label: "Image.asset('images/burgers.jpg')", 27 | ), 28 | decoration: decorationValues[0], 29 | position: decorationPositionValues[0], 30 | ); 31 | super.initState(); 32 | } 33 | 34 | @override 35 | String getDetail() { 36 | return widget.detail; 37 | } 38 | 39 | @override 40 | String getExampleCode() { 41 | return '''DecoratedBox( 42 | decoration: ${setting.decoration?.label??''}, 43 | position: ${setting.position?.label??''}, 44 | child: ${setting.child?.label??''}, 45 | )'''; 46 | } 47 | 48 | @override 49 | List getSetting() { 50 | return [ 51 | ValueTitleWidget(StringParams.kDecoration), 52 | RadioGroupWidget(setting.decoration, decorationValues, (value) { 53 | setState(() { 54 | setting = setting.copyWith(decoration: value); 55 | }); 56 | }), 57 | ValueTitleWidget(StringParams.kPosition), 58 | RadioGroupWidget(setting.position, decorationPositionValues, (value) { 59 | setState(() { 60 | setting = setting.copyWith(position: value); 61 | }); 62 | }), 63 | ]; 64 | } 65 | 66 | @override 67 | String getTitle() { 68 | return 'DecoratedBox'; 69 | } 70 | 71 | 72 | @override 73 | Widget getWidget() { 74 | return DecoratedBox( 75 | decoration: setting.decoration?.value, 76 | position: setting.position?.value, 77 | child: setting.child?.value, 78 | ); 79 | } 80 | } 81 | 82 | class DecoratedBoxSetting { 83 | final Value decoration; 84 | final Value position; 85 | final Value child; 86 | DecoratedBoxSetting({ 87 | this.decoration, this.position, this.child, 88 | }); 89 | 90 | DecoratedBoxSetting copyWith({ 91 | Value decoration, 92 | Value position, 93 | Value child, 94 | }) { 95 | return DecoratedBoxSetting( 96 | decoration: decoration??this.decoration, 97 | position: position??this.position, 98 | child: child??this.child, 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/widgets/painting/dFractionalTranslation.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class FractionalTranslationDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/painting/FractionalTranslation'; 6 | final String detail = '''在绘制其子项之前应用转换转换。 7 | 8 | 翻译表示为缩小到孩子大小的偏移量。例如,a 为0.25 的Offsetdx将导致子宽度的四分之一的水平平移。 9 | 10 | 命中测试只会在FractionalTranslation的范围内被检测到 ,即使内容被偏移使得它们溢出。'''; 11 | 12 | @override 13 | _FractionalTranslationDemoState createState() => 14 | _FractionalTranslationDemoState(); 15 | } 16 | 17 | class _FractionalTranslationDemoState 18 | extends ExampleState { 19 | FractionalTranslationSetting setting; 20 | 21 | @override 22 | void initState() { 23 | setting = FractionalTranslationSetting( 24 | child: Value( 25 | value: Image.asset('images/burgers.jpg'), 26 | label: "Image.asset('images/burgers.jpg')", 27 | ), 28 | translation: offsetValues[0], 29 | ); 30 | super.initState(); 31 | } 32 | 33 | @override 34 | String getDetail() { 35 | return widget.detail; 36 | } 37 | 38 | @override 39 | String getExampleCode() { 40 | return '''FractionalTranslation( 41 | translation: ${setting.translation?.label ?? ''}, 42 | transformHitTests: ${setting.transformHitTests?.label ?? ''}, 43 | child: ${setting.child?.label ?? ''}, 44 | )'''; 45 | } 46 | 47 | @override 48 | List getSetting() { 49 | return [ 50 | ValueTitleWidget(StringParams.kTranslation), 51 | RadioGroupWidget(setting.translation, offsetValues, (value) { 52 | setState(() { 53 | setting = setting.copyWith(translation: value); 54 | }); 55 | }), 56 | SwitchValueTitleWidget(title: StringParams.kTransformHitTests, value: setting.transformHitTests, onChanged: (value){ 57 | setState(() { 58 | setting=setting.copyWith(transformHitTests: value); 59 | }); 60 | }), 61 | ]; 62 | } 63 | 64 | @override 65 | String getTitle() { 66 | return 'FractionalTranslation'; 67 | } 68 | 69 | @override 70 | Widget getWidget() { 71 | return FractionalTranslation( 72 | translation: setting.translation?.value, 73 | transformHitTests: setting.transformHitTests?.value, 74 | child: setting.child?.value, 75 | ); 76 | } 77 | } 78 | 79 | class FractionalTranslationSetting { 80 | final Value translation; 81 | final Value transformHitTests; 82 | final Value child; 83 | 84 | FractionalTranslationSetting({ 85 | this.translation, 86 | this.transformHitTests, 87 | this.child, 88 | }); 89 | 90 | FractionalTranslationSetting copyWith({ 91 | Value translation, 92 | Value transformHitTests, 93 | Value child, 94 | }) { 95 | return FractionalTranslationSetting( 96 | transformHitTests: transformHitTests ?? this.transformHitTests, 97 | translation: translation ?? this.translation, 98 | child: child ?? this.child, 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/widgets/painting/eRotatedBox.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class RotatedBoxDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/painting/RotatedBox'; 6 | final String detail = '''一个小部件,可以将其子项旋转整数个四分之一圈。 7 | 8 | 与在绘制之前应用变换的Transform不同,此对象在布局之前应用其旋转,这意味着整个旋转的框仅消耗旋转子项所需的空间。'''; 9 | 10 | @override 11 | _RotatedBoxDemoState createState() => _RotatedBoxDemoState(); 12 | } 13 | 14 | class _RotatedBoxDemoState extends ExampleState { 15 | RotatedBoxSetting setting; 16 | 17 | @override 18 | void initState() { 19 | setting = RotatedBoxSetting( 20 | child: Value( 21 | value: Image.asset('images/burgers.jpg'), 22 | label: "Image.asset('images/burgers.jpg')", 23 | ), 24 | quarterTurns: intMiniValues[1]); 25 | super.initState(); 26 | } 27 | 28 | 29 | @override 30 | String getDetail() { 31 | return widget.detail; 32 | } 33 | 34 | @override 35 | String getExampleCode() { 36 | return '''RotatedBox( 37 | child: ${setting.child?.label ?? ''}, 38 | quarterTurns: ${setting.quarterTurns?.label ?? ''}, 39 | )'''; 40 | } 41 | 42 | @override 43 | List getSetting() { 44 | return [ 45 | DropDownValueTitleWidget( 46 | title: StringParams.kQuarterTurns, 47 | selectList: intMiniValues, 48 | value: setting.quarterTurns, 49 | onChanged: (value) { 50 | setState(() { 51 | setting = setting.copyWith(quarterTurns: value); 52 | }); 53 | }, 54 | ), 55 | ]; 56 | } 57 | 58 | @override 59 | String getTitle() { 60 | return 'RotatedBox'; 61 | } 62 | 63 | @override 64 | Widget getWidget() { 65 | return pushWidget(); 66 | } 67 | 68 | pushWidget(){ 69 | return new RotatedBox( 70 | child: setting.child?.value, 71 | quarterTurns: setting.quarterTurns?.value, 72 | ); 73 | } 74 | } 75 | 76 | class RotatedBoxSetting { 77 | final Value quarterTurns; 78 | final Value child; 79 | 80 | RotatedBoxSetting({ 81 | this.quarterTurns, 82 | this.child, 83 | }); 84 | 85 | RotatedBoxSetting copyWith({Value quarterTurns}) { 86 | return RotatedBoxSetting( 87 | quarterTurns: quarterTurns ?? this.quarterTurns, 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/widgets/painting/jBackdropFilter.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui' as ui; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutterbyrhyme/code/example_code.dart'; 5 | 6 | class BackdropFilterDemo extends StatefulWidget { 7 | static const String routeName = 'widgets/painting/BackdropFilter'; 8 | final String detail = '''一个小部件,它将过滤器应用于现有的绘制内容,然后绘制子项。 9 | 10 | 这种效果相对昂贵,特别是如果滤镜是非局部的,例如模糊。'''; 11 | 12 | @override 13 | _BackdropFilterDemoState createState() => _BackdropFilterDemoState(); 14 | } 15 | 16 | class _BackdropFilterDemoState extends ExampleState { 17 | BackdropFilterSetting setting; 18 | 19 | @override 20 | void initState() { 21 | setting = BackdropFilterSetting( 22 | filter: Value( 23 | value: ui.ImageFilter.blur(sigmaX: 10.0,sigmaY: 10.0), 24 | label: 'ui.ImageFilter.blur(sigmaX: 10.0,sigmaY: 10.0)', 25 | ), 26 | child: Value( 27 | value: DecoratedBox(decoration: BoxDecoration(color: Colors.transparent)), 28 | label: "Image.asset('images/burgers.jpg')", 29 | ), 30 | ); 31 | super.initState(); 32 | } 33 | 34 | @override 35 | String getDetail() { 36 | return widget.detail; 37 | } 38 | 39 | @override 40 | String getExampleCode() { 41 | return '''import 'dart:ui' as ui; 42 | 43 | Stack( 44 | fit: StackFit.expand, 45 | children: [ 46 | Image.asset('images/burgers.jpg'), 47 | BackdropFilter( 48 | filter: ${setting.filter?.label??''}, 49 | child: ${setting.child?.label??''}, 50 | ), 51 | ], 52 | )'''; 53 | } 54 | 55 | @override 56 | List getSetting() { 57 | return []; 58 | } 59 | 60 | @override 61 | String getTitle() { 62 | return 'BackdropFilter'; 63 | } 64 | 65 | @override 66 | Widget getWidget() { 67 | return Stack( 68 | fit: StackFit.expand, 69 | children: [ 70 | Image.asset('images/burgers.jpg'), 71 | BackdropFilter( 72 | filter: setting.filter?.value, 73 | child: setting.child?.value, 74 | ), 75 | ], 76 | ); 77 | } 78 | } 79 | 80 | class BackdropFilterSetting { 81 | final Value child; 82 | final Value filter; 83 | 84 | BackdropFilterSetting({this.filter, this.child}); 85 | 86 | BackdropFilterSetting copyWith({ 87 | Value child, 88 | Value filter, 89 | }) { 90 | return BackdropFilterSetting( 91 | child: child ?? this.child, 92 | filter: filter ?? this.filter, 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/widgets/scrolling/aScrollingShow.dart: -------------------------------------------------------------------------------- 1 | export 'bNestedScrollView.dart'; 2 | export 'cGridView.dart'; 3 | export 'dSingleChildScrollView.dart'; 4 | export 'fScrollbar.dart'; 5 | export 'gCustomScrollView.dart'; 6 | export 'hNotificationListener.dart'; 7 | export 'iScrollConfiguration.dart'; 8 | export 'jRefreshIndicator.dart'; -------------------------------------------------------------------------------- /lib/widgets/scrolling/fScrollbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutterbyrhyme/code/example_code.dart'; 3 | 4 | class ScrollbarDemo extends StatefulWidget { 5 | static const String routeName = 'widgets/scrolling/Scrollbar'; 6 | final String detail = '''材质设计滚动条。 7 | 8 | 滚动条指示Scrollable小部件的哪个部分实际可见。 9 | 10 | 动态更改为iOS平台上类似CupertinoScrollbar的iOS样式滚动条 。 11 | 12 | 要将滚动条添加到ScrollView,只需将滚动视图窗口小部件包装在Scrollbar小部件中。'''; 13 | 14 | @override 15 | _ScrollbarDemoState createState() => _ScrollbarDemoState(); 16 | } 17 | class _ScrollbarDemoState extends ExampleState { 18 | ScrollbarSetting setting; 19 | 20 | @override 21 | void initState() { 22 | setting = ScrollbarSetting( 23 | child: Value( 24 | value: ListView( 25 | children: [ 26 | ListTile( 27 | leading: CircleAvatar( 28 | child: Text('F'), 29 | ), 30 | title: Text('Flutter'), 31 | ), 32 | ListTile( 33 | leading: CircleAvatar( 34 | child: Text('D'), 35 | ), 36 | title: Text('Dart'), 37 | ), 38 | ListTile( 39 | leading: CircleAvatar( 40 | child: Text('A'), 41 | ), 42 | title: Text('Android'), 43 | ), 44 | ListTile( 45 | leading: CircleAvatar( 46 | child: Text('I'), 47 | ), 48 | title: Text('IOS'), 49 | ), 50 | ListTile( 51 | leading: CircleAvatar( 52 | child: Text('K'), 53 | ), 54 | title: Text('Kotlin'), 55 | ), 56 | ListTile( 57 | leading: CircleAvatar( 58 | child: Text('O'), 59 | ), 60 | title: Text('Object-C'), 61 | ), 62 | ], 63 | ), 64 | 65 | label: '''ListView( 66 | children: [ 67 | ListTile( 68 | leading: CircleAvatar( 69 | child: Text('F'), 70 | ), 71 | title: Text('Flutter'), 72 | ), 73 | //... 74 | ], 75 | )''', 76 | ), 77 | ); 78 | super.initState(); 79 | } 80 | 81 | @override 82 | String getDetail() { 83 | return widget.detail; 84 | } 85 | 86 | @override 87 | String getExampleCode() { 88 | return '''Scrollbar( 89 | child: ${setting.child?.label??''}, 90 | )'''; 91 | } 92 | 93 | @override 94 | List getSetting() { 95 | return []; 96 | } 97 | 98 | @override 99 | String getTitle() { 100 | return 'Scrollbar'; 101 | } 102 | 103 | @override 104 | Widget getWidget() { 105 | return Scrollbar( 106 | child: setting.child?.value, 107 | ); 108 | } 109 | } 110 | 111 | class ScrollbarSetting { 112 | final Value child; 113 | 114 | ScrollbarSetting({ 115 | this.child, 116 | }); 117 | 118 | ScrollbarSetting copyWith({ 119 | Value child, 120 | }) { 121 | return ScrollbarSetting( 122 | child: child ?? this.child, 123 | ); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /lib/widgets/styling/aStylingShow.dart: -------------------------------------------------------------------------------- 1 | export 'bTheme.dart'; 2 | export 'cMediaQuery.dart'; 3 | -------------------------------------------------------------------------------- /lib/widgets/text/aaTextShow.dart: -------------------------------------------------------------------------------- 1 | export 'aRichText.dart'; 2 | export 'bDefaultTextStyle.dart'; -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutterbyrhyme 2 | description: A Flutter course. 3 | 4 | dependencies: 5 | flutter: 6 | sdk: flutter 7 | 8 | cupertino_icons: ^0.1.2 9 | url_launcher: ^5.4.2 10 | shared_preferences: ^0.5.6+2 11 | html: any 12 | http: ^0.12.0 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | 17 | 18 | flutter: 19 | uses-material-design: true 20 | assets: 21 | - images/ 22 | - assets/ 23 | 24 | fonts: 25 | - family: qlYouYuan 26 | fonts: 27 | - asset: fonts/qlYouYuan.ttf 28 | -------------------------------------------------------------------------------- /screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhymelph/FlutterByRhyme/a06f84f810cdbd633db3eeef562b4f5bd744bfdb/screenshot/screenshot.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter 3 | // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to 4 | // find child widgets in the widget tree, read text, and verify that the values of widget properties 5 | // are correct. 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter_test/flutter_test.dart'; 9 | import 'package:flutterbyrhyme/Application.dart'; 10 | 11 | void main() { 12 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | await tester.pumpWidget(new Application()); 15 | 16 | // Verify that our counter starts at 0. 17 | expect(find.text('0'), findsOneWidget); 18 | expect(find.text('1'), findsNothing); 19 | 20 | // Tap the '+' icon and trigger a frame. 21 | await tester.tap(find.byIcon(Icons.add)); 22 | await tester.pump(); 23 | 24 | // Verify that our counter has incremented. 25 | expect(find.text('0'), findsNothing); 26 | expect(find.text('1'), findsOneWidget); 27 | }); 28 | } 29 | --------------------------------------------------------------------------------