merge
@ -1,2 +0,0 @@
|
||||
#Thu Nov 22 22:29:42 CST 2018
|
||||
gradle.version=3.5.1
|
@ -1 +0,0 @@
|
||||
|
43
LICENSE
@ -1,21 +1,28 @@
|
||||
Copyright (c) 2018-present Alibaba Inc.
|
||||
BSD License
|
||||
|
||||
Permission is granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
Copyright (c) 2018-present, Alibaba Group Holding Limited. All rights reserved.
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
|
||||
WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@ -9,7 +9,11 @@
|
||||
|
||||
Android download URL:
|
||||
|
||||
<<<<<<< HEAD
|
||||
<img src="https://img.alicdn.com/tfs/TB180.kOhYaK1RjSZFnXXa80pXa-442-420.png" width="200px">
|
||||
=======
|
||||
<img src="https://img.alicdn.com/tfs/TB1jGgfQ7voK1RjSZFNXXcxMVXa-438-426.png" width="200px">
|
||||
>>>>>>> develop
|
||||
|
||||
Iphone download URL:
|
||||
No
|
||||
|
48
README.md
@ -2,6 +2,26 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
|
||||
## Flutter Go
|
||||
|
||||

|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
|
||||
|
||||
## 版本更新历史
|
||||
> 按时间顺序,展示重要的提交更新内容。
|
||||
|
||||
[地址](https://github.com/alibaba/flutter-go/blob/develop/CHANGE-LOG.md)
|
||||
|
||||
## 开发规范
|
||||
> 由于类似 javascript, java, object-c,等开发者的语言习惯不同而产生歧义,我们依据官方提供的 [dart 语言规范](https://www.dartlang.org) 定制。
|
||||
|
||||
[<< Flutter Go 开发规范第一版 >>](https://github.com/alibaba/flutter-go/blob/develop/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md)
|
||||
|
||||
## The Flutter-Go Roadmap(路线图) for 2019
|
||||
> 考虑到 Flutter 未来的变化和策略的可变性, roadmap 不排除有一定调整,但总体不会变化太大。
|
||||
|
||||
<img src="https://img.alicdn.com/tfs/TB19UahQQzoK1RjSZFlXXai4VXa-1500-1106.png" width="600px">
|
||||
>>>>>>> develop
|
||||
|
||||
> 帮助开发者快速上手 Flutter **Flutter Go 1.0 Android版已正式发布**
|
||||
|
||||
@ -19,7 +39,11 @@ Language: [English](https://github.com/alibaba/flutter-go/blob/master/README-en.
|
||||
|
||||
android下载地址:
|
||||
|
||||
<<<<<<< HEAD
|
||||
<img src="https://img.alicdn.com/tfs/TB180.kOhYaK1RjSZFnXXa80pXa-442-420.png" width="200px">
|
||||
=======
|
||||
<img src="https://img.alicdn.com/tfs/TB1jGgfQ7voK1RjSZFNXXcxMVXa-438-426.png" width="200px">
|
||||
>>>>>>> develop
|
||||
|
||||
iphone下载地址:
|
||||
暂无
|
||||
@ -52,7 +76,11 @@ flutter优点主要包括:
|
||||
|
||||
#### Flutter Go 的优势
|
||||
|
||||
<<<<<<< HEAD
|
||||
- 详解常用widget多达 **140+** 个
|
||||
=======
|
||||
- 详解常用 widget 多达 **140+** 个
|
||||
>>>>>>> develop
|
||||
- 配套 Demo 详解 widget 常规用法
|
||||
- 集中整合 widget 案例,一个 APP 搞定所有常用 widget 的用法
|
||||
- 持续迭代 ‘追新’ 官方版本
|
||||
@ -96,7 +124,23 @@ flutter优点主要包括:
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### 版权说明
|
||||
- 感谢大家对 `flutter go` 的支持和下载,但近期发现,有类似直接被发布到苹果 app store 上的行为,并未注明真实来源,copyright 和 项目的 github 地址,以及开发者的版权相关信息( 包括删除"首页栏的版权声明"和"关于我们"的行为 );
|
||||
|
||||
- 上述行为,打击了 `flutter go` 开发者的积极性,同时干扰了 flutter go app 的正常发布渠道,基于 app 开源项目的发布特殊性,特更新 [LICENSE](LICENSE) 「 开源许可证 」,由 MIT 协议 更改为 BSD 协议, 同时建议不要随意发布到公共渠道的应用商店,影响官方 `flutter go` 的app版本迭代;
|
||||
|
||||
- 大家可以继续放心的开源使用,但是要求注意和遵守以下许可前提:
|
||||
```
|
||||
* 版权声明样式
|
||||
//Copyright (c) 2018-present, Alibaba Group Holding Limited. All rights reserved.
|
||||
|
||||
* 源代码的重新分发必须保留上述版权声明,条件清单和免责声明。
|
||||
|
||||
* 二进制形式的再分发必须复制上述版权声明,此条件列表以及文档中的以下免责声明和/或随分发提供的其他材料。
|
||||
```
|
||||
- 由于本开源项目是供大家学习和交流 flutter 之用,里面耗费了开发人员大量的心血,精力和热情,请尊重开发者的劳动成果,以及相关许可证之规定;
|
||||
|
||||
- 大家的互相信任,尊重与支持,才是开源社区前进的动力和来源.
|
||||
|
||||
Powered by [阿里拍卖前端团队](https://github.com/alibaba-paimai-frontend)<img src="https://img.alicdn.com/tfs/TB1foEhAMHqK1RjSZJnXXbNLpXa-166-166.png" width=20 height=20>
|
||||
|
||||
|
||||
|
||||
|
10
android/.gitignore
vendored
@ -1,10 +0,0 @@
|
||||
*.iml
|
||||
*.class
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
GeneratedPluginRegistrant.java
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>android</name>
|
||||
<comment>Project android created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -1,2 +0,0 @@
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>app</name>
|
||||
<comment>Project app created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -1,2 +0,0 @@
|
||||
connection.project.dir=..
|
||||
eclipse.preferences.version=1
|
@ -1,61 +0,0 @@
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.example.flutterrookiebook"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 27
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.flutterrookiebook">
|
||||
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="flutter_go"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- This keeps the window background of the activity showing
|
||||
until Flutter renders its first frame. It can be removed if
|
||||
there is no splash screen (such as the default splash screen
|
||||
defined in @style/LaunchTheme). -->
|
||||
<meta-data
|
||||
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
|
||||
android:value="true" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
Before Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 721 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.4 KiB |
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
</resources>
|
@ -25,8 +25,19 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
compileSdkVersion 28
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
@ -38,21 +49,32 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
<<<<<<< HEAD
|
||||
applicationId "com.ali.fluttergo"
|
||||
=======
|
||||
applicationId "com.alibaba.fluttergo"
|
||||
>>>>>>> develop
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 27
|
||||
targetSdkVersion 28
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
signingConfigs {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
flutter {
|
||||
@ -62,6 +84,20 @@ flutter {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
//firebase
|
||||
implementation 'com.google.firebase:firebase-core:16.0.8'
|
||||
//Crashlytics SDK
|
||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
|
||||
// 性能监控
|
||||
///implementation 'com.google.firebase:firebase-perf:16.2.3'
|
||||
// 登陆
|
||||
////implementation 'com.google.firebase:firebase-auth:16.0.3'
|
||||
}
|
||||
//firebase
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
//Crashlytics SDK
|
||||
apply plugin: 'io.fabric'
|
||||
// 性能监控
|
||||
///apply plugin: 'com.google.firebase.firebase-perf'
|
40
android/app/google-services.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "611157827052",
|
||||
"firebase_url": "https://alibaba-flutter-go.firebaseio.com",
|
||||
"project_id": "alibaba-flutter-go",
|
||||
"storage_bucket": "alibaba-flutter-go.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:611157827052:android:c6129e5eff2f125d",
|
||||
"android_client_info": {
|
||||
"package_name": "com.alibaba.fluttergo"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "611157827052-iiuevj8qu56alpqh47v37j9sd4e40di7.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyA9chxDIuds7gmPQTJPpDpoXyN9rDTdvhU"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "611157827052-iiuevj8qu56alpqh47v37j9sd4e40di7.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
1
android/app/release/output.json
Normal file
@ -0,0 +1 @@
|
||||
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"0.0.5","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
@ -1,5 +1,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<<<<<<< HEAD
|
||||
package="com.ali.fluttergo">
|
||||
=======
|
||||
package="com.alibaba.fluttergo">
|
||||
>>>>>>> develop
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
|
@ -1,5 +1,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<<<<<<< HEAD
|
||||
package="com.ali.fluttergo">
|
||||
=======
|
||||
package="com.alibaba.fluttergo">
|
||||
>>>>>>> develop
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.example.flutterrookiebook;
|
||||
|
||||
import android.os.Bundle;
|
||||
import io.flutter.app.FlutterActivity;
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
GeneratedPluginRegistrant.registerWith(this);
|
||||
}
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
<<<<<<< HEAD
|
||||
package com.ali.fluttergo
|
||||
=======
|
||||
package com.alibaba.fluttergo
|
||||
>>>>>>> develop
|
||||
|
||||
import android.os.Bundle
|
||||
|
||||
|
@ -6,7 +6,11 @@
|
||||
<!-- You can insert your own image assets here -->
|
||||
<item>
|
||||
<bitmap
|
||||
<<<<<<< HEAD
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/splash" />
|
||||
=======
|
||||
android:src="@drawable/splash" />
|
||||
>>>>>>> develop
|
||||
</item>
|
||||
</layer-list>
|
||||
|
BIN
android/app/src/main/res/mipmap-xxxhdpi/spalsh.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
@ -1,5 +1,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<<<<<<< HEAD
|
||||
package="com.ali.fluttergo">
|
||||
=======
|
||||
package="com.alibaba.fluttergo">
|
||||
>>>>>>> develop
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
|
@ -1,12 +1,30 @@
|
||||
buildscript {
|
||||
<<<<<<< HEAD
|
||||
ext.kotlin_version = '1.2.71'
|
||||
=======
|
||||
ext.kotlin_version = '1.3.0'
|
||||
>>>>>>> develop
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
//Crashlytics SDK
|
||||
maven {
|
||||
url 'https://maven.fabric.io/public'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
<<<<<<< HEAD
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
=======
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
//firebase
|
||||
classpath 'com.google.gms:google-services:4.2.0'
|
||||
//Crashlytics SDK
|
||||
classpath 'io.fabric.tools:gradle:1.26.1'
|
||||
// 性能监控
|
||||
///classpath 'com.google.firebase:firebase-plugins:1.1.5'
|
||||
>>>>>>> develop
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
@ -15,6 +33,10 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
//Crashlytics SDK
|
||||
maven {
|
||||
url 'https://maven.google.com/'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||
|
4
android/key.properties
Normal file
@ -0,0 +1,4 @@
|
||||
storePassword=fluttergo123
|
||||
keyPassword=fluttergo123
|
||||
keyAlias=key
|
||||
storeFile=/Users/xj.deng/key.jks
|
BIN
assets/images/ali_connors.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
flutter_01.png
Normal file
After Width: | Height: | Size: 41 KiB |
@ -29,6 +29,7 @@
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 94722E5B22511D3600F63900 /* GoogleService-Info.plist */; };
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
|
||||
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||
@ -78,6 +79,7 @@
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
94722E5B22511D3600F63900 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
|
||||
@ -87,6 +89,8 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DDA792F029EDD7A11295D192 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -129,6 +133,8 @@
|
||||
0C172CA58CDB230D5DA80034 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CBA6E34746642008D95A119D /* Pods-Runner.debug.xcconfig */,
|
||||
A9941E6EA19A9CEF6B117A70 /* Pods-Runner.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
@ -178,6 +184,7 @@
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
94722E5B22511D3600F63900 /* GoogleService-Info.plist */,
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
@ -236,7 +243,8 @@
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
DevelopmentTeam = RDJKXT446D;
|
||||
DevelopmentTeam = 4WLT68XRNA;
|
||||
ProvisioningStyle = Manual;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -245,6 +253,7 @@
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
@ -282,6 +291,10 @@
|
||||
0828E49B220692B500A59437 /* iPad Landscape@2x.png in Resources */,
|
||||
0828E495220692B500A59437 /* iPhone Portrait-Retina 4.png in Resources */,
|
||||
0828E498220692B500A59437 /* iPhone XS Max Portrait.png in Resources */,
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
94722E5C22511D3600F63900 /* GoogleService-Info.plist in Resources */,
|
||||
>>>>>>> develop
|
||||
0828E496220692B500A59437 /* iPad Portrait.png in Resources */,
|
||||
0828E49C220692B500A59437 /* iPhone Landscape-Retina HD 5.5.png in Resources */,
|
||||
);
|
||||
@ -309,15 +322,11 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
@ -345,15 +354,11 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||
);
|
||||
@ -509,8 +514,12 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
>>>>>>> develop
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = RDJKXT446D;
|
||||
DEVELOPMENT_TEAM = 4WLT68XRNA;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -522,8 +531,13 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
<<<<<<< HEAD
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ali.flutterRookieBook;
|
||||
=======
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
|
||||
>>>>>>> develop
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "FlutterGO-alibaba-develop";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
@ -534,8 +548,13 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = Launch2;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
>>>>>>> develop
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = RDJKXT446D;
|
||||
DEVELOPMENT_TEAM = 4WLT68XRNA;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -547,8 +566,13 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
<<<<<<< HEAD
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.ali.flutterRookieBook;
|
||||
=======
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.fluttergo;
|
||||
>>>>>>> develop
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = FlutterGO_alibaba_distribution_ad_hoc;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
|
@ -42,7 +42,7 @@
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,10 +1,15 @@
|
||||
#include "AppDelegate.h"
|
||||
#include "GeneratedPluginRegistrant.h"
|
||||
|
||||
@import Firebase;//增加 firebase 支持
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
[FIRApp configure];//增加 firebase 支持
|
||||
|
||||
[GeneratedPluginRegistrant registerWithRegistry:self];
|
||||
// Override point for customization after application launch.
|
||||
[NSThread sleepForTimeInterval:2];
|
||||
|
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/1024*1024@as.png
Normal file
After Width: | Height: | Size: 112 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/120*120@2x-1.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/120*120@2x.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/152*152.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/167*167.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/180*180@3x.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/20*20.png
Normal file
After Width: | Height: | Size: 725 B |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/29*29@1x-2.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/29*29@1x.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/40*40@1x-1.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/40*40@1x-2.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/40*40@1x.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/58*58@2x-1.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/58*58@2x.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/60*60@3x.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/76*76.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/80*80@2x-1.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/80*80@2x.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/87*87.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
@ -3,115 +3,115 @@
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"filename" : "40*40@1x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"filename" : "60*60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"filename" : "29*29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"filename" : "58*58@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"filename" : "87*87.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"filename" : "80*80@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"filename" : "120*120@2x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"filename" : "120*120@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"filename" : "180*180@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"filename" : "20*20.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"filename" : "40*40@1x-2.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"filename" : "29*29@1x-2.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"filename" : "58*58@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"filename" : "40*40@1x-1.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"filename" : "80*80@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"filename" : "76*76.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"filename" : "152*152.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"filename" : "167*167.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"filename" : "1024*1024@as.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.5 KiB |
36
ios/Runner/GoogleService-Info.plist
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CLIENT_ID</key>
|
||||
<string>611157827052-0n777p43lrtr2dpo7gco5o3lffu7a7r4.apps.googleusercontent.com</string>
|
||||
<key>REVERSED_CLIENT_ID</key>
|
||||
<string>com.googleusercontent.apps.611157827052-0n777p43lrtr2dpo7gco5o3lffu7a7r4</string>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyDztt5Q9D7plAc8VqNtHumAci6BaoOiTg4</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>611157827052</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.alibaba.fluttergo</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>alibaba-flutter-go</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>alibaba-flutter-go.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:611157827052:ios:c6129e5eff2f125d</string>
|
||||
<key>DATABASE_URL</key>
|
||||
<string>https://alibaba-flutter-go.firebaseio.com</string>
|
||||
</dict>
|
||||
</plist>
|
@ -3,6 +3,7 @@
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
<<<<<<< HEAD
|
||||
"minimum-system-version" : "7.0",
|
||||
"extent" : "full-screen",
|
||||
"scale" : "2x"
|
||||
@ -12,11 +13,16 @@
|
||||
"idiom" : "ipad",
|
||||
"minimum-system-version" : "7.0",
|
||||
"extent" : "full-screen",
|
||||
=======
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
>>>>>>> develop
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
<<<<<<< HEAD
|
||||
"minimum-system-version" : "7.0",
|
||||
"extent" : "full-screen",
|
||||
"scale" : "2x"
|
||||
@ -40,6 +46,25 @@
|
||||
"minimum-system-version" : "7.0",
|
||||
"extent" : "full-screen",
|
||||
"scale" : "1x"
|
||||
=======
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
>>>>>>> develop
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
35
lib/blocs/bak/search_api.dart
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:20 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'dart:convert';
|
||||
import './search_result.dart';
|
||||
import 'package:html/parser.dart' show parse;
|
||||
|
||||
var dio = new Dio();
|
||||
class Api {
|
||||
Future<List<SearchResult>> search(name) async {
|
||||
print('=========>>>');
|
||||
var response = await dio.get("https://www.so.com/s?ie=utf-8&q=$name");
|
||||
// var document = parse(response.data);
|
||||
// var app = document.querySelectorAll('.res-title a');
|
||||
List<SearchResult> res = [];
|
||||
// app.forEach((f) {
|
||||
// res.add(
|
||||
// SearchResult(
|
||||
// title: f.text,
|
||||
// source: f.attributes["data-url"] ?? f.attributes["href"],
|
||||
// ),
|
||||
// );
|
||||
// });
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
Api api = Api();
|
35
lib/blocs/bak/search_bloc.dart
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:17 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
import 'dart:async';
|
||||
import 'package:bloc/bloc.dart';
|
||||
|
||||
import './search_event.dart';
|
||||
import './search_state.dart';
|
||||
import './search_api.dart';
|
||||
|
||||
|
||||
/// 这里导入api类与上面的SearchEvent与SearchState文件
|
||||
|
||||
class SearchBloc extends Bloc<SearchEvent, SearchState> {
|
||||
@override
|
||||
SearchState get initialState => SearchUninitialized();
|
||||
|
||||
@override
|
||||
Stream<SearchState> mapEventToState(SearchEvent event,) async* {
|
||||
if (event is SearchFetch) {
|
||||
try {
|
||||
yield SearchLoading();
|
||||
final res = await api.search(event.query);
|
||||
yield SearchLoaded(res: res);
|
||||
} catch (_) {
|
||||
yield SearchError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
lib/blocs/bak/search_event.dart
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:18 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
abstract class SearchEvent {}
|
||||
|
||||
class SearchFetch extends SearchEvent {
|
||||
final String query;
|
||||
|
||||
SearchFetch({this.query});
|
||||
|
||||
@override
|
||||
String toString() => 'SearchFetch:获取搜索结果事件';
|
||||
}
|
14
lib/blocs/bak/search_result.dart
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:11 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
class SearchResult {
|
||||
String title;
|
||||
String source;
|
||||
|
||||
SearchResult({this.title, this.source});
|
||||
}
|
37
lib/blocs/bak/search_state.dart
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:13 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
import './search_result.dart';
|
||||
|
||||
abstract class SearchState {}
|
||||
|
||||
class SearchError extends SearchState {
|
||||
@override
|
||||
String toString() => 'SearchError:获取失败';
|
||||
}
|
||||
|
||||
class SearchUninitialized extends SearchState {
|
||||
@override
|
||||
String toString() => 'SearchUninitialized:未初始化';
|
||||
}
|
||||
|
||||
class SearchLoading extends SearchState {
|
||||
@override
|
||||
String toString() => 'SearchLoading :正在加载';
|
||||
}
|
||||
|
||||
class SearchLoaded extends SearchState {
|
||||
final List<SearchResult> res;
|
||||
|
||||
SearchLoaded({
|
||||
this.res,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => 'SearchLoaded:加载完毕';
|
||||
}
|
80
lib/blocs/bak/search_widget.dart
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:19 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
//import 'package:suiyi/blocs/search/bloc.dart';
|
||||
import './search_event.dart';
|
||||
import './search_state.dart';
|
||||
import './search_bloc.dart';
|
||||
|
||||
|
||||
class SearchWidget extends StatefulWidget {
|
||||
final SearchDelegate delegate;
|
||||
final String query;
|
||||
SearchWidget({this.delegate, this.query});
|
||||
@override
|
||||
_SearchWidgetState createState() => _SearchWidgetState();
|
||||
}
|
||||
|
||||
class _SearchWidgetState extends State<SearchWidget> {
|
||||
final SearchBloc _search = SearchBloc();
|
||||
String old;
|
||||
@override
|
||||
void dispose() {
|
||||
_search.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print('1:${old}');
|
||||
print('2:${widget.query}');
|
||||
if (old != widget.query) {
|
||||
_search.dispatch(SearchFetch(query: widget.query));
|
||||
old = widget.query;
|
||||
}
|
||||
return BlocBuilder(
|
||||
bloc: _search,
|
||||
builder: (BuildContext context, SearchState state) {
|
||||
print('-------${state}');
|
||||
if (state is SearchUninitialized || state is SearchLoading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else if (state is SearchError) {
|
||||
return Center(
|
||||
child: Text('获取失败'),
|
||||
);
|
||||
} else if (state is SearchLoaded) {
|
||||
return ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
leading: Icon(
|
||||
Icons.bookmark_border,
|
||||
size: 32,
|
||||
),
|
||||
title: Text(
|
||||
state.res[index].title,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: Text(state.res[index].source),
|
||||
onTap: () {
|
||||
// 在这里对选中的结果进行解析,因为我目前是用golang实现的,所以就没贴代码了。
|
||||
print(state.res[index].source);
|
||||
},
|
||||
);
|
||||
},
|
||||
itemCount: state.res.length,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
71
lib/blocs/industry_api.dart
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:20 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget: FlatButton 的示例
|
||||
*/
|
||||
import 'dart:async';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:html/parser.dart' show parse;
|
||||
import './industry_model.dart';
|
||||
import './search_result.dart';
|
||||
|
||||
var dio = new Dio();
|
||||
//class Api2 {
|
||||
// /// 关键字提示(起点)
|
||||
// Future<List<String>> suggestion(String query) async {
|
||||
//// http.Response response = await http.get(
|
||||
//// "https://www.qidian.com/ajax/Search/AutoComplete?siteid=1&query=$query");
|
||||
// var response = await dio.get("https://www.qidian.com/ajax/Search/AutoComplete?siteid=1&query=$query", data: {});
|
||||
// //var response = await dio.get("https://www.so.com/s?ie=utf-8&q=$query");
|
||||
// print('1=====>${query}');
|
||||
// print('2=====>${response.data}');
|
||||
// //var data = Suggestion.fromJson(json.decode(response.body));
|
||||
// //var data = Suggestion.fromJson(json.decode(response.data));
|
||||
// var data = Suggestion.fromJson(json.decode(response.data));
|
||||
// List<String> suggestion = [];
|
||||
// data.suggestions.forEach((k) {
|
||||
// //print('=====>${k.value}');
|
||||
// suggestion.add(k.value);
|
||||
// });
|
||||
//
|
||||
// return Future.delayed(Duration(seconds:2), () {
|
||||
// return suggestion;
|
||||
// });
|
||||
// //return suggestion;
|
||||
// }
|
||||
//}
|
||||
class Api {
|
||||
/// 关键字提示(起点)
|
||||
Future<List<SearchResult>> suggestion(String query) async {
|
||||
// http.Response response = await http.get(
|
||||
// "https://www.qidian.com/ajax/Search/AutoComplete?siteid=1&query=$query");
|
||||
/// var response = await dio.get("https://www.qidian.com/ajax/Search/AutoComplete?siteid=1&query=$query", data: {});
|
||||
var response = await dio.get("https://www.so.com/s?ie=utf-8&q=$query flutter");
|
||||
var document = parse(response.data);
|
||||
var app = document.querySelectorAll('.res-title a');
|
||||
///print('1=====>${query}');
|
||||
///print('2=====>${response.data}');
|
||||
////print('3=====>${app}');
|
||||
List<SearchResult> res = [];
|
||||
app.forEach((f) {
|
||||
///print('f==>${f}');
|
||||
res.add(
|
||||
SearchResult(
|
||||
title: f.text,
|
||||
source: f.attributes["data-url"] ?? f.attributes["href"],
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
return Future.delayed(Duration(seconds:2), () {
|
||||
return res;
|
||||
});
|
||||
//return suggestion;
|
||||
}
|
||||
}
|
||||
|
||||
Api api = Api();
|
41
lib/blocs/industry_bloc.dart
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 5:19 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
import 'dart:async';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import './industry_api.dart';
|
||||
import './industry_event.dart';
|
||||
import './industry_state.dart';
|
||||
|
||||
class SuggestionBloc extends Bloc<SuggestionEvent, SuggestionState> {
|
||||
@override
|
||||
SuggestionState get initialState => SuggestionUninitialized();
|
||||
@override
|
||||
Stream<SuggestionState> mapEventToState(SuggestionEvent event)async* {
|
||||
//Stream<SuggestionState> mapEventToState(SuggestionState currentState, SuggestionEvent event,) async* {
|
||||
if (event is SuggestionFetch) {
|
||||
//print('event==>${event}');
|
||||
try {
|
||||
yield SuggestionLoading();
|
||||
final res = await api.suggestion(event.query);
|
||||
print('res====>${res}');
|
||||
yield SuggestionLoaded(res: res);
|
||||
} catch (_) {
|
||||
yield SuggestionError();
|
||||
}
|
||||
}
|
||||
if (event is SuggestionClearFetch) {
|
||||
//print('event==>${event}');
|
||||
try {
|
||||
yield SuggestionUninitialized();
|
||||
} catch (_) {
|
||||
yield SuggestionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
lib/blocs/industry_event.dart
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:35 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
*/
|
||||
abstract class SuggestionEvent {}
|
||||
|
||||
class SuggestionFetch extends SuggestionEvent {
|
||||
final String query;
|
||||
|
||||
SuggestionFetch({this.query});
|
||||
|
||||
@override
|
||||
String toString() => 'SuggestionFetch:获取关键字提示事件';
|
||||
}
|
||||
|
||||
class SuggestionClearFetch extends SuggestionEvent {
|
||||
final String query;
|
||||
|
||||
SuggestionClearFetch({this.query});
|
||||
|
||||
@override
|
||||
String toString() => 'SuggestionClearFetch:清空界面';
|
||||
}
|
79
lib/blocs/industry_main.dart
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:52 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import './industry_bloc.dart';
|
||||
import './industry_event.dart';
|
||||
import './industry_state.dart';
|
||||
|
||||
final SuggestionBloc suggestion = SuggestionBloc();
|
||||
|
||||
class IndustryPage extends StatefulWidget {
|
||||
final Function itemTitle;
|
||||
IndustryPage({Key key,this.itemTitle}) : super(key: key);
|
||||
|
||||
@override
|
||||
_IndustryState createState() => _IndustryState();
|
||||
}
|
||||
|
||||
class _IndustryState extends State<IndustryPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Column(
|
||||
children: [
|
||||
// TextField(
|
||||
// autofocus: true,
|
||||
// textAlign: TextAlign.center,
|
||||
// onSubmitted: (text) {
|
||||
// print('onSubmitted:${text}');
|
||||
// suggestion.dispatch(SuggestionFetch(query: text));
|
||||
// },
|
||||
// ),
|
||||
Expanded(
|
||||
child: BlocBuilder(
|
||||
bloc: suggestion,
|
||||
builder: (BuildContext context, SuggestionState state) {
|
||||
print('BlocBuilder----${state}');
|
||||
if (state is SuggestionUninitialized) {
|
||||
return Center(
|
||||
child: Text('暂无内容'),
|
||||
);
|
||||
} else if (state is SuggestionLoading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else if (state is SuggestionError) {
|
||||
return Center(
|
||||
child: Text('出现错误'),
|
||||
);
|
||||
} else if (state is SuggestionLoaded) {
|
||||
if (state.res.length == 0) {
|
||||
return Center(
|
||||
child: Text('没有适合的结果,更换查询条件试试'),
|
||||
);
|
||||
}else {
|
||||
if (widget.itemTitle is Function) {
|
||||
return widget.itemTitle(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
//suggestion.dispose();//添加这个第二次进入会失灵
|
||||
super.dispose();
|
||||
}
|
||||
}
|
72
lib/blocs/industry_model.dart
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:19 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
*/
|
||||
class Suggestion {
|
||||
String query;
|
||||
List<Suggestions> suggestions;
|
||||
int code;
|
||||
|
||||
Suggestion({this.query, this.suggestions, this.code});
|
||||
|
||||
Suggestion.fromJson(Map<String, dynamic> json) {
|
||||
query = json['query'];
|
||||
if (json['suggestions'] != null) {
|
||||
suggestions = new List<Suggestions>();
|
||||
json['suggestions'].forEach((v) {
|
||||
suggestions.add(new Suggestions.fromJson(v));
|
||||
});
|
||||
}
|
||||
code = json['code'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['query'] = this.query;
|
||||
if (this.suggestions != null) {
|
||||
data['suggestions'] = this.suggestions.map((v) => v.toJson()).toList();
|
||||
}
|
||||
data['code'] = this.code;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Suggestions {
|
||||
Data data;
|
||||
String value;
|
||||
|
||||
Suggestions({this.data, this.value});
|
||||
|
||||
Suggestions.fromJson(Map<String, dynamic> json) {
|
||||
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
|
||||
value = json['value'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
if (this.data != null) {
|
||||
data['data'] = this.data.toJson();
|
||||
}
|
||||
data['value'] = this.value;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
String category;
|
||||
|
||||
Data({this.category});
|
||||
|
||||
Data.fromJson(Map<String, dynamic> json) {
|
||||
category = json['category'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['category'] = this.category;
|
||||
return data;
|
||||
}
|
||||
}
|
34
lib/blocs/industry_state.dart
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 3:37 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
*/
|
||||
abstract class SuggestionState {}
|
||||
|
||||
class SuggestionError extends SuggestionState {
|
||||
@override
|
||||
String toString() => 'SuggestionError:获取失败';
|
||||
}
|
||||
|
||||
class SuggestionUninitialized extends SuggestionState {
|
||||
@override
|
||||
String toString() => 'SuggestionUninitialized:未初始化';
|
||||
}
|
||||
|
||||
class SuggestionLoading extends SuggestionState {
|
||||
@override
|
||||
String toString() => 'SuggestionLoading :正在加载';
|
||||
}
|
||||
|
||||
class SuggestionLoaded extends SuggestionState {
|
||||
final List res;
|
||||
|
||||
SuggestionLoaded({
|
||||
this.res,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => 'SuggestionLoaded:加载完毕';
|
||||
}
|
14
lib/blocs/search_result.dart
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Created with Android Studio.
|
||||
* User: 一晟
|
||||
* Date: 2019/4/28
|
||||
* Time: 7:11 PM
|
||||
* email: zhu.yan@alibaba-inc.com
|
||||
* tartget:
|
||||
*/
|
||||
class SearchResult {
|
||||
String title;
|
||||
String source;
|
||||
|
||||
SearchResult({this.title, this.source});
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
//颜色配置
|
||||
class AppColor{
|
||||
static const int white = 0xFFFFFFFF;
|
||||
static const int mainTextColor = 0xFF121917;
|
||||
static const int subTextColor = 0xff959595;
|
||||
}
|
||||
|
||||
//文本设置
|
||||
class AppText{
|
||||
static const middleSize = 16.0;
|
||||
|
||||
static const middleText = TextStyle(
|
||||
color: Color(AppColor.mainTextColor),
|
||||
fontSize: middleSize,
|
||||
);
|
||||
|
||||
static const middleSubText = TextStyle(
|
||||
color: Color(AppColor.subTextColor),
|
||||
fontSize: middleSize,
|
||||
);
|
||||
}
|
||||
class WidgetDemoColor {
|
||||
static const int fontColor = 0xFF607173;
|
||||
static const int iconColor = 0xFF607173;
|
||||
static const int borderColor = 0xFFEFEFEF;
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
|
||||
EventBus eventBus = new EventBus();
|
||||
|
||||
class MyEvent {
|
||||
String text;
|
||||
MyEvent(this.text);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2019-01-14 11:42:36
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2019-01-14 16:53:11
|
||||
*/
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import '../routers/application.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
Map<String, String> _exampleCode;
|
||||
String _code;
|
||||
|
||||
void _launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getExampleCode(context,String filePath, AssetBundle bundle) async {
|
||||
if (_exampleCode == null) await _parseExampleCode(context,filePath, bundle);
|
||||
return _code;
|
||||
}
|
||||
|
||||
Future<void> _parseExampleCode(context,String filePath, AssetBundle bundle) async {
|
||||
String code;
|
||||
try {
|
||||
code = await bundle.loadString('lib/widgets/$filePath');
|
||||
} catch (err) {
|
||||
Navigator.of(context).pop();
|
||||
_launchURL(Application.github['widgetsURL'] + filePath);
|
||||
}
|
||||
_code = code;
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* @Author: 一凨
|
||||
* @Date: 2019-01-14 11:42:32
|
||||
* @Last Modified by: 一凨
|
||||
* @Last Modified time: 2019-01-14 14:42:00
|
||||
*/
|
||||
import 'package:flutter/material.dart';
|
||||
import 'example_code_parser.dart';
|
||||
import 'syntax_highlighter.dart';
|
||||
|
||||
class FullScreenCodeDialog extends StatefulWidget {
|
||||
const FullScreenCodeDialog({this.filePath});
|
||||
|
||||
final String filePath;
|
||||
_FullScreenCodeDialogState createState() => _FullScreenCodeDialogState();
|
||||
}
|
||||
|
||||
class _FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
|
||||
String _exampleCode;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
getExampleCode(context,'${widget.filePath}', DefaultAssetBundle.of(context))
|
||||
.then<void>((String code) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_exampleCode = code ?? 'Example code not found';
|
||||
});
|
||||
}
|
||||
});
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final SyntaxHighlighterStyle style =
|
||||
Theme.of(context).brightness == Brightness.dark
|
||||
? SyntaxHighlighterStyle.darkThemeStyle()
|
||||
: SyntaxHighlighterStyle.lightThemeStyle();
|
||||
|
||||
Widget body;
|
||||
if (_exampleCode == null) {
|
||||
body = const Center(child: CircularProgressIndicator());
|
||||
} else {
|
||||
body = SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: const TextStyle(fontFamily: 'monospace', fontSize: 10.0),
|
||||
children: <TextSpan>[
|
||||
DartSyntaxHighlighter(style).format(_exampleCode)
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.clear,
|
||||
semanticLabel: 'Close',
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
title: const Text('Example code'),
|
||||
),
|
||||
body: body);
|
||||
}
|
||||
}
|
@ -1,359 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:string_scanner/string_scanner.dart';
|
||||
|
||||
/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
|
||||
/// DartSyntaxHighlighter(style).format(source)
|
||||
|
||||
class SyntaxHighlighterStyle {
|
||||
SyntaxHighlighterStyle({
|
||||
this.baseStyle,
|
||||
this.numberStyle,
|
||||
this.commentStyle,
|
||||
this.keywordStyle,
|
||||
this.stringStyle,
|
||||
this.punctuationStyle,
|
||||
this.classStyle,
|
||||
this.constantStyle
|
||||
});
|
||||
|
||||
static SyntaxHighlighterStyle lightThemeStyle() {
|
||||
return SyntaxHighlighterStyle(
|
||||
baseStyle: const TextStyle(color: Color(0xFF000000)),
|
||||
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
|
||||
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
|
||||
keywordStyle: const TextStyle(color: Color(0xFF9C27B0)),
|
||||
stringStyle: const TextStyle(color: Color(0xFF43A047)),
|
||||
punctuationStyle: const TextStyle(color: Color(0xFF000000)),
|
||||
classStyle: const TextStyle(color: Color(0xFF512DA8)),
|
||||
constantStyle: const TextStyle(color: Color(0xFF795548))
|
||||
);
|
||||
}
|
||||
|
||||
static SyntaxHighlighterStyle darkThemeStyle() {
|
||||
return SyntaxHighlighterStyle(
|
||||
baseStyle: const TextStyle(color: Color(0xFFFFFFFF)),
|
||||
numberStyle: const TextStyle(color: Color(0xFF1565C0)),
|
||||
commentStyle: const TextStyle(color: Color(0xFF9E9E9E)),
|
||||
keywordStyle: const TextStyle(color: Color(0xFF80CBC4)),
|
||||
stringStyle: const TextStyle(color: Color(0xFF009688)),
|
||||
punctuationStyle: const TextStyle(color: Color(0xFFFFFFFF)),
|
||||
classStyle: const TextStyle(color: Color(0xFF009688)),
|
||||
constantStyle: const TextStyle(color: Color(0xFF795548))
|
||||
);
|
||||
}
|
||||
|
||||
final TextStyle baseStyle;
|
||||
final TextStyle numberStyle;
|
||||
final TextStyle commentStyle;
|
||||
final TextStyle keywordStyle;
|
||||
final TextStyle stringStyle;
|
||||
final TextStyle punctuationStyle;
|
||||
final TextStyle classStyle;
|
||||
final TextStyle constantStyle;
|
||||
}
|
||||
|
||||
abstract class Highlighter { // ignore: one_member_abstracts
|
||||
TextSpan format(String src);
|
||||
}
|
||||
|
||||
class DartSyntaxHighlighter extends Highlighter {
|
||||
DartSyntaxHighlighter([this._style]) {
|
||||
_spans = <_HighlightSpan>[];
|
||||
_style ??= SyntaxHighlighterStyle.darkThemeStyle();
|
||||
}
|
||||
|
||||
SyntaxHighlighterStyle _style;
|
||||
|
||||
static const List<String> _keywords = <String>[
|
||||
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
|
||||
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
|
||||
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
|
||||
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
|
||||
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
|
||||
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
|
||||
'void', 'while', 'with', 'yield'
|
||||
];
|
||||
|
||||
static const List<String> _builtInTypes = <String>[
|
||||
'int', 'double', 'num', 'bool'
|
||||
];
|
||||
|
||||
String _src;
|
||||
StringScanner _scanner;
|
||||
|
||||
List<_HighlightSpan> _spans;
|
||||
|
||||
@override
|
||||
TextSpan format(String src) {
|
||||
_src = src;
|
||||
_scanner = StringScanner(_src);
|
||||
|
||||
if (_generateSpans()) {
|
||||
// Successfully parsed the code
|
||||
final List<TextSpan> formattedText = <TextSpan>[];
|
||||
int currentPosition = 0;
|
||||
|
||||
for (_HighlightSpan span in _spans) {
|
||||
if (currentPosition != span.start)
|
||||
formattedText.add(TextSpan(text: _src.substring(currentPosition, span.start)));
|
||||
|
||||
formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
|
||||
|
||||
currentPosition = span.end;
|
||||
}
|
||||
|
||||
if (currentPosition != _src.length)
|
||||
formattedText.add(TextSpan(text: _src.substring(currentPosition, _src.length)));
|
||||
|
||||
return TextSpan(style: _style.baseStyle, children: formattedText);
|
||||
} else {
|
||||
// Parsing failed, return with only basic formatting
|
||||
return TextSpan(style: _style.baseStyle, text: src);
|
||||
}
|
||||
}
|
||||
|
||||
bool _generateSpans() {
|
||||
int lastLoopPosition = _scanner.position;
|
||||
|
||||
while (!_scanner.isDone) {
|
||||
// Skip White space
|
||||
_scanner.scan(RegExp(r'\s+'));
|
||||
|
||||
// Block comments
|
||||
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.comment,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Line comments
|
||||
if (_scanner.scan('//')) {
|
||||
final int startComment = _scanner.lastMatch.start;
|
||||
|
||||
bool eof = false;
|
||||
int endComment;
|
||||
if (_scanner.scan(RegExp(r'.*\n'))) {
|
||||
endComment = _scanner.lastMatch.end - 1;
|
||||
} else {
|
||||
eof = true;
|
||||
endComment = _src.length;
|
||||
}
|
||||
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.comment,
|
||||
startComment,
|
||||
endComment
|
||||
));
|
||||
|
||||
if (eof)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Raw r"String"
|
||||
if (_scanner.scan(RegExp(r'r".*"'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Raw r'String'
|
||||
if (_scanner.scan(RegExp(r"r'.*'"))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Multiline """String"""
|
||||
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Multiline '''String'''
|
||||
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// "String"
|
||||
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 'String'
|
||||
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.string,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Double
|
||||
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.number,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Integer
|
||||
if (_scanner.scan(RegExp(r'\d+'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.number,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Punctuation
|
||||
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.punctuation,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Meta data
|
||||
if (_scanner.scan(RegExp(r'@\w+'))) {
|
||||
_spans.add(_HighlightSpan(
|
||||
_HighlightType.keyword,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Words
|
||||
if (_scanner.scan(RegExp(r'\w+'))) {
|
||||
_HighlightType type;
|
||||
|
||||
String word = _scanner.lastMatch[0];
|
||||
if (word.startsWith('_'))
|
||||
word = word.substring(1);
|
||||
|
||||
if (_keywords.contains(word))
|
||||
type = _HighlightType.keyword;
|
||||
else if (_builtInTypes.contains(word))
|
||||
type = _HighlightType.keyword;
|
||||
else if (_firstLetterIsUpperCase(word))
|
||||
type = _HighlightType.klass;
|
||||
else if (word.length >= 2 && word.startsWith('k') && _firstLetterIsUpperCase(word.substring(1)))
|
||||
type = _HighlightType.constant;
|
||||
|
||||
if (type != null) {
|
||||
_spans.add(_HighlightSpan(
|
||||
type,
|
||||
_scanner.lastMatch.start,
|
||||
_scanner.lastMatch.end
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this loop did anything
|
||||
if (lastLoopPosition == _scanner.position) {
|
||||
// Failed to parse this file, abort gracefully
|
||||
return false;
|
||||
}
|
||||
lastLoopPosition = _scanner.position;
|
||||
}
|
||||
|
||||
_simplify();
|
||||
return true;
|
||||
}
|
||||
|
||||
void _simplify() {
|
||||
for (int i = _spans.length - 2; i >= 0; i -= 1) {
|
||||
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
|
||||
_spans[i] = _HighlightSpan(
|
||||
_spans[i].type,
|
||||
_spans[i].start,
|
||||
_spans[i + 1].end
|
||||
);
|
||||
_spans.removeAt(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _firstLetterIsUpperCase(String str) {
|
||||
if (str.isNotEmpty) {
|
||||
final String first = str.substring(0, 1);
|
||||
return first == first.toUpperCase();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
enum _HighlightType {
|
||||
number,
|
||||
comment,
|
||||
keyword,
|
||||
string,
|
||||
punctuation,
|
||||
klass,
|
||||
constant
|
||||
}
|
||||
|
||||
class _HighlightSpan {
|
||||
_HighlightSpan(this.type, this.start, this.end);
|
||||
final _HighlightType type;
|
||||
final int start;
|
||||
final int end;
|
||||
|
||||
String textForSpan(String src) {
|
||||
return src.substring(start, end);
|
||||
}
|
||||
|
||||
TextStyle textStyle(SyntaxHighlighterStyle style) {
|
||||
if (type == _HighlightType.number)
|
||||
return style.numberStyle;
|
||||
else if (type == _HighlightType.comment)
|
||||
return style.commentStyle;
|
||||
else if (type == _HighlightType.keyword)
|
||||
return style.keywordStyle;
|
||||
else if (type == _HighlightType.string)
|
||||
return style.stringStyle;
|
||||
else if (type == _HighlightType.punctuation)
|
||||
return style.punctuationStyle;
|
||||
else if (type == _HighlightType.klass)
|
||||
return style.classStyle;
|
||||
else if (type == _HighlightType.constant)
|
||||
return style.constantStyle;
|
||||
else
|
||||
return style.baseStyle;
|
||||
}
|
||||
}
|