Commit f6538347 authored by 关振斌's avatar 关振斌

init getx

parent 70214295
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>IconFont Demo</title>
<link rel="shortcut icon" href="https://gtms04.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">&#xe86b;</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=1707468" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe60d;</span>
<div class="name">share</div>
<div class="code-name">&amp;#xe60d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe60c;</span>
<div class="name">fav</div>
<div class="code-name">&amp;#xe60c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe605;</span>
<div class="name">social-linkedin</div>
<div class="code-name">&amp;#xe605;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe606;</span>
<div class="name">social-apple</div>
<div class="code-name">&amp;#xe606;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe607;</span>
<div class="name">social-octocat</div>
<div class="code-name">&amp;#xe607;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe608;</span>
<div class="name">social-reddit</div>
<div class="code-name">&amp;#xe608;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe609;</span>
<div class="name">social-snapchat</div>
<div class="code-name">&amp;#xe609;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe60a;</span>
<div class="name">social-skype</div>
<div class="code-name">&amp;#xe60a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe60b;</span>
<div class="name">social-twitter</div>
<div class="code-name">&amp;#xe60b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe604;</span>
<div class="name">me</div>
<div class="code-name">&amp;#xe604;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe603;</span>
<div class="name">tag</div>
<div class="code-name">&amp;#xe603;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe602;</span>
<div class="name">grid</div>
<div class="code-name">&amp;#xe602;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe601;</span>
<div class="name">home</div>
<div class="code-name">&amp;#xe601;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.eot');
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'),
url('iconfont.svg#iconfont') format('svg');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont iconshare"></span>
<div class="name">
share
</div>
<div class="code-name">.iconshare
</div>
</li>
<li class="dib">
<span class="icon iconfont iconfav"></span>
<div class="name">
fav
</div>
<div class="code-name">.iconfav
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsociallinkedin"></span>
<div class="name">
social-linkedin
</div>
<div class="code-name">.iconsociallinkedin
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialapple"></span>
<div class="name">
social-apple
</div>
<div class="code-name">.iconsocialapple
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialoctocat"></span>
<div class="name">
social-octocat
</div>
<div class="code-name">.iconsocialoctocat
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialreddit"></span>
<div class="name">
social-reddit
</div>
<div class="code-name">.iconsocialreddit
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialsnapchat"></span>
<div class="name">
social-snapchat
</div>
<div class="code-name">.iconsocialsnapchat
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialskype"></span>
<div class="name">
social-skype
</div>
<div class="code-name">.iconsocialskype
</div>
</li>
<li class="dib">
<span class="icon iconfont iconsocialtwitter"></span>
<div class="name">
social-twitter
</div>
<div class="code-name">.iconsocialtwitter
</div>
</li>
<li class="dib">
<span class="icon iconfont iconme"></span>
<div class="name">
me
</div>
<div class="code-name">.iconme
</div>
</li>
<li class="dib">
<span class="icon iconfont icontag"></span>
<div class="name">
tag
</div>
<div class="code-name">.icontag
</div>
</li>
<li class="dib">
<span class="icon iconfont icongrid"></span>
<div class="name">
grid
</div>
<div class="code-name">.icongrid
</div>
</li>
<li class="dib">
<span class="icon iconfont iconhome"></span>
<div class="name">
home
</div>
<div class="code-name">.iconhome
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont iconxxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconshare"></use>
</svg>
<div class="name">share</div>
<div class="code-name">#iconshare</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconfav"></use>
</svg>
<div class="name">fav</div>
<div class="code-name">#iconfav</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsociallinkedin"></use>
</svg>
<div class="name">social-linkedin</div>
<div class="code-name">#iconsociallinkedin</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialapple"></use>
</svg>
<div class="name">social-apple</div>
<div class="code-name">#iconsocialapple</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialoctocat"></use>
</svg>
<div class="name">social-octocat</div>
<div class="code-name">#iconsocialoctocat</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialreddit"></use>
</svg>
<div class="name">social-reddit</div>
<div class="code-name">#iconsocialreddit</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialsnapchat"></use>
</svg>
<div class="name">social-snapchat</div>
<div class="code-name">#iconsocialsnapchat</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialskype"></use>
</svg>
<div class="name">social-skype</div>
<div class="code-name">#iconsocialskype</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconsocialtwitter"></use>
</svg>
<div class="name">social-twitter</div>
<div class="code-name">#iconsocialtwitter</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconme"></use>
</svg>
<div class="name">me</div>
<div class="code-name">#iconme</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icontag"></use>
</svg>
<div class="name">tag</div>
<div class="code-name">#icontag</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icongrid"></use>
</svg>
<div class="name">grid</div>
<div class="code-name">#icongrid</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#iconhome"></use>
</svg>
<div class="name">home</div>
<div class="code-name">#iconhome</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>
...@@ -78,6 +78,9 @@ PODS: ...@@ -78,6 +78,9 @@ PODS:
- fluttertoast (0.0.2): - fluttertoast (0.0.2):
- Flutter - Flutter
- Toast - Toast
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- GoogleUtilities/AppDelegateSwizzler (7.11.0): - GoogleUtilities/AppDelegateSwizzler (7.11.0):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/Logger - GoogleUtilities/Logger
...@@ -99,6 +102,8 @@ PODS: ...@@ -99,6 +102,8 @@ PODS:
- open_filex (0.0.2): - open_filex (0.0.2):
- Flutter - Flutter
- OrderedSet (5.0.0) - OrderedSet (5.0.0)
- package_info (0.0.1):
- Flutter
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
...@@ -112,6 +117,9 @@ PODS: ...@@ -112,6 +117,9 @@ PODS:
- FlutterMacOS - FlutterMacOS
- smart_auth (0.0.1): - smart_auth (0.0.1):
- Flutter - Flutter
- sqflite (0.0.2):
- Flutter
- FMDB (>= 2.7.5)
- SwiftyGif (5.4.4) - SwiftyGif (5.4.4)
- Toast (4.0.0) - Toast (4.0.0)
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
...@@ -133,9 +141,11 @@ DEPENDENCIES: ...@@ -133,9 +141,11 @@ DEPENDENCIES:
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- open_filex (from `.symlinks/plugins/open_filex/ios`) - open_filex (from `.symlinks/plugins/open_filex/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- smart_auth (from `.symlinks/plugins/smart_auth/ios`) - smart_auth (from `.symlinks/plugins/smart_auth/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
...@@ -147,6 +157,7 @@ SPEC REPOS: ...@@ -147,6 +157,7 @@ SPEC REPOS:
- FirebaseAuth - FirebaseAuth
- FirebaseCore - FirebaseCore
- FirebaseCoreInternal - FirebaseCoreInternal
- FMDB
- GoogleUtilities - GoogleUtilities
- GTMSessionFetcher - GTMSessionFetcher
- OrderedSet - OrderedSet
...@@ -183,12 +194,16 @@ EXTERNAL SOURCES: ...@@ -183,12 +194,16 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/image_picker_ios/ios" :path: ".symlinks/plugins/image_picker_ios/ios"
open_filex: open_filex:
:path: ".symlinks/plugins/open_filex/ios" :path: ".symlinks/plugins/open_filex/ios"
package_info:
:path: ".symlinks/plugins/package_info/ios"
path_provider_foundation: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios" :path: ".symlinks/plugins/path_provider_foundation/ios"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/ios" :path: ".symlinks/plugins/shared_preferences_foundation/ios"
smart_auth: smart_auth:
:path: ".symlinks/plugins/smart_auth/ios" :path: ".symlinks/plugins/smart_auth/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
url_launcher_ios: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
webview_flutter_wkwebview: webview_flutter_wkwebview:
...@@ -212,17 +227,20 @@ SPEC CHECKSUMS: ...@@ -212,17 +227,20 @@ SPEC CHECKSUMS:
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
fluttercontactpicker: d582836dea6b5d489f3d259f35d7817ae82ee5e6 fluttercontactpicker: d582836dea6b5d489f3d259f35d7817ae82ee5e6
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f
GTMSessionFetcher: c9e714f7eec91a55641e2bab9f45fd83a219b882 GTMSessionFetcher: c9e714f7eec91a55641e2bab9f45fd83a219b882
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4 open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: 8ab87d4b3e5cc4927bd47f78db6ceb0b94442577 SDWebImage: 8ab87d4b3e5cc4927bd47f78db6ceb0b94442577
shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
smart_auth: 4bedbc118723912d0e45a07e8ab34039c19e04f2 smart_auth: 4bedbc118723912d0e45a07e8ab34039c19e04f2
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
url_launcher_ios: fb12c43172927bb5cf75aeebd073f883801f1993 url_launcher_ios: fb12c43172927bb5cf75aeebd073f883801f1993
......
library apis;
export 'user.dart';
export 'news.dart';
import 'package:chart/common/entities/classFyDetail.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import '../../entity/plan_entity.dart';
import '../../entity/square_entity.dart';
/// 新闻
class NewsAPI {
/// 翻页
/// refresh 是否刷新
static Future<List<SearchRecordEntity>> newsPageList(
Map<String, int> params) async {
var response = await HttpUtil().get(
'/searchRecord/getSearchRecord/${params['page']}/${params['size']}',
);
return searchRecordEntityFromList(response.data);
}
/// 翻页
/// refresh 是否刷新
static Future<List<MessageEntity>?> bannerList() async {
var response = await HttpUtil().get(
'/hotSearch/getHotSearch',
);
return messageEntityFromList(response['data']);
// NewsPageListResponseEntity.fromJson(response);
}
/// 获取分类
static Future<List<ClassifyEntity>> bannerPage() async {
var response = await HttpUtil().get(
'/classify/getClassifyList',
);
return classifyEntityFromList(response['data']);
// NewsPageListResponseEntity.fromJson(response);
}
/// 分类详情
// / /api/classifyDetail/getClassifyDetailById/1
static Future<List<ClassifyDetialEntity>> classFyDetialList(
Map<String, int> params) async {
var response = await HttpUtil().get(
'/classifyDetail/getClassifyDetailById/${params['id']}',
);
return classifyDetialEntityFromList(response['data']);
// NewsPageListResponseEntity.fromJson(response);
}
// classFyDetialList
/// 推荐
static Future<NewsItem> newsRecommend({
NewsRecommendRequestEntity? params,
bool refresh = false,
bool cacheDisk = false,
}) async {
var response = await HttpUtil().get(
'/news/recommend',
queryParameters: params?.toJson(),
refresh: refresh,
cacheDisk: cacheDisk,
);
return NewsItem.fromJson(response);
}
/// 分类
static Future<List<CategoryResponseEntity>> categories({
bool cacheDisk = false,
}) async {
var response = await HttpUtil().get(
'/categories',
cacheDisk: cacheDisk,
);
return response
.map<CategoryResponseEntity>(
(item) => CategoryResponseEntity.fromJson(item))
.toList();
}
/// 频道
static Future<List<ChannelResponseEntity>> channels({
bool cacheDisk = false,
}) async {
var response = await HttpUtil().get(
'/channels',
cacheDisk: cacheDisk,
);
return response
.map<ChannelResponseEntity>(
(item) => ChannelResponseEntity.fromJson(item))
.toList();
}
/// 标签列表
static Future<List<TagResponseEntity>> tags({
TagRequestEntity? params,
bool cacheDisk = false,
}) async {
var response = await HttpUtil().get(
'/tags',
queryParameters: params?.toJson(),
cacheDisk: cacheDisk,
);
return response
.map<TagResponseEntity>((item) => TagResponseEntity.fromJson(item))
.toList();
}
}
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart';
/// 用户
class UserAPI {
/// 登录
static Future<UserLoginResponseEntity> login({
UserLoginRequestEntity? params,
}) async {
var response = await HttpUtil().post(
'/user/login',
data: params?.toJson(),
);
return UserLoginResponseEntity.fromJson(response);
}
/// 注册
static Future<UserRegisterRequestEntity> register({
UserRegisterRequestEntity? params,
}) async {
var response = await HttpUtil().post(
'/user/register',
data: params?.toJson(),
);
return UserRegisterRequestEntity.fromJson(response);
}
/// Profile
static Future<UserLoginResponseEntity> profile() async {
var response = await HttpUtil().post(
'/user/profile',
);
return UserLoginResponseEntity.fromJson(response);
}
/// Logout
static Future logout() async {
return await HttpUtil().post(
'/user/logout',
);
}
}
/*
app 升级
*/
class AppUpdateRequestEntity {
String? device;
String? channel;
String? architecture;
String? model;
AppUpdateRequestEntity({
this.device,
this.channel,
this.architecture,
this.model,
});
factory AppUpdateRequestEntity.fromJson(Map<String, dynamic> json) =>
AppUpdateRequestEntity(
device: json["device"],
channel: json["channel"],
architecture: json["architecture"],
model: json["model"],
);
Map<String, dynamic> toJson() => {
"device": device,
"channel": channel,
"architecture": architecture,
"model": model,
};
}
class AppUpdateResponseEntity {
String? shopUrl;
String? fileUrl;
String? latestVersion;
String? latestDescription;
AppUpdateResponseEntity({
this.shopUrl,
this.fileUrl,
this.latestVersion,
this.latestDescription,
});
factory AppUpdateResponseEntity.fromJson(Map<String, dynamic> json) =>
AppUpdateResponseEntity(
shopUrl: json["shopUrl"],
fileUrl: json["fileUrl"],
latestVersion: json["latestVersion"],
latestDescription: json["latestDescription"],
);
Map<String, dynamic> toJson() => {
"shopUrl": shopUrl,
"fileUrl": fileUrl,
"latestVersion": latestVersion,
"latestDescription": latestDescription,
};
}
/// 新闻分类 response
class CategoryResponseEntity {
String code;
String title;
CategoryResponseEntity({
required this.code,
required this.title,
});
factory CategoryResponseEntity.fromJson(Map<String, dynamic> json) =>
CategoryResponseEntity(
code: json["code"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"code": code,
"title": title,
};
}
/// 频道列表 response
class ChannelResponseEntity {
String code;
String title;
ChannelResponseEntity({
required this.code,
required this.title,
});
factory ChannelResponseEntity.fromJson(Map<String, dynamic> json) =>
ChannelResponseEntity(
code: json["code"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"code": code,
"title": title,
};
}
import 'dart:convert';
class ClassifyDetialEntity {
ClassifyDetialEntity({
required this.id,
required this.detailName,
required this.detailDesc,
required this.isShow,
required this.template,
});
final int id;
final String detailName;
final String detailDesc;
final int isShow;
final String template;
factory ClassifyDetialEntity.fromJson(String str) =>
ClassifyDetialEntity.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory ClassifyDetialEntity.fromMap(Map<String, dynamic> json) =>
ClassifyDetialEntity(
id: json["id"],
detailName: json["detailName"],
detailDesc: json["detailDesc"],
template: json['template'],
isShow: json['isShow']);
Map<String, dynamic> toMap() => {
"id": id,
"detailName": detailName,
"detailDesc": detailDesc,
"isShow": isShow,
"template": template,
};
}
List<ClassifyDetialEntity> classifyDetialEntityFromList(List data) =>
List<ClassifyDetialEntity>.from(
data.map((x) => ClassifyDetialEntity.fromMap(x)));
library entities;
export 'user.dart';
export 'news.dart';
export 'categories.dart';
export 'channels.dart';
export 'tags.dart';
export 'app.dart';
/// 新闻分页 request
class NewsPageListRequestEntity {
String? categoryCode;
String? channelCode;
String? tag;
String? keyword;
int? pageNum;
int? pageSize;
NewsPageListRequestEntity({
this.categoryCode,
this.channelCode,
this.tag,
this.keyword,
this.pageNum,
this.pageSize,
});
Map<String, dynamic> toJson() => {
"categoryCode": categoryCode,
"channelCode": channelCode,
"tag": tag,
"keyword": keyword,
"pageNum": pageNum,
"pageSize": pageSize,
};
}
/// 新闻分页 response
class NewsPageListResponseEntity {
int? counts;
int? pagesize;
int? pages;
int? page;
List<NewsItem>? items;
NewsPageListResponseEntity({
this.counts,
this.pagesize,
this.pages,
this.page,
this.items,
});
factory NewsPageListResponseEntity.fromJson(Map<String, dynamic> json) =>
NewsPageListResponseEntity(
counts: json["counts"],
pagesize: json["pagesize"],
pages: json["pages"],
page: json["page"],
items: json["items"] == null
? []
: List<NewsItem>.from(
json["items"].map((x) => NewsItem.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"counts": counts ?? 0,
"pagesize": pagesize ?? 0,
"pages": pages ?? 0,
"page": page ?? 0,
"items": items == null
? []
: List<dynamic>.from(items!.map((x) => x.toJson())),
};
}
class NewsItem {
String? id;
String? title;
String? category;
String? thumbnail;
String? author;
DateTime? addtime;
String? url;
NewsItem({
this.id,
this.title,
this.category,
this.thumbnail,
this.author,
this.addtime,
this.url,
});
factory NewsItem.fromJson(Map<String, dynamic> json) => NewsItem(
id: json["id"],
title: json["title"],
category: json["category"],
thumbnail: json["thumbnail"],
author: json["author"],
addtime: DateTime.parse(json["addtime"]),
url: json["url"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"category": category,
"thumbnail": thumbnail,
"author": author,
"addtime": addtime?.toIso8601String(),
"url": url,
};
}
/// 新闻推荐 request
class NewsRecommendRequestEntity {
String? categoryCode;
String? channelCode;
String? tag;
String? keyword;
NewsRecommendRequestEntity({
this.categoryCode,
this.channelCode,
this.tag,
this.keyword,
});
Map<String, dynamic> toJson() => {
"categoryCode": categoryCode,
"channelCode": channelCode,
"tag": tag,
"keyword": keyword,
};
}
/// 标签列表 Request
class TagRequestEntity {
String categoryCode;
String channelCode;
String tag;
String keyword;
String newsID;
TagRequestEntity({
required this.categoryCode,
required this.channelCode,
required this.tag,
required this.keyword,
required this.newsID,
});
Map<String, dynamic> toJson() => {
"categoryCode": categoryCode,
"channelCode": channelCode,
"tag": tag,
"keyword": keyword,
"newsID": newsID,
};
}
/// 标签列表 Response
class TagResponseEntity {
String? tag;
TagResponseEntity({
this.tag,
});
factory TagResponseEntity.fromJson(Map<String, dynamic> json) =>
TagResponseEntity(
tag: json["tag"],
);
Map<String, dynamic> toJson() => {
"tag": tag,
};
}
// 注册请求
class UserRegisterRequestEntity {
String email;
String password;
UserRegisterRequestEntity({
required this.email,
required this.password,
});
factory UserRegisterRequestEntity.fromJson(Map<String, dynamic> json) =>
UserRegisterRequestEntity(
email: json["email"],
password: json["password"],
);
Map<String, dynamic> toJson() => {
"email": email,
"password": password,
};
}
// 登录请求
class UserLoginRequestEntity {
String email;
String password;
UserLoginRequestEntity({
required this.email,
required this.password,
});
factory UserLoginRequestEntity.fromJson(Map<String, dynamic> json) =>
UserLoginRequestEntity(
email: json["email"],
password: json["password"],
);
Map<String, dynamic> toJson() => {
"email": email,
"password": password,
};
}
// 登录返回
class UserLoginResponseEntity {
String? accessToken;
String? displayName;
List<String>? channels;
UserLoginResponseEntity({
this.accessToken,
this.displayName,
this.channels,
});
factory UserLoginResponseEntity.fromJson(Map<String, dynamic> json) =>
UserLoginResponseEntity(
accessToken: json["access_token"],
displayName: json["display_name"],
channels: List<String>.from(json["channels"].map((x) => x)),
);
Map<String, dynamic> toJson() => {
"access_token": accessToken,
"display_name": displayName,
"channels":
channels == null ? [] : List<dynamic>.from(channels!.map((x) => x)),
};
}
const Map<String, String> en_US = {
'title': 'This is Title!',
'login': 'logged in as @name with email @email',
};
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'en_US.dart';
import 'zh_Hans.dart';
import 'zh_HK.dart';
/*
https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html
https://www.ibabbleon.com/iOS-Language-Codes-ISO-639.html
*/
class TranslationService extends Translations {
static Locale? get locale => Get.deviceLocale;
static final fallbackLocale = Locale('en', 'US');
@override
Map<String, Map<String, String>> get keys => {
'en_US': en_US,
'zh_Hans': zh_Hans,
'zh_HK': zh_HK,
};
}
const Map<String, String> zh_HK = {
'title': '這是標題',
'login': '登錄用戶 @name,郵箱賬號 @email',
};
const Map<String, String> zh_Hans = {
'title': '这是标题',
'login': '登录用户 @name,邮箱账号 @email',
};
library middlewares;
export './router_auth.dart';
export './router_welcome.dart';
import 'package:flutter/material.dart';
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/store/store.dart';
import 'package:get/get.dart';
/// 检查是否登录
class RouteAuthMiddleware extends GetMiddleware {
// priority 数字小优先级高
@override
int? priority = 0;
RouteAuthMiddleware({required this.priority});
@override
RouteSettings? redirect(String? route) {
if (UserStore.to.isLogin ||
route == AppRoutes.SIGN_IN ||
route == AppRoutes.SIGN_UP ||
route == AppRoutes.INITIAL) {
return null;
} else {
Future.delayed(
Duration(seconds: 1), () => Get.snackbar("提示", "登录过期,请重新登录"));
return RouteSettings(name: AppRoutes.SIGN_IN);
}
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/store/store.dart';
import 'package:get/get.dart';
/// 第一次欢迎页面
class RouteWelcomeMiddleware extends GetMiddleware {
// priority 数字小优先级高
@override
int? priority = 0;
RouteWelcomeMiddleware({required this.priority});
@override
RouteSettings? redirect(String? route) {
if (ConfigStore.to.isFirstOpen == true) {
return null;
} else if (UserStore.to.isLogin == true) {
return RouteSettings(name: AppRoutes.Application);
} else {
return RouteSettings(name: AppRoutes.SIGN_IN);
}
}
}
class AppRoutes {
static const INITIAL = '/';
static const SIGN_IN = '/sign_in';
static const SIGN_UP = '/sign_up';
static const NotFound = '/not_found';
static const Application = '/application';
static const Category = '/category';
}
static const application = '/application';
static const category = '/category';
static const frameNotfound = '/frame_notfound';
static const frameSignIn = '/frame_sign_in';
static const frameSignUp = '/frame_sign_up';
static const frameWelcome = '/frame_welcome';
static const main = '/main';
import 'package:flutter/material.dart';
import 'routes.dart';
class RouteObservers<R extends Route<dynamic>> extends RouteObserver<R> {
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPush(route, previousRoute);
var name = route.settings.name ?? '';
if (name.isNotEmpty) AppPages.history.add(name);
print('didPush');
print(AppPages.history);
}
@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPop(route, previousRoute);
AppPages.history.remove(route.settings.name);
print('didPop');
print(AppPages.history);
}
@override
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
if (newRoute != null) {
var index = AppPages.history.indexWhere((element) {
return element == oldRoute?.settings.name;
});
var name = newRoute.settings.name ?? '';
if (name.isNotEmpty) {
if (index > 0) {
AppPages.history[index] = name;
} else {
AppPages.history.add(name);
}
}
}
print('didReplace');
print(AppPages.history);
}
@override
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didRemove(route, previousRoute);
AppPages.history.remove(route.settings.name);
print('didRemove');
print(AppPages.history);
}
@override
void didStartUserGesture(
Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didStartUserGesture(route, previousRoute);
}
@override
void didStopUserGesture() {
super.didStopUserGesture();
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/middlewares/middlewares.dart';
import 'package:chart/pages/application/index.dart';
import 'package:chart/pages/category/index.dart';
import 'package:chart/pages/frame/sign_in/index.dart';
import 'package:chart/pages/frame/sign_up/index.dart';
import 'package:chart/pages/frame/welcome/index.dart';
// import 'package:chart/pages/home/home_page.dart';
import 'package:get/get.dart';
import 'routes.dart';
class AppPages {
static const INITIAL = AppRoutes.INITIAL;
static final RouteObserver<Route> observer = RouteObservers();
static List<String> history = [];
static final List<GetPage> routes = [
// // 免登陆
// GetPage(
// name: AppRoutes.INITIAL,
// page: () => WelcomePage(),
// binding: WelcomeBinding(),
// middlewares: [
// RouteWelcomeMiddleware(priority: 1),
// ],
// ),
// 需要登录
GetPage(
name: AppRoutes.INITIAL,
page: () => WelcomePage(), //ApplicationPage(),
binding: WelcomeBinding(), // ApplicationBinding(),
middlewares: [
// RouteAuthMiddleware(priority: 1),
],
),
GetPage(
name: AppRoutes.SIGN_IN,
page: () => SignInPage(),
binding: SignInBinding(),
),
GetPage(
name: AppRoutes.SIGN_UP,
page: () => SignUpPage(),
binding: SignUpBinding(),
),
// 需要登录
GetPage(
name: AppRoutes.Application,
page: () => ApplicationPage(),
binding: ApplicationBinding(),
middlewares: [
// RouteAuthMiddleware(priority: 1),
],
),
// 分类列表
GetPage(
name: AppRoutes.Category,
page: () => CategoryPage(),
binding: CategoryBinding(),
),
];
// static final unknownRoute = GetPage(
// name: AppRoutes.NotFound,
// page: () => NotfoundView(),
// );
}
GetPage(
name: RouteNames.application,
page: () => const ApplicationPage(),
),
GetPage(
name: RouteNames.category,
page: () => const CategoryPage(),
),
GetPage(
name: RouteNames.frameNotfound,
page: () => const NotfoundPage(),
),
GetPage(
name: RouteNames.frameSignIn,
page: () => const SignInPage(),
),
GetPage(
name: RouteNames.frameSignUp,
page: () => const SignUpPage(),
),
GetPage(
name: RouteNames.frameWelcome,
page: () => const WelcomePage(),
),
GetPage(
name: RouteNames.main,
page: () => const MainPage(),
),
\ No newline at end of file
library routes;
export 'names.dart';
export 'pages.dart';
export './observers.dart';
library services;
export './storage.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
class StorageService extends GetxService {
static StorageService get to => Get.put(StorageService());
// static StorageService get to => Get.find();
//
late final SharedPreferences _prefs;
Future<StorageService> init() async {
_prefs = await SharedPreferences.getInstance();
return this;
}
Future<bool> setString(String key, String value) async {
return await _prefs.setString(key, value);
}
Future<bool> setBool(String key, bool value) async {
return await _prefs.setBool(key, value);
}
Future<bool> setList(String key, List<String> value) async {
return await _prefs.setStringList(key, value);
}
String getString(String key) {
return _prefs.getString(key) ?? '';
}
bool getBool(String key) {
return _prefs.getBool(key) ?? false;
}
List<String> getList(String key) {
return _prefs.getStringList(key) ?? [];
}
Future<bool> remove(String key) async {
return await _prefs.remove(key);
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/services/services.dart';
import 'package:chart/common/values/values.dart';
import 'package:get/get.dart';
import 'package:package_info/package_info.dart';
class ConfigStore extends GetxController {
static ConfigStore get to => Get.put(ConfigStore());
// .find();
bool isFirstOpen = false;
PackageInfo? _platform;
String get version => _platform?.version ?? '-';
bool get isRelease => bool.fromEnvironment("dart.vm.product");
Locale locale = Locale('en', 'US');
List<Locale> languages = [
Locale('en', 'US'),
Locale('zh', 'CN'),
];
@override
void onInit() {
super.onInit();
isFirstOpen = StorageService.to.getBool(STORAGE_DEVICE_FIRST_OPEN_KEY);
}
Future<void> getPlatform() async {
_platform = await PackageInfo.fromPlatform();
}
// 标记用户已打开APP
Future<bool> saveAlreadyOpen() {
return StorageService.to.setBool(STORAGE_DEVICE_FIRST_OPEN_KEY, false);
}
void onInitLocale() {
var langCode = StorageService.to.getString(STORAGE_LANGUAGE_CODE);
if (langCode.isEmpty) return;
var index = languages.indexWhere((element) {
return element.languageCode == langCode;
});
if (index < 0) return;
locale = languages[index];
}
void onLocaleUpdate(Locale value) {
locale = value;
Get.updateLocale(value);
StorageService.to.setString(STORAGE_LANGUAGE_CODE, value.languageCode);
}
}
library store;
export './user.dart';
export './config.dart';
import 'dart:convert';
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/services/services.dart';
import 'package:chart/common/values/values.dart';
import 'package:get/get.dart';
class UserStore extends GetxController {
static UserStore get to => Get.find();
// 是否登录
final _isLogin = false.obs;
// 令牌 token
String token = '';
// 用户 profile
final _profile = UserLoginResponseEntity().obs;
bool get isLogin => _isLogin.value;
UserLoginResponseEntity get profile => _profile.value;
bool get hasToken => token.isNotEmpty;
@override
void onInit() {
super.onInit();
token = StorageService.to.getString(STORAGE_USER_TOKEN_KEY);
var profileOffline = StorageService.to.getString(STORAGE_USER_PROFILE_KEY);
if (profileOffline.isNotEmpty) {
_profile(UserLoginResponseEntity.fromJson(jsonDecode(profileOffline)));
}
}
// 保存 token
Future<void> setToken(String value) async {
await StorageService.to.setString(STORAGE_USER_TOKEN_KEY, value);
token = value;
}
// 获取 profile
Future<void> getProfile() async {
if (token.isEmpty) return;
var result = await UserAPI.profile();
_profile(result);
_isLogin.value = true;
StorageService.to.setString(STORAGE_USER_PROFILE_KEY, jsonEncode(result));
}
// 保存 profile
Future<void> saveProfile(UserLoginResponseEntity profile) async {
_isLogin.value = true;
StorageService.to.setString(STORAGE_USER_PROFILE_KEY, jsonEncode(profile));
}
// 注销
Future<void> onLogout() async {
if (_isLogin.value) await UserAPI.logout();
await StorageService.to.remove(STORAGE_USER_TOKEN_KEY);
_isLogin.value = false;
token = '';
}
}
import 'package:flutter/material.dart';
class AppColor {
/// 页面背景颜色
static const Color scaffoldBackground = Color(0xFFFFFFFF);
/// 主要背景颜色
// static const Color primaryBackground = Color(0xFF5C78FF);
/// 主要文本颜色
static const Color primaryText = Color(0xFF333333);
/// 次要文本颜色
static const Color secondaryText = Color(0xFF74788D);
/// 高亮颜色
static const Color accentColor = Color(0xFF5C78FF);
/// 次要颜色
static const Color secondaryColor = Color(0xFFDEE3FF);
/// 警告颜色
static const Color warnColor = Color(0xFFFFB822);
/// 边框颜色
static const Color borderColor = Color(0xFFDEE3FF);
static const Color pinkColor = Color(0xFFF77866);
static const Color yellowColor = Color(0xFFFFB822);
}
library style;
export './color.dart';
export './theme.dart';
import 'package:flutter/material.dart';
import 'color.dart';
class AppTheme {
static const horizontalMargin = 16.0;
static const radius = 10.0;
static ThemeData light = ThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: AppColor.scaffoldBackground,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
primaryColor: AppColor.accentColor,
colorScheme: ColorScheme.fromSwatch().copyWith(
secondary: AppColor.accentColor,
),
appBarTheme: AppBarTheme(
elevation: 0,
centerTitle: true,
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: AppColor.primaryText,
),
titleTextStyle: TextStyle(
color: AppColor.primaryText,
fontSize: 20,
fontWeight: FontWeight.w500,
),
toolbarTextStyle: TextStyle(
color: AppColor.primaryText,
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
backgroundColor: AppColor.scaffoldBackground,
unselectedLabelStyle: TextStyle(fontSize: 12),
selectedLabelStyle: TextStyle(fontSize: 12),
unselectedItemColor: Color(0xffA2A5B9),
selectedItemColor: AppColor.accentColor,
),
tabBarTheme: TabBarTheme(
indicatorSize: TabBarIndicatorSize.label,
labelColor: AppColor.accentColor,
unselectedLabelColor: AppColor.secondaryText,
),
);
}
import 'package:intl/intl.dart';
/// 格式化时间
String duTimeLineFormat(DateTime dt) {
var now = DateTime.now();
var difference = now.difference(dt);
// 1天内
if (difference.inHours < 24) {
return "${difference.inHours} hours ago";
}
// 30天内
else if (difference.inDays < 30) {
return "${difference.inDays} days ago";
}
// MM-dd
else if (difference.inDays < 365) {
final dtFormat = new DateFormat('MM-dd');
return dtFormat.format(dt);
}
// yyyy-MM-dd
else {
final dtFormat = new DateFormat('yyyy-MM-dd');
var str = dtFormat.format(dt);
return str;
}
}
import 'dart:async';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:chart/common/store/store.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart' hide FormData;
/*
* http 操作类
*
* 手册
* https://github.com/flutterchina/dio/blob/master/README-ZH.md
*
* 从 3 升级到 4
* https://github.com/flutterchina/dio/blob/master/migration_to_4.x.md
*/
class HttpUtil {
static HttpUtil _instance = HttpUtil._internal();
factory HttpUtil() => _instance;
late Dio dio;
CancelToken cancelToken = new CancelToken();
HttpUtil._internal() {
// BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
BaseOptions options = new BaseOptions(
// 请求基地址,可以包含子路径
baseUrl: SERVER_API_URL,
// baseUrl: storage.read(key: STORAGE_KEY_APIURL) ?? SERVICE_API_BASEURL,
//连接服务器超时时间,单位是毫秒.
connectTimeout: 10000,
// 响应流上前后两次接受到数据的间隔,单位为毫秒。
receiveTimeout: 5000,
// Http请求头.
headers: {},
/// 请求的Content-Type,默认值是"application/json; charset=utf-8".
/// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,
/// 可以设置此选项为 `Headers.formUrlEncodedContentType`, 这样[Dio]
/// 就会自动编码请求体.
contentType: 'application/json; charset=utf-8',
/// [responseType] 表示期望以那种格式(方式)接受响应数据。
/// 目前 [ResponseType] 接受三种类型 `JSON`, `STREAM`, `PLAIN`.
///
/// 默认值是 `JSON`, 当响应头中content-type为"application/json"时,dio 会自动将响应内容转化为json对象。
/// 如果想以二进制方式接受响应数据,如下载一个二进制文件,那么可以使用 `STREAM`.
///
/// 如果想以文本(字符串)格式接收响应数据,请使用 `PLAIN`.
responseType: ResponseType.json,
);
dio = new Dio(options);
// Cookie管理
CookieJar cookieJar = CookieJar();
dio.interceptors.add(CookieManager(cookieJar));
// 添加拦截器
dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
// Do something before request is sent
return handler.next(options); //continue
// 如果你想完成请求并返回一些自定义数据,你可以resolve一个Response对象 `handler.resolve(response)`。
// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
//
// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`handler.reject(error)`,
// 这样请求将被中止并触发异常,上层catchError会被调用。
},
onResponse: (response, handler) {
// Do something with response data
return handler.next(response); // continue
// 如果你想终止请求并触发一个错误,你可以 reject 一个`DioError`对象,如`handler.reject(error)`,
// 这样请求将被中止并触发异常,上层catchError会被调用。
},
onError: (DioError e, handler) {
// Do something with response error
Loading.dismiss();
ErrorEntity eInfo = createErrorEntity(e);
onError(eInfo);
return handler.next(e); //continue
// 如果你想完成请求并返回一些自定义数据,可以resolve 一个`Response`,如`handler.resolve(response)`。
// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
},
));
}
/*
* error统一处理
*/
// 错误处理
void onError(ErrorEntity eInfo) {
print('error.code -> ' +
eInfo.code.toString() +
', error.message -> ' +
eInfo.message);
switch (eInfo.code) {
case 401:
UserStore.to.onLogout();
EasyLoading.showError(eInfo.message);
break;
default:
EasyLoading.showError('未知错误');
break;
}
}
// 错误信息
ErrorEntity createErrorEntity(DioError error) {
switch (error.type) {
case DioErrorType.cancel:
return ErrorEntity(code: -1, message: "请求取消");
case DioErrorType.connectTimeout:
return ErrorEntity(code: -1, message: "连接超时");
case DioErrorType.sendTimeout:
return ErrorEntity(code: -1, message: "请求超时");
case DioErrorType.receiveTimeout:
return ErrorEntity(code: -1, message: "响应超时");
case DioErrorType.cancel:
return ErrorEntity(code: -1, message: "请求取消");
case DioErrorType.response:
{
try {
int errCode =
error.response != null ? error.response!.statusCode! : -1;
// String errMsg = error.response.statusMessage;
// return ErrorEntity(code: errCode, message: errMsg);
switch (errCode) {
case 400:
return ErrorEntity(code: errCode, message: "请求语法错误");
case 401:
return ErrorEntity(code: errCode, message: "没有权限");
case 403:
return ErrorEntity(code: errCode, message: "服务器拒绝执行");
case 404:
return ErrorEntity(code: errCode, message: "无法连接服务器");
case 405:
return ErrorEntity(code: errCode, message: "请求方法被禁止");
case 500:
return ErrorEntity(code: errCode, message: "服务器内部错误");
case 502:
return ErrorEntity(code: errCode, message: "无效的请求");
case 503:
return ErrorEntity(code: errCode, message: "服务器挂了");
case 505:
return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
default:
{
// return ErrorEntity(code: errCode, message: "未知错误");
return ErrorEntity(
code: errCode,
message: error.response != null
? error.response!.statusMessage!
: "",
);
}
}
} on Exception catch (_) {
return ErrorEntity(code: -1, message: "未知错误");
}
}
default:
{
return ErrorEntity(code: -1, message: error.message);
}
}
}
/*
* 取消请求
*
* 同一个cancel token 可以用于多个请求,当一个cancel token取消时,所有使用该cancel token的请求都会被取消。
* 所以参数可选
*/
void cancelRequests(CancelToken token) {
token.cancel("cancelled");
}
/// 读取本地配置
Map<String, dynamic>? getAuthorizationHeader() {
var headers = <String, dynamic>{};
if (Get.isRegistered<UserStore>() && UserStore.to.hasToken == true) {
headers['Authorization'] = 'Bearer ${UserStore.to.token}';
}
return headers;
}
/// restful get 操作
/// refresh 是否下拉刷新 默认 false
/// noCache 是否不缓存 默认 true
/// list 是否列表 默认 false
/// cacheKey 缓存key
/// cacheDisk 是否磁盘缓存
Future get(
String path, {
Map<String, dynamic>? queryParameters,
Options? options,
bool refresh = false,
bool noCache = !CACHE_ENABLE,
bool list = false,
String cacheKey = '',
bool cacheDisk = false,
}) async {
Options requestOptions = options ?? Options();
if (requestOptions.extra == null) {
requestOptions.extra = Map();
}
requestOptions.extra!.addAll({
"refresh": refresh,
"noCache": noCache,
"list": list,
"cacheKey": cacheKey,
"cacheDisk": cacheDisk,
});
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.get(
path,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
);
return response.data;
}
/// restful post 操作
Future post(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.post(
path,
data: data,
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
/// restful put 操作
Future put(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.put(
path,
data: data,
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
/// restful patch 操作
Future patch(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.patch(
path,
data: data,
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
/// restful delete 操作
Future delete(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.delete(
path,
data: data,
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
/// restful post form 表单提交操作
Future postForm(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
var response = await dio.post(
path,
data: FormData.fromMap(data),
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
/// restful post Stream 流数据
Future postStream(
String path, {
dynamic data,
int dataLength = 0,
Map<String, dynamic>? queryParameters,
Options? options,
}) async {
Options requestOptions = options ?? Options();
requestOptions.headers = requestOptions.headers ?? {};
Map<String, dynamic>? authorization = getAuthorizationHeader();
if (authorization != null) {
requestOptions.headers!.addAll(authorization);
}
requestOptions.headers!.addAll({
Headers.contentLengthHeader: dataLength.toString(),
});
var response = await dio.post(
path,
data: Stream.fromIterable(data.map((e) => [e])),
queryParameters: queryParameters,
options: requestOptions,
cancelToken: cancelToken,
);
return response.data;
}
}
// 异常处理
class ErrorEntity implements Exception {
int code = -1;
String message = "";
ErrorEntity({required this.code, required this.message});
String toString() {
if (message == "") return "Exception";
return "Exception: code $code, $message";
}
}
import 'package:flutter/material.dart';
class Iconfont {
// iconName: share
static const share = IconData(
0xe60d,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: fav
static const fav = IconData(
0xe60c,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-linkedin
static const sociallinkedin = IconData(
0xe605,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-apple
static const socialapple = IconData(
0xe606,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-octocat
static const socialoctocat = IconData(
0xe607,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-reddit
static const socialreddit = IconData(
0xe608,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-snapchat
static const socialsnapchat = IconData(
0xe609,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-skype
static const socialskype = IconData(
0xe60a,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: social-twitter
static const socialtwitter = IconData(
0xe60b,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: me
static const me = IconData(
0xe604,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: tag
static const tag = IconData(
0xe603,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: grid
static const grid = IconData(
0xe602,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
// iconName: home
static const home = IconData(
0xe601,
fontFamily: 'Iconfont',
matchTextDirection: true,
);
}
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
class Loading {
Loading() {
EasyLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.ring
..loadingStyle = EasyLoadingStyle.custom
..indicatorSize = 35.0
..lineWidth = 2
..radius = 10.0
..progressColor = Colors.white
..backgroundColor = Colors.black.withOpacity(0.7)
..indicatorColor = Colors.white
..textColor = Colors.white
..maskColor = Colors.black.withOpacity(0.6)
..userInteractions = true
..dismissOnTap = false
..maskType = EasyLoadingMaskType.custom;
}
static void show([String? text]) {
EasyLoading.instance.userInteractions = false;
EasyLoading.show(status: text ?? 'Loading...');
}
static void toast(String text) {
EasyLoading.showToast(text);
}
static void dismiss() {
EasyLoading.instance.userInteractions = true;
EasyLoading.dismiss();
}
}
class Logger {
// Sample of abstract logging function
static void write(String text, {bool isError = false}) {
Future.microtask(() => print('** $text. isError: [$isError]'));
}
}
import 'dart:convert';
import 'package:crypto/crypto.dart';
/// SHA256
String duSHA256(String input) {
String salt = 'EIpWsyfiy@R@X#qn17!StJNdZK1fFF8iV6ffN!goZkqt#JxO'; // 加盐
var bytes = utf8.encode(input + salt);
var digest = sha256.convert(bytes);
return digest.toString();
}
library utils;
export 'validator.dart';
export 'http.dart';
export 'security.dart';
export 'iconfont.dart';
export 'date.dart';
export 'logger.dart';
export 'loading.dart';
/// 检查邮箱格式
bool duIsEmail(String? input) {
if (input == null || input.isEmpty) return false;
// 邮箱正则
String regexEmail = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$";
return RegExp(regexEmail).hasMatch(input);
}
/// 检查字符长度
bool duCheckStringLength(String? input, int length) {
if (input == null || input.isEmpty) return false;
return input.length >= length;
}
import 'package:flutter/rendering.dart';
class Borders {
static const BorderSide primaryBorder = BorderSide(
color: Color.fromARGB(255, 230, 230, 231),
width: 1,
style: BorderStyle.solid,
);
}
\ No newline at end of file
// 是否启用缓存
const CACHE_ENABLE = false;
// 缓存的最长时间,单位(秒)
const CACHE_MAXAGE = 1000;
// 最大缓存数
const CACHE_MAXCOUNT = 100;
import 'dart:ui';
class AppColors {
/// 主背景 白色
static const Color primaryBackground = Color.fromARGB(255, 255, 255, 255);
/// 主文本 灰色
static const Color primaryText = Color.fromARGB(255, 45, 45, 47);
/// 主控件-背景 蓝色
static const Color primaryElement = Color.fromARGB(255, 41, 103, 255);
/// 主控件-文本 白色
static const Color primaryElementText = Color.fromARGB(255, 255, 255, 255);
// *****************************************
/// 第二种控件-背景色 淡灰色
static const Color secondaryElement = Color.fromARGB(255, 246, 246, 246);
/// 第二种控件-文本 浅蓝色
static const Color secondaryElementText = Color.fromARGB(255, 41, 103, 255);
// *****************************************
/// 第三种控件-背景色 石墨色
static const Color thirdElement = Color.fromARGB(255, 45, 45, 47);
/// 第三种控件-文本 浅灰色2
static const Color thirdElementText = Color.fromARGB(255, 141, 141, 142);
// *****************************************
/// tabBar 默认颜色 灰色
static const Color tabBarElement = Color.fromARGB(255, 208, 208, 208);
/// tabCellSeparator 单元格底部分隔条 颜色
static const Color tabCellSeparator = Color.fromARGB(255, 230, 230, 231);
}
// 是否启用代理
const PROXY_ENABLE = false;
/// 代理服务IP
// const PROXY_IP = '192.168.1.105';
const PROXY_IP = '172.16.43.74';
/// 代理服务端口
const PROXY_PORT = 8866;
import 'package:flutter/rendering.dart';
class Radii {
static const BorderRadiusGeometry k6pxRadius =
BorderRadius.all(Radius.circular(6));
static const BorderRadiusGeometry k54pxRadius =
BorderRadius.all(Radius.circular(54));
}
// baidu yapi
// const SERVER_API_URL = 'https://yapi.baidu.com/mock/41008';
// const SERVER_API_URL = 'https://yapi.ducafecat.tech/mock/11';
const SERVER_API_URL = 'http://192.168.110.1:8083/api';
// static const String baseUrl = 'http://101.34.153.228:8083'; // 基础接口地址
// static const String baseApiUrl = '${baseUrl}/api'; // 基础接口地址
// http://101.34.153.228:8083/api/doc.html
//192.168.110.1:8083
// 本地搭建 yapi
// const SERVER_API_URL = 'http://yapi.ducafecat.tech/mock/11';
import 'package:flutter/rendering.dart';
class Shadows {
static const BoxShadow primaryShadow = BoxShadow(
color: Color.fromARGB(38, 27, 27, 29),
offset: Offset(0, 5),
blurRadius: 10,
);
}
\ No newline at end of file
/// 用户 - 配置信息
const String STORAGE_USER_PROFILE_KEY = 'user_profile';
/// 用户 - 配置信息
const String STORAGE_USER_TOKEN_KEY = 'user_token';
/// 设备是否第一次打开
const String STORAGE_DEVICE_FIRST_OPEN_KEY = 'device_first_open';
/// 首页新闻cacheKey
const String STORAGE_INDEX_NEWS_CACHE_KEY = 'cache_index_news';
/// 多语言
const String STORAGE_LANGUAGE_CODE = 'language_code';
library values;
export 'colors.dart';
export 'borders.dart';
export 'radii.dart';
export 'shadows.dart';
export 'server.dart';
export 'storage.dart';
export 'cache.dart';
export 'proxy.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:chart/common/values/values.dart';
/// 透明背景 AppBar
AppBar transparentAppBar({
Widget? title,
Widget? leading,
List<Widget>? actions,
}) {
return AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
title: title != null
? Center(
child: title,
)
: null,
leading: leading,
actions: actions,
);
}
/// 10像素 Divider
Widget divider10Px({Color bgColor = AppColors.secondaryElement}) {
return Container(
height: 10.w,
decoration: BoxDecoration(
color: bgColor,
),
);
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/// 扁平圆角按钮
Widget btnFlatButtonWidget({
required VoidCallback onPressed,
double width = 140,
double height = 44,
Color gbColor = AppColors.primaryElement,
String title = "button",
Color fontColor = AppColors.primaryElementText,
double fontSize = 18,
String fontName = "Montserrat",
FontWeight fontWeight = FontWeight.w400,
}) {
return Container(
width: width.w,
height: height.h,
child: TextButton(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(TextStyle(
fontSize: 16.sp,
)),
foregroundColor: MaterialStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused) &&
!states.contains(MaterialState.pressed)) {
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
return Colors.deepPurple;
}
return fontColor;
},
),
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.pressed)) {
return Colors.blue[200];
}
return gbColor;
}),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: Radii.k6pxRadius,
)),
),
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
color: fontColor,
fontFamily: fontName,
fontWeight: fontWeight,
fontSize: fontSize.sp,
height: 1,
),
),
onPressed: onPressed,
),
);
}
/// 第三方按钮
Widget btnFlatButtonBorderOnlyWidget({
required VoidCallback onPressed,
double width = 88,
double height = 44,
required String iconFileName,
}) {
return Container(
width: width.w,
height: height.h,
child: TextButton(
style: ButtonStyle(
// textStyle: MaterialStateProperty.all(TextStyle(
// fontSize: 16.sp,
// )),
// foregroundColor: MaterialStateProperty.resolveWith(
// (states) {
// if (states.contains(MaterialState.focused) &&
// !states.contains(MaterialState.pressed)) {
// return Colors.blue;
// } else if (states.contains(MaterialState.pressed)) {
// return Colors.deepPurple;
// }
// return AppColors.primaryElementText;
// },
// ),
// backgroundColor: MaterialStateProperty.resolveWith((states) {
// if (states.contains(MaterialState.pressed)) {
// return Colors.blue[200];
// }
// return AppColors.primaryElement;
// }),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: Radii.k6pxRadius,
)),
),
child: Image.asset(
"assets/images/icons-$iconFileName.png",
),
onPressed: onPressed,
),
);
}
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/// 缓存图片
Widget netImageCached(
String url, {
double width = 48,
double height = 48,
EdgeInsetsGeometry? margin,
}) {
return CachedNetworkImage(
imageUrl: url,
imageBuilder: (context, imageProvider) => Container(
height: height.h,
width: width.w,
margin: margin,
decoration: BoxDecoration(
borderRadius: Radii.k6pxRadius,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
// colorFilter: ColorFilter.mode(Colors.red, BlendMode.colorBurn),
),
),
),
placeholder: (context, url) {
return Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
);
},
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/// 输入框
Widget inputTextEdit({
TextEditingController? controller,
TextInputType keyboardType = TextInputType.text,
String? hintText,
bool isPassword = false,
double marginTop = 15,
bool autofocus = false,
}) {
return Container(
height: 44.h,
margin: EdgeInsets.only(top: marginTop.h),
decoration: BoxDecoration(
color: AppColors.secondaryElement,
borderRadius: Radii.k6pxRadius,
),
child: TextField(
autofocus: autofocus,
controller: controller,
keyboardType: keyboardType,
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 9),
border: InputBorder.none,
),
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 18.sp,
),
maxLines: 1,
autocorrect: false, // 自动纠正
obscureText: isPassword, // 隐藏输入内容, 密码框
),
);
}
/// email 输入框
/// 背景白色,文字黑色,带阴影
Widget inputEmailEdit({
TextEditingController? controller,
TextInputType keyboardType = TextInputType.text,
String? hintText,
bool isPassword = false,
double marginTop = 15,
bool autofocus = false,
}) {
return Container(
height: 44.h,
margin: EdgeInsets.only(top: marginTop.h),
decoration: BoxDecoration(
color: AppColors.primaryBackground,
borderRadius: Radii.k6pxRadius,
boxShadow: [
BoxShadow(
color: Color.fromARGB(41, 0, 0, 0),
offset: Offset(0, 1),
blurRadius: 0,
),
],
),
child: TextField(
autofocus: autofocus,
controller: controller,
keyboardType: keyboardType,
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 9),
border: InputBorder.none,
hintStyle: TextStyle(
color: AppColors.primaryText,
),
),
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 18.sp,
),
maxLines: 1,
autocorrect: false, // 自动纠正
obscureText: isPassword, // 隐藏输入内容, 密码框
),
);
}
// /// 骨架屏-卡片
// Widget cardListSkeleton() {
// return PKCardListSkeleton(
// isCircularImage: true,
// isBottomLinesActive: false,
// length: 10,
// );
// }
// /// 页面骨架屏
// Widget pageSkeleton() {
// return PKCardPageSkeleton(
// totalLines: 5,
// );
// }
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
Future<bool?> toastInfo({
required String msg,
Color backgroundColor = Colors.black,
Color textColor = Colors.white,
}) {
return Fluttertoast.showToast(
msg: msg,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
timeInSecForIosWeb: 1,
backgroundColor: backgroundColor,
textColor: textColor,
fontSize: 16.sp,
);
}
library widgets;
export 'button.dart';
export 'toast.dart';
export 'app.dart';
export 'input.dart';
export 'image.dart';
export 'skeleton.dart';
class AppUrls { class AppUrls {
static const String baseUrl = 'http://192.168.110.1:8083'; // 基础接口地址 static const String baseUrl = 'http://101.34.153.228:8083'; // 基础接口地址
static const String baseApiUrl = '${baseUrl}/api'; // 基础接口地址 static const String baseApiUrl = '${baseUrl}/api'; // 基础接口地址
// http://101.34.153.228:8083/api/doc.html // http://101.34.153.228:8083/api/doc.html
......
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:chart/common/services/services.dart';
import 'package:chart/common/store/store.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:get/get.dart';
/// 全局静态数据
class Global {
/// 初始化
static Future init() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
setSystemUi();
Loading();
await Get.putAsync<StorageService>(() => StorageService().init());
Get.put<ConfigStore>(ConfigStore());
Get.put<UserStore>(UserStore());
}
static void setSystemUi() {
if (GetPlatform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark,
);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
}
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:chart/models/app_model.dart';
import 'package:provider/provider.dart';
import 'package:chart/router/routers.dart';
import 'package:chart/router/application.dart';
import 'package:flutter/services.dart' as services;
// import 'package:chart/constant/app_colors.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; //国际化
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
// import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
// import 'package:firebase_core/firebase_core.dart';
// import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:ui';
import 'models/user_model.dart';
// ignore: non_constant_identifier_names
// WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
var appModel = AppModel();
var userViewModel = UserModel();
userViewModel.refreshData();
// appModel.getClassFyList();
// var appModel = AppModel();
// var userViewModel = UserModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var planModel = PlanModel();
runApp(MultiProvider(providers: [
ChangeNotifierProvider<AppModel>.value(value: appModel),
ChangeNotifierProvider<UserModel>.value(value: userViewModel),
// ChangeNotifierProvider<UserSubscribeModel>.value(value: userSubscribeModel),
// ChangeNotifierProvider<ServerModel>.value(value: serverModel),
// ChangeNotifierProvider<PlanModel>.value(value: planModel)
], child: ChartApp()));
configLoading();
}
class ChartApp extends StatelessWidget {
ChartApp({Key? key}) : super(key: key) {
final router = FluroRouter();
Routers.configureRoutes(router);
Application.router = router;
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
services.SystemChrome.setPreferredOrientations([
services.DeviceOrientation.portraitUp,
services.DeviceOrientation.portraitDown
]);
return MaterialApp(
// <--- /!\ Add the builder
title: AppStrings.appName,
navigatorKey: Application.navigatorKey,
debugShowCheckedModeBanner: false,
onGenerateRoute: Application.router?.generator,
localizationsDelegates: const [
// 本地化的代理类
RefreshLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate //复制
],
builder: EasyLoading.init(),
supportedLocales: const [
Locale('en', 'US'), // 美国英语
Locale('zh', 'CN'), // 中文简体
//其它Locales
],
theme: ThemeData(
// Color(0xff9182F9)
primarySwatch: createMaterialColor(const Color(0xff9182F9)),
// AppColors.themeColorGreen,
visualDensity: VisualDensity.adaptivePlatformDensity),
);
}
}
//调用的时候需要把hex改一下,比如#223344 needs change to 0xFF223344
//即把#换成0xFF即可
MaterialColor createMaterialColor(Color color) {
List strengths = <double>[.05];
Map<int, Color> swatch = {};
final int r = color.red, g = color.green, b = color.blue;
for (int i = 1; i < 10; i++) {
strengths.add(0.1 * i);
}
strengths.forEach((strength) {
final double ds = 0.5 - strength;
swatch[(strength * 1000).round()] = Color.fromRGBO(
r + ((ds < 0 ? r : (255 - r)) * ds).round(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(),
b + ((ds < 0 ? b : (255 - b)) * ds).round(),
1,
);
});
return MaterialColor(color.value, swatch);
}
void configLoading() {
EasyLoading
.instance
// ..displayDuration = const Duration(milliseconds: 2000)
// ..indicatorType = EasyLoadingIndicatorType.fadingCircle
// ..loadingStyle = EasyLoadingStyle.dark
// ..indicatorSize = 45.0
// ..radius = 10.0
// ..progressColor = Colors.yellow
// ..backgroundColor = Colors.green
// ..indicatorColor = Colors.yellow
// ..textColor = Colors.yellow
// ..maskColor = Colors.blue.withOpacity(0.5)
// ..userInteractions = false
.userInteractions = false;
// ..customAnimation = CustomAnimation();
}
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:chart/models/app_model.dart'; import 'package:chart/common/langs/translation_service.dart';
import 'package:provider/provider.dart'; import 'package:chart/common/routers/pages.dart';
import 'package:chart/router/routers.dart'; import 'package:chart/common/store/store.dart';
import 'package:chart/router/application.dart'; import 'package:chart/common/style/style.dart';
import 'package:flutter/services.dart' as services; import 'package:chart/common/utils/utils.dart';
// import 'package:chart/constant/app_colors.dart'; import 'package:chart/global.dart';
import 'package:chart/constant/app_strings.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; //国际化
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart';
// import 'package:firebase_phone_auth_handler/firebase_phone_auth_handler.dart';
// import 'package:firebase_core/firebase_core.dart';
// import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:ui';
import 'models/user_model.dart';
// ignore: non_constant_identifier_names
// WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); await Global.init();
// await Firebase.initializeApp(); runApp(ChatApp());
var appModel = AppModel();
var userViewModel = UserModel();
userViewModel.refreshData();
// appModel.getClassFyList();
// var appModel = AppModel();
// var userViewModel = UserModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var userSubscribeModel = UserSubscribeModel();
// var serverModel = ServerModel();
// var planModel = PlanModel();
runApp(MultiProvider(providers: [
ChangeNotifierProvider<AppModel>.value(value: appModel),
ChangeNotifierProvider<UserModel>.value(value: userViewModel),
// ChangeNotifierProvider<UserSubscribeModel>.value(value: userSubscribeModel),
// ChangeNotifierProvider<ServerModel>.value(value: serverModel),
// ChangeNotifierProvider<PlanModel>.value(value: planModel)
], child: ChartApp()));
configLoading();
} }
class ChartApp extends StatelessWidget { class ChatApp extends StatelessWidget {
ChartApp({Key? key}) : super(key: key) { const ChatApp({Key? key}) : super(key: key);
final router = FluroRouter();
Routers.configureRoutes(router);
Application.router = router;
}
// This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
services.SystemChrome.setPreferredOrientations([ return ScreenUtilInit(
services.DeviceOrientation.portraitUp, designSize: Size(375, 812),
services.DeviceOrientation.portraitDown builder: (context, child) => GetMaterialApp(
]); title: 'News',
theme: AppTheme.light,
debugShowCheckedModeBanner: false,
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
builder: EasyLoading.init(),
translations: TranslationService(),
navigatorObservers: [AppPages.observer],
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: ConfigStore.to.languages,
locale: ConfigStore.to.locale,
fallbackLocale: Locale('en', 'US'),
enableLog: true,
logWriterCallback: Logger.write,
));
return MaterialApp( // GetMaterialApp(
// <--- /!\ Add the builder // debugShowCheckedModeBanner: false,
title: AppStrings.appName, // enableLog: true,
navigatorKey: Application.navigatorKey, // logWriterCallback: Logger.write,
debugShowCheckedModeBanner: false, // initialRoute: AppPages.INITIAL,
onGenerateRoute: Application.router?.generator, // getPages: AppPages.routes,
localizationsDelegates: const [ // locale: TranslationService.locale,
// 本地化的代理类 // fallbackLocale: TranslationService.fallbackLocale,
RefreshLocalizations.delegate, // translations: TranslationService(),
GlobalMaterialLocalizations.delegate, // );
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate //复制
],
builder: EasyLoading.init(),
supportedLocales: const [
Locale('en', 'US'), // 美国英语
Locale('zh', 'CN'), // 中文简体
//其它Locales
],
theme: ThemeData(
// Color(0xff9182F9)
primarySwatch: createMaterialColor(const Color(0xff9182F9)),
// AppColors.themeColorGreen,
visualDensity: VisualDensity.adaptivePlatformDensity),
);
} }
} }
//调用的时候需要把hex改一下,比如#223344 needs change to 0xFF223344 // () => RefreshConfiguration(
//即把#换成0xFF即可 // headerBuilder: () => ClassicHeader(),
// footerBuilder: () => ClassicFooter(),
MaterialColor createMaterialColor(Color color) { // hideFooterWhenNotFull: true,
List strengths = <double>[.05]; // headerTriggerDistance: 80,
Map<int, Color> swatch = {}; // maxOverScrollExtent: 100,
final int r = color.red, g = color.green, b = color.blue; // footerTriggerDistance: 150,
// child: GetMaterialApp(
for (int i = 1; i < 10; i++) { // title: 'News',
strengths.add(0.1 * i); // theme: AppTheme.light,
} // debugShowCheckedModeBanner: false,
strengths.forEach((strength) { // initialRoute: AppPages.INITIAL,
final double ds = 0.5 - strength; // getPages: AppPages.routes,
swatch[(strength * 1000).round()] = Color.fromRGBO( // builder: EasyLoading.init(),
r + ((ds < 0 ? r : (255 - r)) * ds).round(), // translations: TranslationService(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(), // navigatorObservers: [AppPages.observer],
b + ((ds < 0 ? b : (255 - b)) * ds).round(), // localizationsDelegates: [
1, // GlobalMaterialLocalizations.delegate,
); // GlobalWidgetsLocalizations.delegate,
}); // GlobalCupertinoLocalizations.delegate,
return MaterialColor(color.value, swatch); // ],
} // supportedLocales: ConfigStore.to.languages,
// locale: ConfigStore.to.locale,
void configLoading() { // fallbackLocale: Locale('en', 'US'),
EasyLoading // enableLog: true,
.instance // logWriterCallback: Logger.write,
// ..displayDuration = const Duration(milliseconds: 2000) // ),
// ..indicatorType = EasyLoadingIndicatorType.fadingCircle // ),
// ..loadingStyle = EasyLoadingStyle.dark \ No newline at end of file
// ..indicatorSize = 45.0
// ..radius = 10.0
// ..progressColor = Colors.yellow
// ..backgroundColor = Colors.green
// ..indicatorColor = Colors.yellow
// ..textColor = Colors.yellow
// ..maskColor = Colors.blue.withOpacity(0.5)
// ..userInteractions = false
.userInteractions = false;
// ..customAnimation = CustomAnimation();
}
import 'package:chart/pages/category/index.dart';
import 'package:chart/pages/main/index.dart';
import 'package:get/get.dart';
import 'controller.dart';
class ApplicationBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<ApplicationController>(() => ApplicationController());
Get.lazyPut<MainController>(() => MainController());
Get.lazyPut<CategoryController>(() => CategoryController());
}
}
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import 'package:get/get.dart';
// import 'package:uni_links/uni_links.dart';
import 'index.dart';
class ApplicationController extends GetxController {
ApplicationController();
/// 响应式成员变量
final state = ApplicationState();
/// 成员变量
// tab 页标题
late final List<String> tabTitles;
// 页控制器
late final PageController pageController;
// 底部导航项目
late final List<BottomNavigationBarItem> bottomTabs;
/// 事件
// tab栏动画
void handleNavBarTap(int index) {
pageController.animateToPage(index,
duration: const Duration(milliseconds: 200), curve: Curves.ease);
}
// tab栏页码切换
void handlePageChanged(int page) {
state.page = page;
}
/// scheme 内部打开
bool isInitialUriIsHandled = false;
StreamSubscription? uriSub;
// 第一次打开
Future<void> handleInitialUri() async {
if (!isInitialUriIsHandled) {
isInitialUriIsHandled = true;
try {
final uri = null;
// await getInitialUri();
if (uri == null) {
print('no initial uri');
} else {
// 这里获取了 scheme 请求
print('got initial uri: $uri');
}
} on PlatformException {
print('falied to get initial uri');
} on FormatException catch (err) {
print('malformed initial uri, ' + err.toString());
}
}
}
// 程序打开时介入
void handleIncomingLinks() {
if (!kIsWeb) {
// uriSub = uriLinkStream.listen((Uri? uri) {
// // 这里获取了 scheme 请求
// print('got uri: $uri');
// // if (uri!.pathSegments[1].toLowerCase() == 'category') {
// if (uri != null && uri.path == '/notify/category') {
// Get.toNamed(AppRoutes.Category);
// }
// }, onError: (Object err) {
// print('got err: $err');
// });
}
}
/// 生命周期
@override
void onInit() {
super.onInit();
// handleInitialUri();
// handleIncomingLinks();
// 准备一些静态数据
tabTitles = ['Welcome', 'Cagegory', 'Account'];
bottomTabs = <BottomNavigationBarItem>[
new BottomNavigationBarItem(
icon: Icon(
Iconfont.fav,
color: AppColors.tabBarElement,
),
activeIcon: Icon(
Iconfont.home,
color: AppColors.secondaryElementText,
),
label: 'main',
backgroundColor: AppColors.primaryBackground,
),
new BottomNavigationBarItem(
icon: Icon(
Iconfont.grid,
color: AppColors.tabBarElement,
),
activeIcon: Icon(
Iconfont.grid,
color: AppColors.secondaryElementText,
),
label: 'category',
backgroundColor: AppColors.primaryBackground,
),
// new BottomNavigationBarItem(
// icon: Icon(
// Iconfont.tag,
// color: AppColors.tabBarElement,
// ),
// activeIcon: Icon(
// Iconfont.tag,
// color: AppColors.secondaryElementText,
// ),
// label: 'tag',
// backgroundColor: AppColors.primaryBackground,
// ),
new BottomNavigationBarItem(
icon: Icon(
Iconfont.me,
color: AppColors.tabBarElement,
),
activeIcon: Icon(
Iconfont.me,
color: AppColors.secondaryElementText,
),
label: 'my',
backgroundColor: AppColors.primaryBackground,
),
];
pageController = new PageController(initialPage: state.page);
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {
super.onClose();
}
@override
void dispose() {
uriSub?.cancel();
pageController.dispose();
super.dispose();
}
}
library application;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:get/get.dart';
class ApplicationState {
// 当前 tab 页码
final _page = 0.obs;
set page(value) => this._page.value = value;
get page => this._page.value;
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:chart/pages/category/index.dart';
import 'package:chart/pages/main/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
// import '../dashboard/dashboard_page.dart';
import 'index.dart';
class ApplicationPage extends GetView<ApplicationController> {
// 顶部导航
AppBar _buildAppBar() {
return transparentAppBar(
title: Obx(() => Text(
controller.tabTitles[controller.state.page],
style: TextStyle(
color: AppColors.primaryText,
fontFamily: 'Montserrat',
fontSize: 18.sp,
fontWeight: FontWeight.w600,
),
)),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: AppColors.primaryText,
),
onPressed: () {},
)
]);
}
// 内容页
Widget _buildPageView() {
return PageView(
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
MainPage(),
// DashBoardPage(),
// Text("data"),
// Text("da"),
// MainPage(),
CategoryPage(),
Text('BookmarksPage'),
Text('AccountPage'),
],
controller: controller.pageController,
onPageChanged: controller.handlePageChanged,
);
}
// 底部导航
Widget _buildBottomNavigationBar() {
// bottomNavigationBar: CurvedNavigationBar(
// key: _bottomNavigationKey,
// index: 0,
// height: 70.0,
// items: <Widget>[
// // Container(
// // width: 50,
// // height: 50,
// // // width: double.infinity,
// // // height: 100,
// // decoration: BoxDecoration(
// // // color: Colors.white,
// // gradient: LinearGradient(
// // begin: Alignment.topCenter,
// // end: Alignment.bottomCenter,
// // colors: [Color(0xffB8ACFF), Color(0xff9182F9)],
// // ),
// // borderRadius: BorderRadius.circular(8.0),
// // boxShadow: [
// // BoxShadow(
// // color: Colors.red,
// // offset: Offset(0.0, 15.0), //阴影xy轴偏移量
// // blurRadius: 15.0, //阴影模糊程度
// // spreadRadius: 1.0 //阴影扩散程度
// // )
// // ]),
// // child: Icon(Icons.add, size: 30),
// // ),
// Icon(Icons.add, size: 30),
// Icon(Icons.list, size: 30),
// Icon(Icons.compare_arrows, size: 30),
// // Icon(Icons.call_split, size: 30),
// // Icon(Icons.perm_identity, size: 30),
// ],
// color: Colors.white,
// // rgba(238, 242, 248, 1.00)
// buttonBackgroundColor: Color.fromRGBO(238, 242, 248, 1.00),
// backgroundColor: Color(0xff9182F9),
// animationCurve: Curves.easeInOut,
// animationDuration: Duration(milliseconds: 600),
// onTap: (index) {
// setState(() {
// _selectedIndex = index;
// });
// },
// letIndexChange: (index) => true,
// ),
return Obx(() => BottomNavigationBar(
items: controller.bottomTabs,
currentIndex: controller.state.page,
// fixedColor: AppColors.primaryElement,
type: BottomNavigationBarType.fixed,
onTap: controller.handleNavBarTap,
showSelectedLabels: false,
showUnselectedLabels: false,
));
}
@override
Widget build(BuildContext context) {
return Obx(() => Scaffold(
appBar: controller.state.page == 0 ? null : _buildAppBar(),
body: _buildPageView(),
bottomNavigationBar: _buildBottomNavigationBar(),
));
}
}
import 'package:get/get.dart';
import 'controller.dart';
class CategoryBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<CategoryController>(() => CategoryController());
}
}
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'index.dart';
class CategoryController extends GetxController {
CategoryController();
/// UI 组件
final RefreshController refreshController = RefreshController(
initialRefresh: true,
);
/// 响应式成员变量
final state = CategoryState();
/// 成员变量
String categoryCode = '';
int curPage = 1;
int pageSize = 20;
int total = 20;
/// 事件
void onRefresh() {
fetchNewsList(isRefresh: true).then((_) {
refreshController.refreshCompleted(resetFooterState: true);
}).catchError((_) {
refreshController.refreshFailed();
});
}
void onLoading() {
if (state.newsList.length < total) {
fetchNewsList().then((_) {
refreshController.loadComplete();
}).catchError((_) {
refreshController.loadFailed();
});
} else {
refreshController.loadNoData();
}
}
// 方法
// 拉取数据
Future<void> fetchNewsList({bool isRefresh = false}) async {
// var result = await NewsAPI.newsPageList(
// params: NewsPageListRequestEntity(
// categoryCode: categoryCode,
// pageNum: curPage + 1,
// pageSize: pageSize,
// ),
// );
// if (isRefresh == true) {
// curPage = 1;
// total = result.counts!;
// state.newsList.clear();
// } else {
// curPage++;
// }
// state.newsList.addAll(result.items!);
}
/// 生命周期
///dispose 释放内存
@override
void dispose() {
super.dispose();
// dispose 释放对象
refreshController.dispose();
}
}
library category;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:get/get.dart';
class CategoryState {
// 新闻翻页
RxList<NewsItem> newsList = <NewsItem>[].obs;
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'widgets/widgets.dart';
class CategoryPage extends GetView<CategoryController> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
child: NewsPageList(),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
Widget newsListItem(NewsItem item) {
return Container(
height: 161.h,
padding: EdgeInsets.all(20.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 图
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: netImageCached(
item.thumbnail ?? "",
width: 121.w,
height: 121.w,
),
),
// 右侧
SizedBox(
width: 194.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 作者
Container(
margin: EdgeInsets.all(0),
child: Text(
item.author ?? "",
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
height: 1,
),
),
),
// 标题
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: Container(
margin: EdgeInsets.only(top: 10.h),
child: Text(
item.title ?? "",
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w500,
color: AppColors.primaryText,
fontSize: 16.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 3,
),
),
),
// Spacer
Spacer(),
// 一行 3 列
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 分类
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 60.w,
),
child: Text(
item.category ?? "",
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.secondaryElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 添加时间
Container(
width: 15.w,
),
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 100.w,
),
child: Text(
'• ${duTimeLineFormat(item.addtime ?? DateTime(0))}',
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 更多
Spacer(),
InkWell(
child: Icon(
Icons.more_horiz,
color: AppColors.primaryText,
size: 24.sp,
),
onTap: () {},
),
],
),
),
],
),
),
],
),
);
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../index.dart';
import 'widgets.dart';
class NewsPageList extends StatefulWidget {
NewsPageList({Key? key}) : super(key: key);
@override
_NewsPageListState createState() => _NewsPageListState();
}
class _NewsPageListState extends State<NewsPageList>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
final controller = Get.find<CategoryController>();
@override
Widget build(BuildContext context) {
super.build(context);
return GetX<CategoryController>(
init: controller,
builder: (controller) => SmartRefresher(
enablePullUp: true,
controller: controller.refreshController,
onRefresh: controller.onRefresh,
onLoading: controller.onLoading,
child: CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.symmetric(
vertical: 0.w,
horizontal: 0.w,
),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(content, index) {
var item = controller.state.newsList[index];
return newsListItem(item);
},
childCount: controller.state.newsList.length,
),
),
),
],
),
),
);
}
}
library widgets;
export 'news_page_list.dart';
export 'news_item.dart';
...@@ -9,7 +9,7 @@ import 'dart:math'; ...@@ -9,7 +9,7 @@ import 'dart:math';
import 'package:glassmorphism/glassmorphism.dart'; import 'package:glassmorphism/glassmorphism.dart';
import '../../../service/message_service.dart'; import '../../../service/message_service.dart';
import '../../chat/chat_page.dart'; // import '../../chat/chat_page.dart';
const List<Color> kCategoriesPrimaryColor = [ const List<Color> kCategoriesPrimaryColor = [
Color(0xffFFCA8C), Color(0xffFFCA8C),
...@@ -238,13 +238,6 @@ class SwiperPageState extends State<SwiperPage> { ...@@ -238,13 +238,6 @@ class SwiperPageState extends State<SwiperPage> {
child: Column( child: Column(
children: children:
_loading ? [const Text("loading")] : _renderList(index)), _loading ? [const Text("loading")] : _renderList(index)),
// child: ClipRRect(
// borderRadius: BorderRadius.circular(16),
// child: Image.network(
// "https://img14.360buyimg.com/babel/s700x360_jfs/t1/4099/12/2578/101668/5b971b4bE65ae279d/89dd1764797acfd9.jpg!q90!cc_350x180",
// fit: BoxFit.cover,
// ),
// )
); );
}, },
// viewportFraction: 0.8, // viewportFraction: 0.8,
......
...@@ -71,12 +71,12 @@ class DashBoardPageState extends State<DashBoardPage> { ...@@ -71,12 +71,12 @@ class DashBoardPageState extends State<DashBoardPage> {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
children: [ children: [
DoctorAppBar(_userModel), // DoctorAppBar(_userModel),
SwiperPage(), // SwiperPage(),
// SwiperColunmPage(), // // SwiperColunmPage(),
BannerPage(), // BannerPage(),
ListPage(), // ListPage(),
], ],
), ),
), ),
...@@ -123,8 +123,6 @@ class DashBoardPageState extends State<DashBoardPage> { ...@@ -123,8 +123,6 @@ class DashBoardPageState extends State<DashBoardPage> {
} }
} }
class viod {}
class DismissKeyboardDemo extends StatelessWidget { class DismissKeyboardDemo extends StatelessWidget {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
......
import 'package:get/get.dart';
import 'controller.dart';
class NotfoundBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<NotfoundController>(() => NotfoundController());
}
}
import 'package:get/get.dart';
import 'index.dart';
class NotfoundController extends GetxController {
NotfoundController();
/// 响应式成员变量
final state = NotfoundState();
/// 成员变量
/// 事件
// tap
void handleTap(int index) {
Get.snackbar(
"标题",
"消息",
);
}
/// 生命周期
///在 widget 内存中分配后立即调用。
///你可以用它来为控制器初始化 initialize 一些东西。
@override
void onInit() {
super.onInit();
// new 对象
// 初始静态数据
}
///在 onInit() 之后调用 1 帧。这是进入的理想场所
///导航事件,例如 snackbar、对话框或新route,或
///async 异步请求。
@override
void onReady() {
super.onReady();
// async 拉取数据
}
///在 [onDelete] 方法之前调用。 [onClose] 可能用于
///处理控制器使用的资源。就像 closing events 一样,
///或在控制器销毁之前的流。
///或者处置可能造成一些内存泄漏的对象,
///像 TextEditingControllers、AnimationControllers。
///将一些数据保存在磁盘上也可能很有用。
@override
void onClose() {
super.onClose();
// 1 stop & close 关闭对象
// 2 save 持久化数据
}
///dispose 释放内存
@override
void dispose() {
super.dispose();
// dispose 释放对象
}
}
library notfound;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:get/get.dart';
class NotfoundState {
// title
final _title = "".obs;
set title(value) => this._title.value = value;
get title => this._title.value;
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'widgets/widgets.dart';
class NotfoundPage extends GetView<NotfoundController> {
// 内容页
Widget _buildView() {
return HellowordWidget();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildView(),
);
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../index.dart';
/// hellowrod
class HellowordWidget extends GetView<NotfoundController> {
@override
Widget build(BuildContext context) {
return Center(
child: Obx(() => Text(controller.state.title)),
);
}
}
library widgets;
export './helloword.dart';
import 'package:get/get.dart';
import 'controller.dart';
class SignInBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<SignInController>(() => SignInController());
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/store/store.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:get/get.dart';
import 'index.dart';
class SignInController extends GetxController {
final state = SignInState();
SignInController();
// email的控制器
final TextEditingController emailController = TextEditingController();
// 密码的控制器
final TextEditingController passController = TextEditingController();
// final MyRepository repository;
// SignInController({@required this.repository}) : assert(repository != null);
// 跳转 注册界面
handleNavSignUp() {
Get.toNamed(AppRoutes.SIGN_UP);
}
// 忘记密码
handleFogotPassword() {
toastInfo(msg: '忘记密码');
}
// 执行登录操作
handleSignIn() async {
// if (!duIsEmail(_emailController.value.text)) {
// toastInfo(msg: '请正确输入邮件');
// return;
// }
// if (!duCheckStringLength(_passController.value.text, 6)) {
// toastInfo(msg: '密码不能小于6位');
// return;
// }
UserLoginRequestEntity params = UserLoginRequestEntity(
email: emailController.value.text,
password: duSHA256(passController.value.text),
);
UserLoginResponseEntity userProfile = await UserAPI.login(
params: params,
);
UserStore.to.saveProfile(userProfile);
Get.offAndToNamed(AppRoutes.Application);
}
@override
void onReady() {
super.onReady();
}
@override
void dispose() {
emailController.dispose();
passController.dispose();
super.dispose();
}
}
library sign_in;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:get/get.dart';
class SignInState {
final _obj = ''.obs;
set obj(value) => this._obj.value = value;
get obj => this._obj.value;
// SignInState() {}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'index.dart';
class SignInPage extends GetView<SignInController> {
// logo
Widget _buildLogo() {
return Container(
width: 110.w,
margin: EdgeInsets.only(top: (40 + 44.0).h), // 顶部系统栏 44px
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: 76.w,
width: 76.w,
margin: EdgeInsets.symmetric(horizontal: 15.w),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
left: 0,
top: 0,
right: 0,
child: Container(
height: 76.w,
decoration: BoxDecoration(
color: AppColors.primaryBackground,
boxShadow: [
Shadows.primaryShadow,
],
borderRadius: BorderRadius.all(
Radius.circular((76 * 0.5).w)), // 父容器的50%
),
child: Container(),
),
),
Positioned(
top: 13.w,
child: Image.asset(
"assets/images/logo.png",
fit: BoxFit.none,
),
),
],
),
),
Container(
margin: EdgeInsets.only(top: 15.h),
child: Text(
"SECTOR",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,
fontSize: 24.sp,
height: 1,
),
),
),
Text(
"news",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 16.sp,
height: 1,
),
),
],
),
);
}
// 登录表单
Widget _buildInputForm() {
return Container(
width: 295.w,
// height: 204,
margin: EdgeInsets.only(top: 49.h),
child: Column(
children: [
// email input
inputTextEdit(
controller: controller.emailController,
keyboardType: TextInputType.emailAddress,
hintText: "Email",
marginTop: 0,
// autofocus: true,
),
// password input
inputTextEdit(
controller: controller.passController,
keyboardType: TextInputType.visiblePassword,
hintText: "Password",
isPassword: true,
),
// 注册、登录 横向布局
Container(
height: 44.h,
margin: EdgeInsets.only(top: 15.h),
child: Row(
children: [
// 注册
btnFlatButtonWidget(
onPressed: controller.handleNavSignUp,
gbColor: AppColors.thirdElement,
title: "Sign up",
),
Spacer(),
// 登录
btnFlatButtonWidget(
onPressed: controller.handleSignIn,
gbColor: AppColors.primaryElement,
title: "Sign in",
),
],
),
),
// Spacer(),
// Fogot password
Padding(
padding: EdgeInsets.only(top: 8.0),
child: TextButton(
onPressed: controller.handleFogotPassword,
child: Text(
"Fogot password?",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.secondaryElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 16.sp,
height: 1, // 设置下行高,否则字体下沉
),
),
),
),
],
),
);
}
// 第三方登录
Widget _buildThirdPartyLogin() {
return Container(
width: 295.w,
margin: EdgeInsets.only(bottom: 40.h),
child: Column(
children: <Widget>[
// title
Text(
"Or sign in with social networks",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 16.sp,
),
),
// 按钮
Padding(
padding: EdgeInsets.only(top: 20.h),
child: Row(
children: <Widget>[
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "twitter",
),
Spacer(),
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "google",
),
Spacer(),
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "facebook",
),
],
),
),
],
),
);
}
// 注册按钮
Widget _buildSignupButton() {
return Container(
margin: EdgeInsets.only(bottom: 20.h),
child: btnFlatButtonWidget(
onPressed: controller.handleNavSignUp,
width: 294,
gbColor: AppColors.secondaryElement,
fontColor: AppColors.primaryText,
title: "Sign up",
fontWeight: FontWeight.w500,
fontSize: 16,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Center(
child: Column(
children: <Widget>[
_buildLogo(),
_buildInputForm(),
Spacer(),
_buildThirdPartyLogin(),
_buildSignupButton(),
],
),
),
);
}
}
import 'package:get/get.dart';
import 'controller.dart';
class SignUpBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<SignUpController>(() => SignUpController());
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:get/get.dart';
import 'index.dart';
class SignUpController extends GetxController {
SignUpController();
/// obs 响应式变量 才写入 state
final state = SignUpState();
/// 业务变量
final TextEditingController fullnameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController passController = TextEditingController();
/// 业务事件
// 返回上一页
handleNavPop() {
Get.back();
}
// 提示信息
handleTip() {
toastInfo(msg: '这是注册界面');
}
// 忘记密码
handleFogotPassword() {
toastInfo(msg: '忘记密码');
}
// 执行注册操作
handleSignUp() async {
// if (!duCheckStringLength(fullnameController.value.text, 5)) {
// toastInfo(msg: '用户名不能小于5位');
// return;
// }
// if (!duIsEmail(emailController.value.text)) {
// toastInfo(msg: '请正确输入邮件');
// return;
// }
// if (!duCheckStringLength(passController.value.text, 6)) {
// toastInfo(msg: '密码不能小于6位');
// return;
// }
UserRegisterRequestEntity params = UserRegisterRequestEntity(
email: emailController.value.text,
password: duSHA256(passController.value.text),
);
await UserAPI.register(
params: params,
);
Get.back();
}
/// 生命周期
// 页面载入完成
@override
void onReady() {
super.onReady();
}
@override
void dispose() {
fullnameController.dispose();
emailController.dispose();
passController.dispose();
super.dispose();
}
}
library sign_up;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:get/get.dart';
class SignUpState {
/// 响应变量用 get set 包下
final _obj = ''.obs;
set obj(value) => this._obj.value = value;
get obj => this._obj.value;
// SignUpState() {}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'index.dart';
class SignUpPage extends GetView<SignUpController> {
// logo
Widget _buildLogo() {
return Container(
margin: EdgeInsets.only(top: 50.h),
child: Text(
"Sign up",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,
fontSize: 24.sp,
height: 1,
),
),
);
}
// 注册表单
Widget _buildInputForm() {
return Container(
width: 295.w,
// height: 204,
margin: EdgeInsets.only(top: 49.h),
child: Column(
children: [
// fullName input
inputTextEdit(
controller: controller.fullnameController,
keyboardType: TextInputType.text,
hintText: "Full name",
marginTop: 0,
),
// email input
inputTextEdit(
controller: controller.emailController,
keyboardType: TextInputType.emailAddress,
hintText: "Email",
),
// password input
inputTextEdit(
controller: controller.passController,
keyboardType: TextInputType.visiblePassword,
hintText: "Password",
isPassword: true,
),
// 创建
Container(
height: 44.h,
margin: EdgeInsets.only(top: 15.h),
child: btnFlatButtonWidget(
onPressed: controller.handleSignUp,
width: 295.w,
fontWeight: FontWeight.w600,
title: "Create an account",
),
),
// Spacer(),
// Fogot password
Padding(
padding: EdgeInsets.only(top: 8.0),
child: TextButton(
onPressed: controller.handleFogotPassword,
child: Text(
"Fogot password?",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.secondaryElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 16.sp,
height: 1, // 设置下行高,否则字体下沉
),
),
),
),
],
),
);
}
// 第三方
Widget _buildThirdPartyLogin() {
return Container(
width: 295.w,
margin: EdgeInsets.only(bottom: 40.h),
child: Column(
children: <Widget>[
// title
Text(
"Or sign in with social networks",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 16.sp,
),
),
// 按钮
Padding(
padding: EdgeInsets.only(top: 20.h),
child: Row(
children: <Widget>[
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "twitter",
),
Spacer(),
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "google",
),
Spacer(),
btnFlatButtonBorderOnlyWidget(
onPressed: () {},
width: 88,
iconFileName: "facebook",
),
],
),
),
],
),
);
}
// 有账号
Widget _buildHaveAccountButton() {
return Container(
margin: EdgeInsets.only(bottom: 20.h),
child: btnFlatButtonWidget(
onPressed: controller.handleNavPop,
width: 294,
gbColor: AppColors.secondaryElement,
fontColor: AppColors.primaryText,
title: "I have an account",
fontWeight: FontWeight.w500,
fontSize: 16,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: transparentAppBar(
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: AppColors.primaryText,
),
onPressed: controller.handleNavPop,
),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.info_outline,
color: AppColors.primaryText,
),
onPressed: controller.handleTip,
)
],
),
body: Center(
child: Column(
children: <Widget>[
Divider(height: 1),
_buildLogo(),
_buildInputForm(),
Spacer(),
_buildThirdPartyLogin(),
_buildHaveAccountButton(),
],
),
),
);
}
}
import 'package:get/get.dart';
import 'controller.dart';
class WelcomeBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<WelcomeController>(() => WelcomeController());
}
}
import 'package:chart/common/routers/routes.dart';
import 'package:chart/common/store/store.dart';
import 'package:get/get.dart';
import 'index.dart';
class WelcomeController extends GetxController {
final state = WelcomeState();
WelcomeController();
// 跳转 注册界面
handleNavSignIn() async {
await ConfigStore.to.saveAlreadyOpen();
Get.offAndToNamed(AppRoutes.SIGN_IN);
}
// 跳转 注册界面
handleHome() async {
await ConfigStore.to.saveAlreadyOpen();
Get.offAndToNamed(AppRoutes.Application);
}
@override
void onReady() {
super.onReady();
}
}
library welcome;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:get/get.dart';
class WelcomeState {
final _obj = ''.obs;
set obj(value) => this._obj.value = value;
get obj => this._obj.value;
// WelcomeState() {}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'index.dart';
class WelcomePage extends GetView<WelcomeController> {
/// 页头标题
Widget _buildPageHeadTitle() {
return Container(
margin: EdgeInsets.only(top: (60 + 44.0).h), // 顶部系统栏 44px
child: Text(
"Features",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Montserrat",
fontWeight: FontWeight.w600,
fontSize: 24.sp,
height: 1,
),
),
);
}
/// 页头说明
Widget _buildPageHeaderDetail() {
return Container(
width: 242.w,
height: 70.h,
margin: EdgeInsets.only(top: 14.h),
child: Text(
"The best of news channels all in one place. Trusted sources and personalized news for you.",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.normal,
fontSize: 16.sp,
height: 1.3,
),
),
);
}
/// 特性说明
/// 宽度 80 + 20 + 195 = 295
Widget _buildFeatureItem(String imageName, String intro, double marginTop) {
return Container(
width: 295.w,
height: 80.h,
margin: EdgeInsets.only(top: marginTop.h),
child: Row(
children: [
Container(
width: 80.w,
height: 80.w,
child: Image.asset(
"assets/images/$imageName.png",
fit: BoxFit.none,
),
),
Spacer(),
Container(
width: 195.w,
child: Text(
intro,
textAlign: TextAlign.left,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.normal,
fontSize: 16.sp,
),
),
),
],
),
);
}
/// 开始按钮
Widget _buildStartButton(BuildContext context) {
return Container(
width: 295.w,
height: 44.h,
margin: EdgeInsets.only(bottom: 20.h),
child: TextButton(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(TextStyle(
fontSize: 16.sp,
)),
foregroundColor: MaterialStateProperty.resolveWith(
(states) {
if (states.contains(MaterialState.focused) &&
!states.contains(MaterialState.pressed)) {
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
return Colors.deepPurple;
}
return AppColors.primaryElementText;
},
),
backgroundColor: MaterialStateProperty.resolveWith((states) {
if (states.contains(MaterialState.pressed)) {
return Colors.blue[200];
}
return AppColors.primaryElement;
}),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: Radii.k6pxRadius,
)),
),
child: Text("开始"),
onPressed: controller.handleHome,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
// Text("data")
_buildPageHeadTitle(),
_buildPageHeaderDetail(),
_buildFeatureItem(
"feature-1",
"Compelling photography and typography provide a beautiful reading",
86,
),
_buildFeatureItem(
"feature-2",
"Sector news never shares your personal data with advertisers or publishers",
40,
),
_buildFeatureItem(
"feature-3",
"You can get Premium to unlock hundreds of publications",
40,
),
Spacer(),
_buildStartButton(context),
],
),
),
);
}
}
export 'application/index.dart';
export 'category/index.dart';
export 'frame/notfound/index.dart';
export 'frame/sign_in/index.dart';
export 'frame/sign_up/index.dart';
export 'frame/welcome/index.dart';
export 'main/index.dart';
import 'package:get/get.dart';
import 'controller.dart';
class MainBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<MainController>(() => MainController());
}
}
import 'package:chart/common/apis/apis.dart';
import 'package:chart/common/entities/classFyDetail.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:get/get.dart';
import 'index.dart';
class MainController extends GetxController {
MainController();
/// 响应式成员变量
final state = MainState();
/// 成员变量
/// 方法
// 拉取数据
asyncLoadAllData() async {
state.categories = await NewsAPI.categories(
cacheDisk: true,
);
state.channels = await NewsAPI.channels(
cacheDisk: true,
);
state.newsRecommend = await NewsAPI.newsRecommend(
cacheDisk: true,
);
// state.newsPageList = await NewsAPI.newsPageList(
// cacheDisk: true,
// );
state.selCategoryCode = state.categories.first.code;
}
asyncLoadBannerData() async {
// state.bannerList = await NewsAPI.bannerList();
List<MessageEntity>? list = await NewsAPI.bannerList();
state.bannerList = constructList(3, list!);
List<ClassifyEntity>? _bannerPage = await NewsAPI.bannerPage();
state.bannerPage = _bannerPage;
int _classFyId = _bannerPage[0].id;
state.selectorId = _bannerPage[0].id;
List<ClassifyDetialEntity>? _classFyList =
await NewsAPI.classFyDetialList({"id": _classFyId});
state.bannerPageDetail = _classFyList;
// bannerPageDetail
// state.categories = await NewsAPI.categories(
// cacheDisk: true,
// );
// state.channels = await NewsAPI.channels(
// cacheDisk: true,
// );
// state.newsRecommend = await NewsAPI.newsRecommend(
// cacheDisk: true,
// );
// state.newsPageList = await NewsAPI.newsPageList(
// cacheDisk: true,
// );
// state.selCategoryCode = state.categories.first.code;
}
getGlassDetail(int id) async {
state.selectorId = id;
List<ClassifyDetialEntity>? _classFyList =
await NewsAPI.classFyDetialList({"id": id});
state.bannerPageDetail = _classFyList;
}
// 拉取推荐、新闻
asyncLoadNewsData(
categoryCode, {
bool refresh = false,
}) async {
// state.selCategoryCode = categoryCode;
// state.newsRecommend = await NewsAPI.newsRecommend(
// params: NewsRecommendRequestEntity(categoryCode: categoryCode),
// refresh: refresh,
// cacheDisk: true,
// );
// state.newsPageList = await NewsAPI.newsPageList(
// params: NewsPageListRequestEntity(categoryCode: categoryCode),
// refresh: refresh,
// cacheDisk: true,
// );
}
/// 事件
/// 生命周期
/// 初始
@override
void onInit() {
super.onInit();
}
/// 可 async 拉取数据
/// 可触发展示交互组件
/// onInit 之后
@override
void onReady() {
super.onReady();
// asyncLoadAllData();
asyncLoadBannerData();
}
/// 关闭页面
/// 可以缓存数据,关闭各种控制器
/// dispose 之前
@override
void onClose() {
super.onClose();
}
/// 被释放
/// 手动 释放各种内存资源
@override
void dispose() {
super.dispose();
}
}
List<List<MessageEntity>>? constructList(int len, List<MessageEntity> list) {
var length = list.length; //列表数组数据总条数
List<List<MessageEntity>> result = []; //结果集合
int index = 1;
//循环 构造固定长度列表数组
while (true) {
if (index * len < length) {
List<MessageEntity> temp =
list.skip((index - 1) * len).take(len).toList();
result.add(temp);
index++;
continue;
}
List<MessageEntity> temp = list.skip((index - 1) * len).toList();
result.add(temp);
break;
}
return result;
}
library main;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/entity/plan_entity.dart';
import 'package:get/get.dart';
import '../../common/entities/classFyDetail.dart';
class MainState {
// 分类
var _categories = Rx<List<CategoryResponseEntity>?>(null);
set categories(value) => _categories.value = value;
get categories => _categories.value;
// 新闻翻页
var _newsPageList = Rx<NewsPageListResponseEntity?>(null);
set newsPageList(value) => _newsPageList.value = value;
get newsPageList => _newsPageList.value;
void appendNewsPageList(NewsPageListResponseEntity value) {
if (_newsPageList.value != null) {
_newsPageList.value!.items?.addAll(value.items!.toList());
}
}
// banner
var _bannerList = Rx<List<List<MessageEntity>>?>([]);
set bannerList(value) => _bannerList.value = value;
List<List<MessageEntity>>? get bannerList => _bannerList.value;
// banner分类列表
var _bannerPage = Rx<List<ClassifyEntity>?>([]);
set bannerPage(value) => _bannerPage.value = value;
List<ClassifyEntity>? get bannerPage => _bannerPage.value;
//选中bannerid
var _selectorId = Rx<int>(0);
set selectorId(value) => _selectorId.value = value;
int get selectorId => _selectorId.value;
// banner分类详情
var _bannerPageDetail = Rx<List<ClassifyDetialEntity>?>([]);
set bannerPageDetail(value) => _bannerPageDetail.value = value;
List<ClassifyDetialEntity>? get bannerPageDetail => _bannerPageDetail.value;
// /api/classifyDetail/getClassifyDetailById/1
// 新闻推荐
var _newsRecommend = Rx<NewsItem?>(null);
set newsRecommend(value) => _newsRecommend.value = value;
get newsRecommend => _newsRecommend.value;
// 频道
var _channels = Rx<List<ChannelResponseEntity>?>(null);
set channels(value) => _channels.value = value;
get channels => _channels.value;
// 选中的分类Code
var _selCategoryCode = "".obs;
set selCategoryCode(value) => _selCategoryCode.value = value;
get selCategoryCode => _selCategoryCode.value;
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
// import '../dashboard/components/swiper.dart';
import 'index.dart';
import 'widgets/widgets.dart';
class MainPage extends GetView<MainController> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: Image.asset("assets/images/bg.png").image,
fit: BoxFit.cover),
),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: <Widget>[
NewsCategoriesWidget(),
SiperBannerWidget(),
BannerPageWidget(),
ListPageWidget(),
// NewsRecommendWidget()
// SiperBannerWidget(),
// SiperBannerWidget(),
// Divider(height: 10),
// NewsRecommendWidget(),
// Divider(height: 1),
// NewsChannelsWidget(),
// Divider(height: 1),
// NewsListWidget(),
// Divider(height: 1),
// NewsletterWidget(),
],
),
),
));
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../index.dart';
/// ad广告
class AdWidget extends GetView<MainController> {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 100.w,
padding: EdgeInsets.all(20.w),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20.w),
decoration: BoxDecoration(
border: Border.fromBorderSide(Borders.primaryBorder),
borderRadius: Radii.k6pxRadius,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Tired of Ads? Get Premium - \$9.99",
textAlign: TextAlign.center,
style: TextStyle(
color: AppColors.primaryText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 18.sp,
height: 18.sp / 18,
),
),
],
),
),
);
}
}
import 'package:chart/models/user_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// import '../size_confige.dart';
class DoctorAppBar extends StatelessWidget {
const DoctorAppBar(
this.userModel, {
Key? key,
}) : super(key: key);
final UserModel userModel;
// late final UserModel _userModel;
// @override
// didChangeDependencies() {
// super.didChangeDependencies();
// _userModel = Provider.of<UserModel>(context);
// }
@override
Widget build(BuildContext context) {
UserModel userViewModel = Provider.of<UserModel>(context);
// final text = Provider.of<String>(context);
// _userModel = Provider.of<UserModel>(context);
// ${userViewModel.integralEntity?.username}
print(userViewModel.integralEntity);
return Container(
width: double.infinity,
child: Padding(
padding: EdgeInsets.only(left: 20, top: 60, right: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
// ignore: prefer_const_literals_to_create_immutables
children: [
// ignore: prefer_const_constructors
Text(
"Hi, ${userViewModel.integralEntity?.username}",
// ignore: prefer_const_constructors
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w800,
fontSize: 20),
),
SizedBox(height: 30),
// ignore: prefer_const_constructors
Text(
"欢迎使用GPT大师傅,你可以收获很多",
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
GestureDetector(
onTap: () => {Navigator.of(context).pushNamed('/goods')},
child: Container(
height: 60,
width: 60,
decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// blurRadius: 3,
// offset: Offset(0, 4),
// color: Colors.black54,
// )
// ],
// color: Color(0xffA295FD),
borderRadius: BorderRadius.circular(5)),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset("assets/images/dingyue.png")),
),
)
],
),
),
);
}
}
import 'package:chart/entity/plan_entity.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:card_swiper/card_swiper.dart';
import '../index.dart';
import 'package:glassmorphism/glassmorphism.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'widgets.dart';
/// 放宽
class BannerPageWidget extends GetView<MainController> {
const BannerPageWidget({super.key});
@override
Widget build(BuildContext context) {
final controllerPage =
PageController(viewportFraction: 0.8, keepPage: true);
return Obx(() => controller.state.bannerPage!.isEmpty
? Container()
: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 16),
SizedBox(
height: 270,
child: PageView.builder(
controller: controllerPage,
onPageChanged: (value) => {
controller.getGlassDetail(
controller.state.bannerPage![value].id)
},
itemCount: controller.state.bannerPage!.length,
itemBuilder: (_, index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
),
margin:
EdgeInsets.symmetric(horizontal: 10, vertical: 4),
child: GlassmorphicContainer(
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
],
),
height: 270,
width: double.infinity,
child: Column(
children: [
Row(
children: [
Expanded(
// width: double.infinity,
// height: 400,
child: Stack(
children: [
Container(
width: 300,
height: 130,
padding: EdgeInsets.only(top: 16),
child: Image.asset(
doctorsList[index].image,
fit: BoxFit.contain,
width: double.infinity,
height: double.infinity,
),
),
],
),
),
// SizedBox(width: 40)
],
),
Container(
// ignore: prefer_const_constructors
decoration: BoxDecoration(
// circular(24)
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(16),
bottomRight: Radius.circular(16),
),
// color: Colors.white,
),
//
// color: Colors.white,
height: 132,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 20, horizontal: 20),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
controller.state.bannerPage![index]
.classifyName,
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 24),
),
SizedBox(height: 5),
Text(
controller.state.bannerPage![index]
.classifyDesc,
style: TextStyle(
color: Colors.white,
fontSize: 16),
),
SizedBox(height: 5),
Row(
children: [
RatingBar.builder(
unratedColor:
Colors.grey.withOpacity(0.5),
itemSize: 15,
initialRating: doctorsList[index]
.reviewScore
.toDouble(),
minRating: 0,
allowHalfRating: true,
direction: Axis.horizontal,
itemPadding: EdgeInsets.symmetric(
horizontal: 5),
itemCount: 5,
updateOnDrag: false,
itemBuilder: (context, _) => Icon(
Icons.star,
color: Colors.orange,
),
onRatingUpdate: (value) {},
),
SizedBox(width: 1),
Text(
"(103个用户使用过)",
style: TextStyle(
color: Colors.white,
fontSize: 12),
)
],
),
],
),
)),
],
),
),
);
// return controller.state.bannerPage![index % pages.length];
},
),
),
Container(
// color: Colors.red.withOpacity(.4),
child: SmoothPageIndicator(
// onDotClicked: (index) => {print("$index")},
controller: controllerPage,
count: controller.state.bannerPage!.length,
effect: CustomizableEffect(
activeDotDecoration: DotDecoration(
width: 32,
height: 12,
color: Colors.indigo,
rotationAngle: 180,
verticalOffset: -10,
borderRadius: BorderRadius.circular(24),
// dotBorder: DotBorder(
// padding: 2,
// width: 2,
// color: Colors.indigo,
// ),
),
dotDecoration: DotDecoration(
width: 24,
height: 12,
color: Colors.grey,
// dotBorder: DotBorder(
// padding: 2,
// width: 2,
// color: Colors.grey,
// ),
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(2),
// topRight: Radius.circular(16),
// bottomLeft: Radius.circular(16),
// bottomRight: Radius.circular(2)),
borderRadius: BorderRadius.circular(16),
verticalOffset: 0,
),
spacing: 6.0,
activeColorOverride: (i) => kCategoriesSecondryColor[i],
inActiveColorOverride: (i) => kCategoriesSecondryColor[i],
),
),
),
],
),
));
}
}
class Doctor {
final String name, speciality, image;
final int reviews;
final int reviewScore;
Doctor(
{required this.name,
required this.speciality,
required this.image,
required this.reviews,
required this.reviewScore});
}
final doctorsList = [
Doctor(
name: "通用型",
speciality: "通用聊天",
image: "assets/images/doctor_1.png",
reviews: 80,
reviewScore: 4),
Doctor(
name: "英汉互译",
speciality: "翻译高手",
image: "assets/images/doctor_2.png",
reviews: 67,
reviewScore: 5),
Doctor(
name: "面试官",
speciality: "谷歌面试官帮你面试",
image: "assets/images/doctor_3.png",
reviews: 19,
reviewScore: 4),
Doctor(
name: "知音",
speciality: "最懂你的女生",
image: "assets/images/doctor_2.png",
reviews: 19,
reviewScore: 5),
];
const kLightTextColor = Color(0xffB5C8E7);
const kHardTextColor = Color(0xff586191);
const kPrimaryDarkColor = Color(0xff46BDFA);
const kPrimarylightColor = Color(0xff77E2FE);
const kBackgroundColor = Color(0xffEFF2F7);
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
/// 分类导航
class NewsCategoriesWidget extends GetView<MainController> {
// NewsCategoriesWidget();
@override
Widget build(BuildContext context) {
return Obx(() => controller.state.bannerList == null
? Container()
: Container(
// color: Colors.red,
// width: ,
// height: 300.h,
child: Padding(
padding: const EdgeInsets.only(
left: 0, top: 60, right: 0, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
// ignore: prefer_const_literals_to_create_immutables
children: [
// ignore: prefer_const_constructors
Text(
"Hi, userViewModel.",
// ignore: prefer_const_constructors
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w800,
fontSize: 20.sp),
),
SizedBox(height: 30),
// ignore: prefer_const_constructors
Text(
"欢迎使用GPT大师傅,你可以收获很多",
style:
TextStyle(color: Colors.white, fontSize: 12.sp),
),
],
),
GestureDetector(
onTap: () =>
{Navigator.of(context).pushNamed('/goods')},
child: Container(
height: 60.h,
width: 60.w,
decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// blurRadius: 3,
// offset: Offset(0, 4),
// color: Colors.black54,
// )
// ],
// color: Color(0xffA295FD),
borderRadius: BorderRadius.circular(5.r)),
child: ClipRRect(
borderRadius: BorderRadius.circular(5.r),
child: Image.asset("assets/images/dingyue.png")),
),
)
],
),
),
)
// SingleChildScrollView(
// scrollDirection: Axis.horizontal,
// child: Row(
// children: controller.state.categories.map<Widget>((item) {
// return Container(
// alignment: Alignment.center,
// height: 52.h,
// padding: EdgeInsets.symmetric(horizontal: 8),
// child: GestureDetector(
// child: Text(
// item.title,
// style: TextStyle(
// color: controller.state.selCategoryCode == item.code
// ? AppColors.secondaryElementText
// : AppColors.primaryText,
// fontSize: 18.sp,
// fontFamily: 'Montserrat',
// fontWeight: FontWeight.w600,
// ),
// ),
// onTap: () {
// // 拉取数据
// controller.asyncLoadNewsData(item.code);
// },
// ),
// );
// }).toList(),
// ),
// ),
);
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
/// 分类导航
class NewsCategoriesWidget extends GetView<MainController> {
NewsCategoriesWidget();
@override
Widget build(BuildContext context) {
return Obx(
() => controller.state.categories == null
? Container()
: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: controller.state.categories.map<Widget>((item) {
return Container(
alignment: Alignment.center,
height: 52.h,
padding: EdgeInsets.symmetric(horizontal: 8),
child: GestureDetector(
child: Text(
item.title,
style: TextStyle(
color: controller.state.selCategoryCode == item.code
? AppColors.secondaryElementText
: AppColors.primaryText,
fontSize: 18.sp,
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
),
),
onTap: () {
// 拉取数据
controller.asyncLoadNewsData(item.code);
},
),
);
}).toList(),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
/// 频道导航
class NewsChannelsWidget extends GetView<MainController> {
const NewsChannelsWidget({super.key});
@override
Widget build(BuildContext context) {
return Obx(
() => controller.state.channels == null
? Container()
: Container(
height: 137.w,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: controller.state.channels.map<Widget>((item) {
// 项
return Container(
width: 70.w,
height: 97.w,
margin: EdgeInsets.symmetric(horizontal: 10),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
// crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 图标
Container(
height: 64.w,
margin: EdgeInsets.symmetric(horizontal: 3),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
left: 0,
top: 0,
right: 0,
child: Container(
height: 64.w,
decoration: BoxDecoration(
color: AppColors.primaryBackground,
boxShadow: [
Shadows.primaryShadow,
],
borderRadius: BorderRadius.all(
Radius.circular(32)),
),
child: Container(),
),
),
Positioned(
left: 10.w,
top: 10.w,
right: 10.w,
child: Image.asset(
"assets/images/channel-${item.code}.png",
fit: BoxFit.cover,
),
),
],
),
),
// 标题
Padding(
padding: const EdgeInsets.only(top: 12),
child: Text(
item.title,
textAlign: TextAlign.center,
overflow: TextOverflow.clip,
maxLines: 1,
style: TextStyle(
color: AppColors.thirdElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
height: 14.sp / 14,
),
),
),
],
),
onTap: () {},
),
);
}).toList(),
),
),
),
);
}
}
import 'package:flutter/material.dart';
const kLightTextColor = Color(0xffB5C8E7);
const kHardTextColor = Color(0xff586191);
const kPrimaryDarkColor = Color(0xff46BDFA);
const kPrimarylightColor = Color(0xff77E2FE);
const kBackgroundColor = Color(0xffEFF2F7);
const List<Color> kCategoriesPrimaryColor = [
Color(0xffFFCA8C),
Color(0xff5DF9D3),
Color(0xff85E4FD),
Color(0xffB8ACFF)
];
const List<Color> kCategoriesSecondryColor = [
Color(0xffFEA741),
Color(0xff31DFB5),
Color(0xff45BAFB),
Color(0xff9182F9)
];
import 'package:chart/entity/plan_entity.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:card_swiper/card_swiper.dart';
import '../index.dart';
import 'package:glassmorphism/glassmorphism.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'widgets.dart';
/// 放宽
class ListPageWidget extends GetView<MainController> {
const ListPageWidget({super.key});
@override
Widget build(BuildContext context) {
final list = controller.state.bannerPageDetail;
return Obx(() => controller.state.bannerPageDetail!.isEmpty
? Container()
: Container(
margin: const EdgeInsets.symmetric(vertical: 20.0),
height: 80.0,
child: ListView(
// This next line does the trick.
scrollDirection: Axis.horizontal,
children: List.generate(
controller.state.bannerPageDetail!.length,
(index) => Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GlassmorphicContainer(
width: 200,
height: 180.0,
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
],
),
child: Container(
height: 180.0,
width: 200.0,
constraints: BoxConstraints(minWidth: 41),
decoration: BoxDecoration(
// color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 14),
child: Row(
children: [
Container(
padding: EdgeInsets.all(14),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
kCategoriesPrimaryColor[index],
kCategoriesSecondryColor[index],
],
),
borderRadius: BorderRadius.circular(16)),
child: Icon(
Icons.headset_mic,
size: 20,
color: Colors.white,
),
),
SizedBox(width: 11),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${controller.state.bannerPageDetail![index].detailName}",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
"${controller.state.bannerPageDetail![index].detailDesc}",
style: TextStyle(
color: Colors.white, fontSize: 12),
),
],
),
],
),
),
)),
SizedBox(width: 20)
],
),
),
),
));
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/entities/entities.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
import 'ad.dart';
/// 新闻行 Item
class NewsListWidget extends GetView<MainController> {
NewsListWidget();
Widget _buildListItem(NewsItem item) {
return Container(
height: 161.w,
padding: EdgeInsets.all(20.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 图
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: SizedBox(
width: 121.w,
height: 121.w,
child: netImageCached(
item.thumbnail ?? "",
width: 121.w,
height: 121.w,
),
),
),
// 右侧
SizedBox(
width: 194.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 作者
Container(
margin: EdgeInsets.all(0),
child: Text(
item.author ?? "",
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
),
),
),
// 标题
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: Container(
margin: EdgeInsets.only(top: 10.w),
child: Text(
item.title ?? "",
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w500,
color: AppColors.primaryText,
fontSize: 16.sp,
overflow: TextOverflow.clip,
),
overflow: TextOverflow.clip,
maxLines: 3,
),
),
),
// Spacer
Spacer(),
// 一行 3 列
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 分类
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 60.w,
),
child: Text(
item.category ?? "",
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.secondaryElementText,
fontSize: 14.sp,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 添加时间
Container(
width: 15.w,
),
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 100.w,
),
child: Text(
'• ${duTimeLineFormat(item.addtime ?? DateTime(0))}',
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 更多
Spacer(),
InkWell(
child: Icon(
Icons.more_horiz,
color: AppColors.primaryText,
size: 24,
),
onTap: () {},
),
],
),
),
],
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Obx(() => controller.state.newsPageList == null
? Container()
: Column(
children: controller.state.newsPageList.items.map<Widget>((item) {
// 新闻行
List<Widget> widgets = <Widget>[
_buildListItem(item),
Divider(height: 1),
];
// 每 5 条 显示广告
int index = controller.state.newsPageList.items.indexOf(item);
if (((index + 1) % 5) == 0) {
widgets.addAll(<Widget>[
AdWidget(),
Divider(height: 1),
]);
}
// 返回
return Column(
children: widgets,
);
}).toList(),
));
}
}
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
/// 邮件订阅
class NewsletterWidget extends GetView<MainController> {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(20.w),
child: Column(
children: <Widget>[
// newsletter
Row(
children: <Widget>[
Text(
'Newsletter',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 18.sp,
fontWeight: FontWeight.w600,
color: AppColors.thirdElement,
),
),
Spacer(),
IconButton(
icon: Icon(
Icons.close,
color: AppColors.thirdElementText,
size: 17.sp,
),
onPressed: () {},
),
],
),
// email
inputEmailEdit(
marginTop: 19,
keyboardType: TextInputType.emailAddress,
hintText: "Email",
isPassword: false,
controller: null,
),
// btn subcrible
Padding(
padding: EdgeInsets.only(top: 15),
child: btnFlatButtonWidget(
onPressed: () {},
width: 335.w,
height: 44.h,
fontWeight: FontWeight.w600,
title: "Subscribe",
),
),
// disc
Container(
margin: EdgeInsets.only(top: 29.h),
width: 261.w,
child: Text.rich(TextSpan(children: <TextSpan>[
TextSpan(
text: 'By clicking on Subscribe button you agree to accept',
style: new TextStyle(
color: AppColors.thirdElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
),
),
TextSpan(
text: ' Privacy Policy',
style: new TextStyle(
color: AppColors.secondaryElementText,
fontFamily: "Avenir",
fontWeight: FontWeight.w400,
fontSize: 14.sp,
),
recognizer: TapGestureRecognizer()
..onTap = () {
toastInfo(msg: 'Privacy Policy');
},
),
])),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:chart/common/utils/utils.dart';
import 'package:chart/common/values/values.dart';
import 'package:chart/common/widgets/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../index.dart';
/// 推荐阅读
class NewsRecommendWidget extends GetView<MainController> {
NewsRecommendWidget();
@override
Widget build(BuildContext context) {
return Obx(() => controller.state.newsRecommend == null
? Container()
: Container(
margin: EdgeInsets.all(20.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// 图
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: netImageCached(
controller.state.newsRecommend.thumbnail,
width: 335.w,
height: 290.h,
),
),
// 作者
Container(
margin: EdgeInsets.only(top: 14.h),
child: Text(
controller.state.newsRecommend.author,
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
),
),
),
// 标题
InkWell(
onTap: () {
// ExtendedNavigator.rootNavigator.pushNamed(
// Routes.detailsPageRoute,
// arguments: DetailsPageArguments(item: item),
// );
},
child: Container(
margin: EdgeInsets.only(top: 10.h),
child: Text(
controller.state.newsRecommend.title,
style: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.w600,
color: AppColors.primaryText,
fontSize: 24.sp,
height: 1,
),
),
),
),
// 一行 3 列
Container(
margin: EdgeInsets.only(top: 10.h),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
// 分类
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 120,
),
child: Text(
controller.state.newsRecommend.category,
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.secondaryElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 添加时间
Container(
width: 15.w,
),
ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 120,
),
child: Text(
'• ${duTimeLineFormat(controller.state.newsRecommend.addtime)}',
style: TextStyle(
fontFamily: 'Avenir',
fontWeight: FontWeight.normal,
color: AppColors.thirdElementText,
fontSize: 14.sp,
height: 1,
),
overflow: TextOverflow.clip,
maxLines: 1,
),
),
// 更多
Spacer(),
InkWell(
child: Icon(
Icons.more_horiz,
color: AppColors.primaryText,
size: 24,
),
onTap: () {},
),
],
),
),
],
),
));
}
}
import 'package:flutter/material.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
// import 'package:line_icons/line_icons.dart';
// import './size_confige.dart';
class SearchField extends StatelessWidget {
SearchField({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 200,
child: Center(
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 20),
fillColor: Colors.white,
filled: true,
hintText: "Search Doctor",
hintStyle: TextStyle(
fontSize: 12,
color: Colors.blueGrey.withOpacity(0.9),
),
// prefixIcon:
// Icon(
// LineIcons.search,
// color: Colors.blueGrey.withOpacity(0.9),
// size: getRelativeWidth(0.065),
// ),
suffixIcon: Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: Container(
width: 100,
height: 60,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xffFBA473), Color(0xffFA7A30)]),
borderRadius: BorderRadius.circular(25),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Filter",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20),
),
Icon(
Icons.filter_list,
color: Colors.white,
size: 20,
)
],
),
),
),
),
border: outlineBorder,
enabledBorder: outlineBorder,
focusedBorder: outlineBorder),
),
),
);
}
final outlineBorder = OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(30),
);
}
import 'package:flutter/material.dart';
class SizeConfig {
static double screenWidth = double.infinity;
static double screenHeight = 550;
static initSize(BuildContext context) {
final mediaQuery = MediaQuery.of(context);
screenWidth = mediaQuery.size.width;
screenHeight = mediaQuery.size.height;
}
}
double getRelativeHeight(double percentage) {
return percentage * SizeConfig.screenHeight;
}
double getRelativeWidth(double percentage) {
return percentage * SizeConfig.screenWidth;
}
import 'package:chart/entity/plan_entity.dart';
import 'package:flutter/material.dart';
import 'package:chart/common/values/values.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:card_swiper/card_swiper.dart';
import '../index.dart';
import 'package:glassmorphism/glassmorphism.dart';
/// 分类导航
class SiperBannerWidget extends GetView<MainController> {
const SiperBannerWidget({super.key});
@override
Widget build(BuildContext context) {
List<Widget> _renderList(int index) {
return controller.state.bannerList!
.asMap()
.keys
.map((idx) => _generateWidget(
controller.state.bannerList![index][idx], idx, index))
.toList();
}
return Obx(() => controller.state.bannerList == null
? Container()
: Container(
height: 230.h,
child: Swiper(
scrollDirection: Axis.vertical,
autoplay: true,
itemCount: 3,
pagination: SwiperPagination(),
control: null,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.r),
color: Colors.black.withAlpha(0),
),
child: Column(children: _renderList(index)),
);
},
),
));
}
Widget _generateWidget(MessageEntity message, int idx, int index) {
return Container(
height: 70.0,
width: double.infinity,
margin: idx == 1 ? const EdgeInsets.symmetric(vertical: 10.0) : null,
constraints: const BoxConstraints(minWidth: 41),
decoration: BoxDecoration(
// color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: GlassmorphicContainer(
borderRadius: 16,
padding: EdgeInsets.only(bottom: 16),
blur: 14,
alignment: Alignment.bottomCenter,
border: 2,
linearGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(0.2),
Color(0xFF0FFFF).withOpacity(0.2),
],
),
borderGradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0FFFF).withOpacity(1),
Color(0xFFFFFFF),
Color(0xFF0FFFF).withOpacity(1),
],
),
height: 70,
width: double.infinity,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 14),
child: GestureDetector(
onTap: () => {
// Navigator.of(context).pushNamed("/chat",
// arguments: {"question": message.question})
// Navigator.push(context, MaterialPageRoute(builder: (context) {
// return ChatPage();
// }))
// Navigator.of(context).pop({'id': "1"})
// print("${message.question}")
},
child: Row(
children: [
Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
kCategoriesPrimaryColor[index],
kCategoriesSecondryColor[index],
],
),
borderRadius: BorderRadius.circular(16)),
child: const Icon(
Icons.headset_mic,
size: 20,
color: Colors.white,
),
),
const SizedBox(width: 11),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 15),
Text(
message.question,
// ignore: prefer_const_constructors
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white),
),
const SizedBox(height: 5),
Expanded(
child: SizedBox(
width: 200,
child: Text(
message.resp,
maxLines: 1,
// ignore: prefer_const_constructors
style: TextStyle(
fontSize: 14,
decoration: TextDecoration.none,
color: Colors.white,
),
overflow: TextOverflow.ellipsis,
// softWrap: true,
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// maxLines: 1,
// style: TextStyle(
// color: Colors.black.withOpacity(0.48), fontSize: 12),
)),
),
],
),
],
),
)),
));
}
}
const List<Color> kCategoriesPrimaryColor = [
Color(0xffFFCA8C),
Color(0xff5DF9D3),
Color(0xff85E4FD),
Color(0xffB8ACFF),
Color(0xffFFCA8C),
Color(0xff5DF9D3),
Color(0xff85E4FD),
Color(0xffB8ACFF),
];
const List<Color> kCategoriesSecondryColor = [
Color(0xffFEA741),
Color(0xff31DFB5),
Color(0xff45BAFB),
Color(0xff9182F9),
Color(0xffFFCA8C),
Color(0xff5DF9D3),
Color(0xff85E4FD),
Color(0xffB8ACFF)
];
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:card_swiper/card_swiper.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'dart:math';
const List<Color> kCategoriesPrimaryColor = [
Color(0xffFFCA8C),
Color(0xff5DF9D3),
Color(0xff85E4FD),
Color(0xffB8ACFF)
];
const List<Color> kCategoriesSecondryColor = [
Color(0xffFEA741),
Color(0xff31DFB5),
Color(0xff45BAFB),
Color(0xff9182F9)
];
class Doctor {
final String name, speciality, image;
final int reviews;
final int reviewScore;
Doctor(
{required this.name,
required this.speciality,
required this.image,
required this.reviews,
required this.reviewScore});
}
const kLightTextColor = Color(0xffB5C8E7);
const kHardTextColor = Color(0xff586191);
const kPrimaryDarkColor = Color(0xff46BDFA);
const kPrimarylightColor = Color(0xff77E2FE);
const kBackgroundColor = Color(0xffEFF2F7);
// import 'package:flutter_rating_bar/flutter_rating_bar.dart';
class SwiperColunmPage extends StatefulWidget {
@override
SwiperColunmPageState createState() => SwiperColunmPageState();
}
class SwiperColunmPageState extends State<SwiperColunmPage> {
final controller = PageController(viewportFraction: 0.8, keepPage: true);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
height: 200,
child: Swiper(
// scrollDirection: Axis.vertical,
autoplay: true,
itemBuilder: (BuildContext context, int index) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.black.withAlpha(0),
// Color.fromRGBO(69, 185, 251, 1.00),
// rgba(69, 185, 251, 1.00)
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Image.network(
"https://img14.360buyimg.com/babel/s700x360_jfs/t1/4099/12/2578/101668/5b971b4bE65ae279d/89dd1764797acfd9.jpg!q90!cc_350x180",
fit: BoxFit.cover,
),
));
},
viewportFraction: 0.8,
scale: 0.9,
// layout: SwiperLayout.CUSTOM,
// customLayoutOption: CustomLayoutOption(startIndex: -1, stateCount: 3)
// ..addRotate([-45.0 / 180, 0.0, 45.0 / 180])
// ..addTranslate(
// [Offset(-370.0, -40.0), Offset(0.0, 0.0), Offset(370.0, -40.0)]),
// itemWidth: 300.0,
// itemHeight: 200.0,
itemCount: 3,
pagination: SwiperPagination(),
control: null,
),
);
}
}
library widgets;
export './ad.dart';
export './categories.dart';
export './channels.dart';
export 'news_list.dart';
export './newsletter.dart';
export './recommend.dart';
export './swiper.dart';
export './banner.dart';
export './list.dart';
...@@ -8,17 +8,21 @@ import Foundation ...@@ -8,17 +8,21 @@ import Foundation
import connectivity_plus import connectivity_plus
import firebase_auth import firebase_auth
import firebase_core import firebase_core
import package_info
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import smart_auth import smart_auth
import sqflite
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SmartAuthPlugin.register(with: registry.registrar(forPlugin: "SmartAuthPlugin")) SmartAuthPlugin.register(with: registry.registrar(forPlugin: "SmartAuthPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }
...@@ -64,6 +64,27 @@ packages: ...@@ -64,6 +64,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
cached_network_image:
dependency: "direct main"
description:
name: cached_network_image
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.3"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
card_swiper: card_swiper:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -120,6 +141,13 @@ packages: ...@@ -120,6 +141,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.7.0" version: "4.7.0"
cookie_jar:
dependency: "direct main"
description:
name: cookie_jar
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crisp: crisp:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -183,6 +211,13 @@ packages: ...@@ -183,6 +211,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.6" version: "4.0.6"
dio_cookie_manager:
dependency: "direct main"
description:
name: dio_cookie_manager
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
easy_container: easy_container:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -293,6 +328,20 @@ packages: ...@@ -293,6 +328,20 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_blurhash:
dependency: transitive
description:
name: flutter_blurhash
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.0"
flutter_chat_types: flutter_chat_types:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -469,6 +518,13 @@ packages: ...@@ -469,6 +518,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "9.2.0" version: "9.2.0"
get:
dependency: "direct main"
description:
name: get
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.5"
glass_kit: glass_kit:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -644,6 +700,13 @@ packages: ...@@ -644,6 +700,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.0" version: "0.5.0"
octo_image:
dependency: transitive
description:
name: octo_image
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
open_filex: open_filex:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -651,6 +714,13 @@ packages: ...@@ -651,6 +714,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.3.2" version: "4.3.2"
package_info:
dependency: "direct main"
description:
name: package_info
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path: path:
dependency: transitive dependency: transitive
description: description:
...@@ -700,6 +770,13 @@ packages: ...@@ -700,6 +770,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "2.1.3"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
...@@ -791,6 +868,13 @@ packages: ...@@ -791,6 +868,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.27.7"
scroll_to_index: scroll_to_index:
dependency: transitive dependency: transitive
description: description:
...@@ -873,6 +957,20 @@ packages: ...@@ -873,6 +957,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.9.0"
sqflite:
dependency: transitive
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4+1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.2+2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
...@@ -894,6 +992,13 @@ packages: ...@@ -894,6 +992,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
......
...@@ -95,6 +95,12 @@ dependencies: ...@@ -95,6 +95,12 @@ dependencies:
extended_phone_number_input: ^1.0.2 extended_phone_number_input: ^1.0.2
gradient_widgets: ^0.6.0 gradient_widgets: ^0.6.0
json_dynamic_form: ^1.0.0 json_dynamic_form: ^1.0.0
get: ^4.6.5
dio_cookie_manager: ^2.0.0
cookie_jar: ^3.0.1
cached_network_image: ^3.0.0
# 包信息
package_info: ^2.0.0
# package:bubble/bubble.dart # package:bubble/bubble.dart
dev_dependencies: dev_dependencies:
...@@ -119,6 +125,20 @@ flutter: ...@@ -119,6 +125,20 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
fonts:
- family: Avenir
fonts:
- asset: assets/fonts/Avenir-Book.ttf
weight: 400 # normal
- family: Montserrat
fonts:
- asset: assets/fonts/Montserrat-Medium.ttf
weight: 500
- asset: assets/fonts/Montserrat-SemiBold.ttf
weight: 600
- family: Iconfont
fonts:
- asset: assets/fonts/iconfont.ttf
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets:
......
...@@ -13,7 +13,7 @@ import 'package:chart/main.dart'; ...@@ -13,7 +13,7 @@ import 'package:chart/main.dart';
void main() { void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async { testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget(ChartApp()); await tester.pumpWidget(ChatApp());
// Verify that our counter starts at 0. // Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget); expect(find.text('0'), findsOneWidget);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment