mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-09-24 07:05:02 +08:00
feat(加入欢迎页):
This commit is contained in:
@ -60,7 +60,7 @@ class PagerIndicator extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Expanded(child: new Container()),
|
new Expanded(child: new Container()),
|
||||||
new Transform(
|
new Transform(
|
||||||
transform: new Matrix4.translationValues(translation, 0.0, 0.0),
|
transform: new Matrix4.translationValues(0, 0.0, 0.0),
|
||||||
child: new Row(
|
child: new Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: bubbles,
|
children: bubbles,
|
||||||
|
@ -35,12 +35,16 @@ class Page extends StatelessWidget {
|
|||||||
this.viewModel,
|
this.viewModel,
|
||||||
this.percentVisible = 1.0,
|
this.percentVisible = 1.0,
|
||||||
});
|
});
|
||||||
|
_goHomePage(context) {
|
||||||
|
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||||
|
'/home', (Route<dynamic> route) => false);
|
||||||
|
}
|
||||||
|
|
||||||
Widget creatButton(BuildContext context,String txt,IconData iconName,String type){
|
Widget creatButton(BuildContext context,String txt,IconData iconName,String type){
|
||||||
return RaisedButton.icon(
|
return RaisedButton.icon(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if(type == 'start'){
|
if(type == 'start'){
|
||||||
//Navigator.popUntil(context, ModalRoute.withName('/'));
|
_goHomePage(context);
|
||||||
}else if(type == 'goGithub'){
|
}else if(type == 'goGithub'){
|
||||||
Application.router.navigateTo(context, '${Routes.webViewPage}?title=${Uri.encodeComponent(txt)} Doc&&url=${Uri.encodeComponent("https://github.com/alibaba/flutter-go")}');
|
Application.router.navigateTo(context, '${Routes.webViewPage}?title=${Uri.encodeComponent(txt)} Doc&&url=${Uri.encodeComponent("https://github.com/alibaba/flutter-go")}');
|
||||||
}
|
}
|
||||||
@ -60,13 +64,13 @@ class Page extends StatelessWidget {
|
|||||||
return new Container(
|
return new Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: viewModel.color,
|
color: viewModel.color,
|
||||||
|
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||||
child: new Opacity(
|
child: new Opacity(
|
||||||
opacity: percentVisible,
|
opacity: percentVisible,
|
||||||
child: new Column(
|
child: new Column(
|
||||||
crossAxisAlignment:CrossAxisAlignment.center,
|
crossAxisAlignment:CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
new Transform(
|
new Transform(
|
||||||
transform: new Matrix4.translationValues(0.0, 50.0 * (1.0 - percentVisible) ,0.0),
|
transform: new Matrix4.translationValues(0.0, 50.0 * (1.0 - percentVisible) ,0.0),
|
||||||
child: new Padding(
|
child: new Padding(
|
||||||
|
154
lib/main.dart
154
lib/main.dart
@ -1,17 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fluro/fluro.dart';
|
import 'package:fluro/fluro.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
import 'views/first_page.dart';
|
|
||||||
import 'views/widget_page.dart';
|
|
||||||
import 'views/fourth_page.dart';
|
|
||||||
import 'views/collection_page.dart';
|
|
||||||
import 'routers/routers.dart';
|
import 'routers/routers.dart';
|
||||||
import 'routers/application.dart';
|
import 'routers/application.dart';
|
||||||
import 'common/provider.dart';
|
import 'common/provider.dart';
|
||||||
import 'model/widget.dart';
|
|
||||||
import './widgets/index.dart';
|
|
||||||
import 'package:flutter_go/components/search_input.dart';
|
|
||||||
import 'views/welcome_page/index.dart';
|
import 'views/welcome_page/index.dart';
|
||||||
|
|
||||||
const int ThemeColor = 0xFFC91B3A;
|
const int ThemeColor = 0xFFC91B3A;
|
||||||
@ -40,7 +33,9 @@ class MyApp extends StatelessWidget {
|
|||||||
size: 35.0,
|
size: 35.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
home: new WelcomePage(),
|
home: new Scaffold(
|
||||||
|
body: new WelcomePage(),
|
||||||
|
),
|
||||||
onGenerateRoute: Application.router.generator,
|
onGenerateRoute: Application.router.generator,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -54,144 +49,3 @@ void main() async {
|
|||||||
db = Provider.db;
|
db = Provider.db;
|
||||||
runApp(new MyApp());
|
runApp(new MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() {
|
|
||||||
return _MyHomePageState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyHomePageState extends State<MyHomePage>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
WidgetControlModel widgetControl = new WidgetControlModel();
|
|
||||||
TabController controller;
|
|
||||||
bool isSearch = false;
|
|
||||||
String data = '无';
|
|
||||||
String data2ThirdPage = '这是传给ThirdPage的值';
|
|
||||||
String appBarTitle = tabData[0]['text'];
|
|
||||||
static List tabData = [
|
|
||||||
{'text': '业界动态', 'icon': new Icon(Icons.language)},
|
|
||||||
{'text': 'WIDGET', 'icon': new Icon(Icons.extension)},
|
|
||||||
{'text': '组件收藏', 'icon': new Icon(Icons.star)},
|
|
||||||
{'text': '关于手册', 'icon': new Icon(Icons.favorite)}
|
|
||||||
];
|
|
||||||
|
|
||||||
List<Widget> myTabs = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
controller = new TabController(
|
|
||||||
initialIndex: 0, vsync: this, length: 4); // 这里的length 决定有多少个底导 submenus
|
|
||||||
for (int i = 0; i < tabData.length; i++) {
|
|
||||||
myTabs.add(new Tab(text: tabData[i]['text'], icon: tabData[i]['icon']));
|
|
||||||
}
|
|
||||||
controller.addListener(() {
|
|
||||||
if (controller.indexIsChanging) {
|
|
||||||
_onTabChange();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Application.controller = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void onWidgetTap(WidgetPoint widgetPoint, BuildContext context) {
|
|
||||||
List widgetDemosList = new WidgetDemoList().getDemos();
|
|
||||||
String targetName = widgetPoint.name;
|
|
||||||
String targetRouter = '/category/error/404';
|
|
||||||
widgetDemosList.forEach((item) {
|
|
||||||
if (item.name == targetName) {
|
|
||||||
targetRouter = item.routerName;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Application.router.navigateTo(context, "$targetRouter");
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildSearchInput(BuildContext context) {
|
|
||||||
return new SearchInput((value) async {
|
|
||||||
if (value != '') {
|
|
||||||
List<WidgetPoint> list = await widgetControl.search(value);
|
|
||||||
|
|
||||||
return list
|
|
||||||
.map((item) => new MaterialSearchResult<String>(
|
|
||||||
value: item.name,
|
|
||||||
text: item.name,
|
|
||||||
onTap: () {
|
|
||||||
onWidgetTap(item, context);
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.toList();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, (value) {}, () {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return new Scaffold(
|
|
||||||
appBar: new AppBar(title: buildSearchInput(context)),
|
|
||||||
body: new TabBarView(controller: controller, children: <Widget>[
|
|
||||||
new FirstPage(),
|
|
||||||
new WidgetPage(db),
|
|
||||||
new CollectionPage(),
|
|
||||||
new FourthPage()
|
|
||||||
]),
|
|
||||||
bottomNavigationBar: Material(
|
|
||||||
color: const Color(0xFFF0EEEF), //底部导航栏主题颜色
|
|
||||||
child: SafeArea(
|
|
||||||
child: Container(
|
|
||||||
height: 65.0,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xFFF0F0F0),
|
|
||||||
boxShadow: <BoxShadow>[
|
|
||||||
BoxShadow(
|
|
||||||
color: const Color(0xFFd0d0d0),
|
|
||||||
blurRadius: 3.0,
|
|
||||||
spreadRadius: 2.0,
|
|
||||||
offset: Offset(-1.0, -1.0),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: TabBar(
|
|
||||||
controller: controller,
|
|
||||||
indicatorColor: Theme.of(context).primaryColor, //tab标签的下划线颜色
|
|
||||||
// labelColor: const Color(0xFF000000),
|
|
||||||
indicatorWeight: 3.0,
|
|
||||||
labelColor: Theme.of(context).primaryColor,
|
|
||||||
unselectedLabelColor: const Color(0xFF8E8E8E),
|
|
||||||
tabs: <Tab>[
|
|
||||||
Tab(text: '业界动态', icon: Icon(Icons.language)),
|
|
||||||
Tab(text: '组件', icon: Icon(Icons.extension)),
|
|
||||||
Tab(text: '组件收藏', icon: Icon(Icons.favorite)),
|
|
||||||
Tab(text: '关于手册', icon: Icon(Icons.line_weight)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onTabChange() {
|
|
||||||
if (this.mounted) {
|
|
||||||
this.setState(() {
|
|
||||||
appBarTitle = tabData[controller.index]['text'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// void _onDataChange(val) {
|
|
||||||
// if (this.mounted) {
|
|
||||||
// setState(() {
|
|
||||||
// data = val;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
@ -4,6 +4,14 @@ import '../views/category.dart';
|
|||||||
import '../widgets/404.dart';
|
import '../widgets/404.dart';
|
||||||
import '../common/full_screen_code_dialog.dart';
|
import '../common/full_screen_code_dialog.dart';
|
||||||
import '../views/web_view_page.dart';
|
import '../views/web_view_page.dart';
|
||||||
|
import '../views/home.dart';
|
||||||
|
|
||||||
|
// app的首页
|
||||||
|
var homeHandler = new Handler(
|
||||||
|
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||||
|
return new AppPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
var categoryHandler = new Handler(
|
var categoryHandler = new Handler(
|
||||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||||
|
@ -6,6 +6,7 @@ import './router_handler.dart';
|
|||||||
|
|
||||||
class Routes {
|
class Routes {
|
||||||
static String root = "/";
|
static String root = "/";
|
||||||
|
static String home = "/home";
|
||||||
static String widgetDemo = '/widget-demo';
|
static String widgetDemo = '/widget-demo';
|
||||||
static String codeView = '/code-view';
|
static String codeView = '/code-view';
|
||||||
static String webViewPage = '/web-view-page';
|
static String webViewPage = '/web-view-page';
|
||||||
@ -15,7 +16,7 @@ class Routes {
|
|||||||
router.notFoundHandler = new Handler(
|
router.notFoundHandler = new Handler(
|
||||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||||
});
|
});
|
||||||
|
router.define(home, handler: homeHandler);
|
||||||
|
|
||||||
router.define('/category/:type', handler: categoryHandler);
|
router.define('/category/:type', handler: categoryHandler);
|
||||||
router.define('/category/error/404', handler: widgetNotFoundHandler);
|
router.define('/category/error/404', handler: widgetNotFoundHandler);
|
||||||
|
164
lib/views/home.dart
Normal file
164
lib/views/home.dart
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/**
|
||||||
|
* Created with Android Studio.
|
||||||
|
* User: 三帆
|
||||||
|
* Date: 16/01/2019
|
||||||
|
* Time: 11:16
|
||||||
|
* email: sanfan.hx@alibaba-inc.com
|
||||||
|
* tartget: app首页
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
|
import 'first_page.dart';
|
||||||
|
import 'widget_page.dart';
|
||||||
|
//import 'package:flutter_go/views/welcome_page/fourth_page.dart';
|
||||||
|
import 'collection_page.dart';
|
||||||
|
import '../routers/application.dart';
|
||||||
|
import '../common/provider.dart';
|
||||||
|
import '../model/widget.dart';
|
||||||
|
import '../widgets/index.dart';
|
||||||
|
import 'package:flutter_go/components/search_input.dart';
|
||||||
|
|
||||||
|
const int ThemeColor = 0xFFC91B3A;
|
||||||
|
|
||||||
|
class AppPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return _MyHomePageState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyHomePageState extends State<AppPage>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
WidgetControlModel widgetControl = new WidgetControlModel();
|
||||||
|
TabController controller;
|
||||||
|
bool isSearch = false;
|
||||||
|
String data = '无';
|
||||||
|
String data2ThirdPage = '这是传给ThirdPage的值';
|
||||||
|
String appBarTitle = tabData[0]['text'];
|
||||||
|
static List tabData = [
|
||||||
|
{'text': '业界动态', 'icon': new Icon(Icons.language)},
|
||||||
|
{'text': 'WIDGET', 'icon': new Icon(Icons.extension)},
|
||||||
|
{'text': '组件收藏', 'icon': new Icon(Icons.star)},
|
||||||
|
{'text': '关于手册', 'icon': new Icon(Icons.favorite)}
|
||||||
|
];
|
||||||
|
|
||||||
|
List<Widget> myTabs = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
controller = new TabController(
|
||||||
|
initialIndex: 0, vsync: this, length: 4); // 这里的length 决定有多少个底导 submenus
|
||||||
|
for (int i = 0; i < tabData.length; i++) {
|
||||||
|
myTabs.add(new Tab(text: tabData[i]['text'], icon: tabData[i]['icon']));
|
||||||
|
}
|
||||||
|
controller.addListener(() {
|
||||||
|
if (controller.indexIsChanging) {
|
||||||
|
_onTabChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Application.controller = controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onWidgetTap(WidgetPoint widgetPoint, BuildContext context) {
|
||||||
|
List widgetDemosList = new WidgetDemoList().getDemos();
|
||||||
|
String targetName = widgetPoint.name;
|
||||||
|
String targetRouter = '/category/error/404';
|
||||||
|
widgetDemosList.forEach((item) {
|
||||||
|
if (item.name == targetName) {
|
||||||
|
targetRouter = item.routerName;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Application.router.navigateTo(context, "$targetRouter");
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildSearchInput(BuildContext context) {
|
||||||
|
return new SearchInput((value) async {
|
||||||
|
if (value != '') {
|
||||||
|
List<WidgetPoint> list = await widgetControl.search(value);
|
||||||
|
|
||||||
|
return list
|
||||||
|
.map((item) => new MaterialSearchResult<String>(
|
||||||
|
value: item.name,
|
||||||
|
text: item.name,
|
||||||
|
onTap: () {
|
||||||
|
onWidgetTap(item, context);
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.toList();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, (value) {}, () {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var db = Provider.db;
|
||||||
|
|
||||||
|
return new Scaffold(
|
||||||
|
appBar: new AppBar(title: buildSearchInput(context)),
|
||||||
|
body: new TabBarView(controller: controller, children: <Widget>[
|
||||||
|
new FirstPage(),
|
||||||
|
new WidgetPage(db),
|
||||||
|
new CollectionPage(),
|
||||||
|
Container(
|
||||||
|
child: Center(
|
||||||
|
child: Text("开发中"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
bottomNavigationBar: Material(
|
||||||
|
color: const Color(0xFFF0EEEF), //底部导航栏主题颜色
|
||||||
|
child: SafeArea(
|
||||||
|
child: Container(
|
||||||
|
height: 65.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFF0F0F0),
|
||||||
|
boxShadow: <BoxShadow>[
|
||||||
|
BoxShadow(
|
||||||
|
color: const Color(0xFFd0d0d0),
|
||||||
|
blurRadius: 3.0,
|
||||||
|
spreadRadius: 2.0,
|
||||||
|
offset: Offset(-1.0, -1.0),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: TabBar(
|
||||||
|
controller: controller,
|
||||||
|
indicatorColor: Theme.of(context).primaryColor, //tab标签的下划线颜色
|
||||||
|
// labelColor: const Color(0xFF000000),
|
||||||
|
indicatorWeight: 3.0,
|
||||||
|
labelColor: Theme.of(context).primaryColor,
|
||||||
|
unselectedLabelColor: const Color(0xFF8E8E8E),
|
||||||
|
tabs: <Tab>[
|
||||||
|
Tab(text: '业界动态', icon: Icon(Icons.language)),
|
||||||
|
Tab(text: '组件', icon: Icon(Icons.extension)),
|
||||||
|
Tab(text: '组件收藏', icon: Icon(Icons.favorite)),
|
||||||
|
Tab(text: '关于手册', icon: Icon(Icons.line_weight)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTabChange() {
|
||||||
|
if (this.mounted) {
|
||||||
|
this.setState(() {
|
||||||
|
appBarTitle = tabData[controller.index]['text'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,8 +7,6 @@ import 'package:flutter_go/components/fourth_page_feature/page_reveal.dart';
|
|||||||
import 'package:flutter_go/components/fourth_page_feature/pager_indicator.dart';
|
import 'package:flutter_go/components/fourth_page_feature/pager_indicator.dart';
|
||||||
import 'package:flutter_go/components/fourth_page_feature/pages.dart';
|
import 'package:flutter_go/components/fourth_page_feature/pages.dart';
|
||||||
|
|
||||||
import '../components/comp_list.dart';
|
|
||||||
|
|
||||||
class FourthPage extends StatefulWidget {
|
class FourthPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
FourthPageState createState() => new FourthPageState();
|
FourthPageState createState() => new FourthPageState();
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'dart:math' as math;
|
import 'package:flutter_go/views/welcome_page/fourth_page.dart';
|
||||||
class WelcomePage extends StatefulWidget {
|
class WelcomePage extends StatefulWidget {
|
||||||
WelcomePage({Key key}) : super(key: key);
|
WelcomePage({Key key}) : super(key: key);
|
||||||
|
|
||||||
@ -19,208 +19,13 @@ class WelcomePage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class OnSkipClickListener {
|
class _WelcomePageState extends State<WelcomePage> {
|
||||||
void onSkipClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _WelcomePageState extends State<WelcomePage> implements OnSkipClickListener {
|
|
||||||
@override
|
|
||||||
void onSkipClick() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new Stack(
|
return new Container(
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
children: <Widget>[
|
|
||||||
new Container(
|
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: new Image.network(
|
child: FourthPage()
|
||||||
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547488149046&di=d30f671ee92d67c1b93dce3eb4b11d5e&imgtype=0&src=http%3A%2F%2Fp0.ssl.qhimg.com%2Ft01c3f5bf72e7d1ac67.png',
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
),
|
|
||||||
constraints: new BoxConstraints.expand(),
|
|
||||||
),
|
|
||||||
// new Container(
|
|
||||||
// child: Align(
|
|
||||||
// alignment: Alignment.topRight,
|
|
||||||
// child: new Container(
|
|
||||||
// padding: const EdgeInsets.only(top: 30.0, right: 20.0),
|
|
||||||
// child: new SkipDownTimeProgress(
|
|
||||||
// Colors.red,
|
|
||||||
// 22.0,
|
|
||||||
// new Duration(seconds: 5),
|
|
||||||
// new Size(25.0, 25.0),
|
|
||||||
// skipText: "跳过",
|
|
||||||
// clickListener: this,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _DrawProgress extends CustomPainter {
|
|
||||||
final Color color;
|
|
||||||
final double radius;
|
|
||||||
double angle;
|
|
||||||
AnimationController animation;
|
|
||||||
|
|
||||||
Paint circleFillPaint;
|
|
||||||
Paint progressPaint;
|
|
||||||
Rect rect;
|
|
||||||
|
|
||||||
_DrawProgress(this.color, this.radius,
|
|
||||||
{double this.angle, AnimationController this.animation}) {
|
|
||||||
circleFillPaint = new Paint();
|
|
||||||
circleFillPaint.color = Colors.white;
|
|
||||||
circleFillPaint.style = PaintingStyle.fill;
|
|
||||||
|
|
||||||
progressPaint = new Paint();
|
|
||||||
progressPaint.color = color;
|
|
||||||
progressPaint.style = PaintingStyle.stroke;
|
|
||||||
progressPaint.strokeCap = StrokeCap.round;
|
|
||||||
progressPaint.strokeWidth = 4.0;
|
|
||||||
|
|
||||||
if (animation != null && !animation.isAnimating) {
|
|
||||||
animation.forward();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void paint(Canvas canvas, Size size) {
|
|
||||||
double x = size.width / 2;
|
|
||||||
double y = size.height / 2;
|
|
||||||
Offset center = new Offset(x, y);
|
|
||||||
canvas.drawCircle(center, radius - 2, circleFillPaint);
|
|
||||||
rect = Rect.fromCircle(center: center, radius: radius);
|
|
||||||
angle = angle * (-1);
|
|
||||||
double startAngle = -math.pi / 2;
|
|
||||||
double sweepAngle = math.pi * angle / 180;
|
|
||||||
print("draw paint-------------------= $startAngle, $sweepAngle");
|
|
||||||
//canvas.drawArc(rect, startAngle, sweepAngle, false, progressPaint);
|
|
||||||
Path path = new Path();
|
|
||||||
path.arcTo(rect, startAngle, sweepAngle, true);
|
|
||||||
canvas.drawPath(path, progressPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool shouldRepaint(CustomPainter oldDelegate) {
|
|
||||||
return oldDelegate != this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SkipDownTimeProgress extends StatefulWidget {
|
|
||||||
final Color color;
|
|
||||||
final double radius;
|
|
||||||
final Duration duration;
|
|
||||||
final Size size;
|
|
||||||
String skipText;
|
|
||||||
OnSkipClickListener clickListener;
|
|
||||||
|
|
||||||
SkipDownTimeProgress(
|
|
||||||
this.color,
|
|
||||||
this.radius,
|
|
||||||
this.duration,
|
|
||||||
this.size, {
|
|
||||||
Key key,
|
|
||||||
String this.skipText = "跳过",
|
|
||||||
OnSkipClickListener this.clickListener,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_SkipDownTimeProgressState createState() {
|
|
||||||
return new _SkipDownTimeProgressState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SkipDownTimeProgressState extends State<SkipDownTimeProgress>
|
|
||||||
with TickerProviderStateMixin {
|
|
||||||
AnimationController animationController;
|
|
||||||
double curAngle = 360.0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
print('initState----------------------');
|
|
||||||
animationController =
|
|
||||||
new AnimationController(vsync: this, duration: widget.duration);
|
|
||||||
animationController.addListener(_change);
|
|
||||||
_doAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(SkipDownTimeProgress oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
print('didUpdateWidget----------------------');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
print('dispose----------------------');
|
|
||||||
animationController.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onSkipClick() {
|
|
||||||
if (widget.clickListener != null) {
|
|
||||||
print('skip onclick ---------------');
|
|
||||||
widget.clickListener.onSkipClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _doAnimation() async {
|
|
||||||
Future.delayed(new Duration(milliseconds: 50), () {
|
|
||||||
if(mounted) {
|
|
||||||
animationController.forward().orCancel;
|
|
||||||
}else {
|
|
||||||
_doAnimation();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _change() {
|
|
||||||
print('ange == $animationController.value');
|
|
||||||
double ange =
|
|
||||||
double.parse(((animationController.value * 360) ~/ 1).toString());
|
|
||||||
setState(() {
|
|
||||||
curAngle = (360.0 - ange);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return new GestureDetector(
|
|
||||||
onTap: _onSkipClick,
|
|
||||||
child: new Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
new CustomPaint(
|
|
||||||
painter:
|
|
||||||
new _DrawProgress(widget.color, widget.radius, angle: curAngle),
|
|
||||||
size: widget.size,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
widget.skipText,
|
|
||||||
style: TextStyle(
|
|
||||||
color: widget.color,
|
|
||||||
fontSize: 13.5,
|
|
||||||
decoration: TextDecoration.none),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Demo extends StatefulWidget {
|
class RichTextDemo extends StatefulWidget {
|
||||||
_Demo createState() => _Demo();
|
_Demo createState() => _Demo();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Demo extends State<Demo> {
|
class _Demo extends State<RichTextDemo> {
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
@ -70,7 +70,7 @@ class _Demo extends State<Demo> {
|
|||||||
contentList: [new Column(
|
contentList: [new Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
MarkdownBody(data: markDesc['intro']),
|
MarkdownBody(data: markDesc['intro']),
|
||||||
Demo(),
|
RichTextDemo(),
|
||||||
MarkdownBody(data: markDesc['diff']),
|
MarkdownBody(data: markDesc['diff']),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user