From c120fd3f94f70c97b4f42782d92aceb251780897 Mon Sep 17 00:00:00 2001 From: "sanfan.hx" Date: Sun, 13 Jan 2019 14:15:18 +0800 Subject: [PATCH 1/4] =?UTF-8?q?refactor(=E6=95=B4=E7=90=86=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E5=88=9D=E5=A7=8B=E9=80=BB=E8=BE=91,=20?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=95=B0=E6=8D=AE=E5=BA=93=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E6=80=A7):=20=E5=88=A4=E6=96=AD=E6=98=AF=E5=90=A6=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E5=B7=B2=E7=9F=A5=E7=9A=84cat,=20widget,=20collection?= =?UTF-8?q?=E4=B8=89=E5=BC=A0=E8=A1=A8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/common/provider.dart | 63 ++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/lib/common/provider.dart b/lib/common/provider.dart index 8540d671..32703214 100644 --- a/lib/common/provider.dart +++ b/lib/common/provider.dart @@ -4,37 +4,81 @@ import 'dart:typed_data'; import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; import 'package:flutter/services.dart' show rootBundle; +//const createSql = { +// 'cat': """ +// CREATE TABLE "cat" ( +// `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, +// `name` TEXT NOT NULL UNIQUE, +// `depth` INTEGER NOT NULL DEFAULT 1, +// `parentId` INTEGER NOT NULL, +// `desc` TEXT +// ); +// """, +// 'collectio': """ +// CREATE TABLE collection (id INTEGER PRIMARY KEY NOT NULL UNIQUE, name TEXT NOT NULL, router TEXT); +// """, +// 'widget': """ +// CREATE TABLE widget (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, name TEXT NOT NULL, cnName TEXT NOT NULL, image TEXT NOT NULL, doc TEXT, demo TEXT, catId INTEGER NOT NULL REFERENCES cat (id), owner TEXT); +// """; +//}; class Provider { static Database db; + // 获取数据库中所有的表 + Future getTables() async { + if (db == null) { + return Future.value([]); + } + List tables = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"'); + List targetList = []; + tables.forEach((item) { + targetList.add(item['name']); + }); + return targetList; + } + + // 检查数据库中, 表是否完整, 在部份android中, 会出现表丢失的情况 + Future checkTableIsRight() async { + List expectTables = ['cat', 'widget', 'collection']; + + List tables = await getTables(); + + for(int i = 0; i < expectTables.length; i++) { + if (!tables.contains(expectTables[i])) { + print("table lost in app"); + return false; + } + } + return true; + + } + //初始化数据库 - // isCreate 用永远 copy 一个新的数据库 + Future init(bool isCreate) async { //Get a location using getDatabasesPath String databasesPath = await getDatabasesPath(); String path = join(databasesPath, 'flutter.db'); - List tables; + try { db = await openDatabase(path); - tables = await db - .rawQuery('SELECT name FROM sqlite_master WHERE type = "table"'); - print('${tables.length} 7891'); } catch (e) { print("Error $e"); } + bool tableIsRight = await this.checkTableIsRight(); - if (tables.length < 3) { - // Delete the database - await deleteDatabase(path); + if (!tableIsRight) { // 关闭上面打开的db,否则无法执行open db.close(); + // Delete the database + await deleteDatabase(path); ByteData data = await rootBundle.load(join("assets", "app.db")); List bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await new File(path).writeAsBytes(bytes); - db = await openDatabase(path, version: 2, + db = await openDatabase(path, version: 1, onCreate: (Database db, int version) async { print('db created version is $version'); }, onOpen: (Database db) async { @@ -44,4 +88,5 @@ class Provider { print("Opening existing database"); } } + } From 7cf8d11fda6a3f466b6b3caafdfc0619d4127048 Mon Sep 17 00:00:00 2001 From: ryan730 Date: Sun, 13 Jan 2019 17:41:23 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feat(=E5=A2=9E=E5=8A=A0=E5=85=8D=E8=B4=A3?= =?UTF-8?q?=E5=A3=B0=E6=98=8E):=20=E5=A3=B0=E6=98=8E=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=BC=B9=E5=87=BA=EF=BC=8C=E5=B7=A6?= =?UTF-8?q?=E4=B8=8A=E8=A7=92=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/components/disclaimer_msg.dart | 247 ++++++++++++++++++ lib/main.dart | 28 +- lib/model/collection_general.dart | 69 +++++ lib/views/first_page.dart | 63 ++++- .../Form/CheckBox/CheckboxListTile/index.dart | 3 +- 5 files changed, 387 insertions(+), 23 deletions(-) create mode 100644 lib/components/disclaimer_msg.dart create mode 100644 lib/model/collection_general.dart diff --git a/lib/components/disclaimer_msg.dart b/lib/components/disclaimer_msg.dart new file mode 100644 index 00000000..b65a6f2d --- /dev/null +++ b/lib/components/disclaimer_msg.dart @@ -0,0 +1,247 @@ +/** + * Created with Android Studio. + * User: 一晟 + * Date: 2019/1/12 + * Time: 下午9:19 + * email: zhu.yan@alibaba-inc.com + */ +import 'package:flutter/material.dart'; +//import 'package:flutter_rookie_book/model/collection_general.dart'; +//import 'package:flutter_rookie_book/model/collection_general.dart'; + + +const disclaimerText1 = '\r\r\r\r\r\r本APP属于个人的非赢利性开源项目,以供开源社区使用,凡本APP转载的所有的文章 、图片、音频、视频文件等资料的版权归版权所有人所有,本APP采用的非本站原创文章及图片等内容无法一一和版权者联系,如果本网所选内容的文章作者及编辑认为其作品不宜上网供大家浏览,或不应无偿使用请及时用电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。'; +const disclaimerText2 = '\n\r\r\r\r\r\r对于已经授权本APP独家使用并提供给本站资料的版权所有人的文章、图片等资料,如需转载使用,需取得本站和版权所有人的同意。本APP所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。'; + + +class DisclaimerMsg extends StatefulWidget { + final State pWidget; + DisclaimerMsg({ Key key, this.pWidget }) : super(key: key); + DisclaimerMsgState createState() => DisclaimerMsgState(); +} + +class DisclaimerMsgState extends State { + var _valBool = false; + var _page; + //CollectionControlModel _collectionControl = new CollectionControlModel(); + //List _collectionList = []; + // void init(BuildContext context) { + // Toast.show(context: context, message: "👉 APP免责声明",cb:showAlertDialog); + // } + + @override + void initState() { + super.initState(); +// _collectionList.clear(); +// _collectionControl.getAllCollection().then((resultList) { +// resultList.forEach((item) { +// _collectionList.add(item); +// print('=============db=========${item}'); +// }); +// }); + _page = widget.pWidget; + } + + + + void refs(bool value){ + if(this.mounted){ + setState(() { + _valBool=value; + _page.save(value); + }); + +// _collectionControl +// .insert(CollectionGeneral(key: 'disclaimer', values: value.toString())) +// .then((result) { +// print('result2====${result}'); +// } +// ); + } + } + + void showAlertDialog(BuildContext context) { +// new Future.delayed(Duration(seconds: 5)).then((value) { +// Navigator.of(context).pop(); +// }); + showDialog( + context: context, + barrierDismissible: false, // user must tap button! + builder: (BuildContext context) { + return AlertDialog( + title: Text('免责声明'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text(disclaimerText1), + Text(disclaimerText2), + ], + ), + ), + shape:RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20.0)), // 圆角 + actions: [ + Container( + width: 270, + alignment: Alignment.centerLeft, + padding: new EdgeInsets.fromLTRB(0.0, 0.0, 30.0, 0.0), + child: + Row( + mainAxisAlignment:MainAxisAlignment.spaceAround, + //crossAxisAlignment:CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment:MainAxisAlignment.center, + children: [ + Checkbox( + activeColor: Theme.of(context).primaryColor, + tristate:false, + value: _valBool, + onChanged: (bool bol) { + refs(bol); + Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs + showAlertDialog(context); //here i call the same function + } + ), + Text('不再显示',style:TextStyle(fontSize: 14)), + ], + ), + new Flexible( + flex: 1, + child: Container(width: 100,) + ), + FlatButton( + child: Text('知道了',style:TextStyle(fontSize: 16,color: Colors.white)), + color: Theme.of(context).primaryColor, + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ] +// SizedBox( +// width:150, +// height:55, +// child: CheckboxListTile( +// title: Text('不再显示',style:TextStyle(fontSize: 14)), +// controlAffinity: ListTileControlAffinity.leading, +// activeColor: Colors.red, +// value: _valBool, +// onChanged: (bool value) { +// refs(value); +// Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs +// showAlertDialog(context); //here i call the same function +// } +// ) +// //secondary: const Icon(Icons.hourglass_empty), +// ), +// Checkbox( +// activeColor: Colors.red, +// tristate:false, +// value: _valBool, +// onChanged: (bool bol) { +// refs(bol); +// Navigator.of(context).pop(); // here I pop to avoid multiple Dialogs +// showAlertDialog(context); //here i call the same function +// } +// ), +// Text('不再显示',style:TextStyle(fontSize: 14)), +// FlatButton( +// child: Text('知道了',style:TextStyle(fontSize: 16,color: Colors.green)), +// onPressed: () { +// Navigator.of(context).pop(); +// }, +// ), +// ], + ) + )], + ); + }, + ); + } + Widget build(BuildContext context) { + return new GestureDetector( + onTap: () { + showAlertDialog(context); + }, + child: Stack( + //alignment: const Alignment(1.6, 1.6), + children: [ + new Container( + width:90.0, + alignment: Alignment.center, + decoration: new BoxDecoration( + borderRadius:new BorderRadius.horizontal(right: Radius.circular(10)), + color: Colors.black45, + ), + child: new Text( + '🔔 免责声明', + style: new TextStyle( + fontSize: 14.0, + //fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + ], + ) + ); + } + + Widget build2(BuildContext context) { + return Container( + padding: new EdgeInsets.all(0.0), + alignment:Alignment.centerRight, + child:FlatButton( + //padding: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0), + child: new Text( + '👉 APP免责声明', + style: new TextStyle( + fontSize: 12.0, //textsize + color: Colors.black54, // textcolor + ), + ), + //color: Theme.of(context).accentColor, + color: Theme.of(context).accentColor, + //elevation: 0.0,//shadow + //splashColor: Colors.blueGrey, + onPressed: () { + showAlertDialog(context); + //Toast.show(context: context, message: "👉 APP免责声明",cb:showAlertDialog); + }) + ); + } +} + +class Toast { + static void show({@required BuildContext context, @required String message,Function cb}) { + //创建一个OverlayEntry对象 + OverlayEntry overlayEntry = new OverlayEntry(builder: (context) { + return new Positioned( + top: MediaQuery.of(context).size.height * 0.12, + right:5.0, + child:RaisedButton( + padding: new EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), + child: new Text( + '👉 APP免责声明', + style: new TextStyle( + fontSize: 14.0, //textsize + color: Colors.black54, // textcolor + ), + ), + //color: Theme.of(context).accentColor, + color: Colors.red, + //elevation: 0.0,//shadow + //splashColor: Colors.blueGrey, + onPressed: () { + if(cb is Function){ + cb(context); + } + }) + ); + }); + //往Overlay中插入插入OverlayEntry + Overlay.of(context).insert(overlayEntry); + new Future.delayed(Duration(seconds: 2)).then((value) { + //overlayEntry.remove(); + }); + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index a85aaa6c..de235248 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -121,12 +121,12 @@ class _MyHomePageState extends State return list .map((item) => new MaterialSearchResult( - value: item.name, - text: item.name, - onTap: () { - onWidgetTap(item, context); - }, - )) + value: item.name, + text: item.name, + onTap: () { + onWidgetTap(item, context); + }, + )) .toList(); } else { return null; @@ -163,7 +163,7 @@ class _MyHomePageState extends State child: new TabBar( controller: controller, indicatorColor: - Theme.of(context).primaryColor, //tab标签的下划线颜色 + Theme.of(context).primaryColor, //tab标签的下划线颜色 // labelColor: const Color(0xFF000000), indicatorWeight: 3.0, labelColor: Theme.of(context).primaryColor, @@ -184,11 +184,11 @@ class _MyHomePageState extends State } } - // void _onDataChange(val) { - // if (this.mounted) { - // setState(() { - // data = val; - // }); - // } - // } +// void _onDataChange(val) { +// if (this.mounted) { +// setState(() { +// data = val; +// }); +// } +// } } diff --git a/lib/model/collection_general.dart b/lib/model/collection_general.dart new file mode 100644 index 00000000..9e23674d --- /dev/null +++ b/lib/model/collection_general.dart @@ -0,0 +1,69 @@ +/** + * Created with Android Studio. + * User: 一晟 + * Date: 2019/1/12 + * Time: 下午9:19 + * email: zhu.yan@alibaba-inc.com + */ +import 'dart:async'; +import '../common/sql.dart'; + +abstract class CollectionInterface { + String get key; + String get values; +} + +class CollectionGeneral implements CollectionInterface { + String key; + String values; + + CollectionGeneral({this.key, this.values}); + + factory CollectionGeneral.fromJSON(Map json){ + return CollectionGeneral(key: json['name'],values: json['values']); + } + + Object toMap() { + return {'key': key, 'values': values}; + } +} + +class CollectionControlModel { + final String table = 'collectionGeneral'; + Sql sql; + + CollectionControlModel() { + sql = Sql.setTable(table); + } + + // 获取所有的收藏 + + // 插入新收藏 + Future insert(CollectionGeneral collection) { + var result = + sql.insert({'key': collection.key, 'values': collection.values}); + return result; + } + + // 获取全部的收藏 + Future> getAllCollection() async { + List list = await sql.getByCondition(); + List resultList = []; + list.forEach((item){ + print(item); + resultList.add(CollectionGeneral.fromJSON(item)); + }); + return resultList; + } + + // 通过收藏名获取router + Future getRouterByName(String key) async { + List list = await sql.getByCondition(conditions: {'key': key}); + return list; + } + + // 删除 + Future deleteByName(String key) async{ + return await sql.delete(key,'key'); + } +} diff --git a/lib/views/first_page.dart b/lib/views/first_page.dart index d183770d..c31df0a2 100644 --- a/lib/views/first_page.dart +++ b/lib/views/first_page.dart @@ -4,8 +4,12 @@ import 'package:flutter_rookie_book/common/list_view_item.dart'; import 'package:flutter_rookie_book/components/list_refresh.dart' as listComp; import 'package:flutter_rookie_book/components/pagination.dart'; import 'package:flutter_rookie_book/components/first_page_item.dart'; +import 'package:flutter_rookie_book/components/disclaimer_msg.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../common/net_utils.dart'; +GlobalKey key; + class FirstPage extends StatefulWidget { @override FirstPageState createState() => new FirstPageState(); @@ -13,13 +17,52 @@ class FirstPage extends StatefulWidget { class FirstPageState extends State with AutomaticKeepAliveClientMixin{ - @override - bool get wantKeepAlive => true; + bool get wantKeepAlive => true; + + save(bool flag) async{ + //print('=============save=========$flag'); + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString('disclaimer', flag.toString()); + } + + Future get() async { + var value; + SharedPreferences prefs = await SharedPreferences.getInstance(); + value = prefs.getString('disclaimer'); + return value; + } @override void initState() { super.initState(); + if(key == null) { + //print('=============111=========${key}'); + delayed(); + } + key = GlobalKey(); + + } + + /* + * 判断是否需要弹出免责声明,已经勾选过不在显示,就不会主动弹 + * */ + Future delayed() async { + await new Future.delayed(const Duration(seconds: 1)); +// if (this.mounted) { +// setState(() { +// print('test=======>${key.currentState}'); +// key.currentState.showAlertDialog(context); +// //key.currentState.init(context); +// }); +// } + Future flag = get(); + flag.then((String value) { + //print('=============get=========$value'); + if(value.toString() == 'false'){ // 如果没有勾选下次开启 + key.currentState.showAlertDialog(context); + } + }); } Future getIndexListData([Map params]) async { @@ -52,7 +95,6 @@ class FirstPageState extends State with AutomaticKeepAliveClientMixin var myTitle = '${item.title}'; var myUsername = '${'👲'}: ${item.username} '; var codeUrl = '${item.detailUrl}'; - return new ListViewItem(itemUrl:codeUrl,itemTitle: myTitle,data: myUsername,); } @@ -61,14 +103,21 @@ class FirstPageState extends State with AutomaticKeepAliveClientMixin super.build(context); return new Column( children: [ - new Container( - child: new Pagination(), - ), + new Stack( + //alignment: const FractionalOffset(0.9, 0.1),//方法一 + children: [ + Pagination(), + Positioned(//方法二 + top: 10.0, + left: 0.0, + child: DisclaimerMsg(key:key,pWidget:this) + ), + ]), SizedBox(height: 2, child:Container(color: Theme.of(context).primaryColor)), new Expanded( //child: new List(), child: listComp.ListRefresh(getIndexListData,makeCard) - ), + ) ] ); diff --git a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart index 2592135c..a5e48eb8 100644 --- a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart +++ b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart @@ -34,10 +34,9 @@ const String _CheckboxListTileText2 = """### **进阶用法** > CheckboxListTile 单选和全选的示例 """; - +var valBool = true; class Demo extends StatefulWidget { static const String routeName = '/element/Form/Checkbox/CheckboxListTile'; - final bool valBool = true; @override _DemoState createState() => _DemoState(); } From f4aac4941e0ed15ba354e2e7d04635f42c82008d Mon Sep 17 00:00:00 2001 From: ryan730 Date: Sun, 13 Jan 2019 18:13:38 +0800 Subject: [PATCH 3/4] =?UTF-8?q?Modfiy:=E8=87=AA=E5=8A=A8=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/components/disclaimer_msg.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/disclaimer_msg.dart b/lib/components/disclaimer_msg.dart index b65a6f2d..2862e3e4 100644 --- a/lib/components/disclaimer_msg.dart +++ b/lib/components/disclaimer_msg.dart @@ -102,7 +102,7 @@ class DisclaimerMsgState extends State { showAlertDialog(context); //here i call the same function } ), - Text('不再显示',style:TextStyle(fontSize: 14)), + Text('不再自动提示',style:TextStyle(fontSize: 14)), ], ), new Flexible( From 5d88d0c088fe417197d4ae7512779c97a8653e10 Mon Sep 17 00:00:00 2001 From: ryan730 Date: Sun, 13 Jan 2019 19:06:08 +0800 Subject: [PATCH 4/4] Modify: checkbosListTile bug --- lib/widgets/elements/Form/CheckBox/CheckboxListTile/demo.dart | 4 ++-- .../elements/Form/CheckBox/CheckboxListTile/index.dart | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/demo.dart b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/demo.dart index bae9572c..ce63afa7 100644 --- a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/demo.dart +++ b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/demo.dart @@ -119,9 +119,9 @@ class CheckboxListTileDefault extends StatelessWidget { return CheckboxListTile( title: Text('一个简单的例子'), activeColor: Colors.red, - value: widget.valBool, + value: widget.valBool['val'], onChanged: (bool value) { - parant.setState(()=> widget.valBool = value); + parant.setState(()=> widget.valBool['val'] = value); }, secondary: const Icon(Icons.hourglass_empty), ); diff --git a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart index a5e48eb8..a38f9cbc 100644 --- a/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart +++ b/lib/widgets/elements/Form/CheckBox/CheckboxListTile/index.dart @@ -34,9 +34,10 @@ const String _CheckboxListTileText2 = """### **进阶用法** > CheckboxListTile 单选和全选的示例 """; -var valBool = true; + class Demo extends StatefulWidget { static const String routeName = '/element/Form/Checkbox/CheckboxListTile'; + final Map valBool = {'val':true}; @override _DemoState createState() => _DemoState(); }