mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
update task page
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:back_button_interceptor/back_button_interceptor.dart';
|
||||
@@ -28,23 +27,23 @@ class CommonDialog extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 15.0),
|
||||
margin: const EdgeInsets.only(top: 15.0),
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 40,
|
||||
),
|
||||
child: IconTheme(
|
||||
data: IconThemeData(
|
||||
data: const IconThemeData(
|
||||
color: Colors.white,
|
||||
size: 40.0,
|
||||
),
|
||||
child: LoadingIcon()),
|
||||
),
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
if (text != null)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 15,
|
||||
right: 15,
|
||||
bottom: 15,
|
||||
@@ -53,7 +52,7 @@ class CommonDialog extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: const TextStyle(color: Colors.white, fontSize: 14),
|
||||
child: Text(text!),
|
||||
),
|
||||
),
|
||||
@@ -83,7 +82,7 @@ class LoadingIconState extends State<LoadingIcon> with SingleTickerProviderState
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = new AnimationController(vsync: this, duration: Duration(milliseconds: 1000))..repeat();
|
||||
_controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 1000))..repeat();
|
||||
_doubleAnimation = Tween(begin: 0.0, end: 360.0).animate(_controller!)
|
||||
..addListener(() {
|
||||
setState(() {});
|
||||
@@ -113,12 +112,14 @@ typedef HideCallback = Future Function();
|
||||
|
||||
int backButtonIndex = 2;
|
||||
|
||||
OverlayEntry? overlay;
|
||||
|
||||
HideCallback showCommonDialog(
|
||||
BuildContext context, {
|
||||
String? text,
|
||||
bool backButtonClose = false,
|
||||
CommonDialogState commonDialogState = CommonDialogState.LOADING,
|
||||
}) {
|
||||
BuildContext context, {
|
||||
String? text,
|
||||
bool backButtonClose = false,
|
||||
CommonDialogState commonDialogState = CommonDialogState.LOADING,
|
||||
}) {
|
||||
Completer<VoidCallback> result = Completer<VoidCallback>();
|
||||
var backButtonName = 'QL_Toast$backButtonIndex';
|
||||
BackButtonInterceptor.add((stopDefaultButtonEvent, _) {
|
||||
@@ -131,7 +132,11 @@ HideCallback showCommonDialog(
|
||||
}, zIndex: backButtonIndex, name: backButtonName);
|
||||
backButtonIndex++;
|
||||
|
||||
var overlay = OverlayEntry(
|
||||
if (overlay != null) {
|
||||
overlay?.remove();
|
||||
overlay = null;
|
||||
}
|
||||
overlay = OverlayEntry(
|
||||
maintainState: true,
|
||||
builder: (_) => WillPopScope(
|
||||
onWillPop: () async {
|
||||
@@ -145,10 +150,12 @@ HideCallback showCommonDialog(
|
||||
),
|
||||
);
|
||||
result.complete(() {
|
||||
overlay.remove();
|
||||
overlay?.remove();
|
||||
BackButtonInterceptor.removeByName(backButtonName);
|
||||
});
|
||||
Overlay.of(context)?.insert(overlay);
|
||||
if (overlay != null) {
|
||||
Overlay.of(context)?.insert(overlay!);
|
||||
}
|
||||
|
||||
return () async {
|
||||
var hide = await result.future;
|
||||
@@ -193,4 +200,4 @@ HideCallback loadingDialog(BuildContext context, {String? text}) {
|
||||
commonDialogState: CommonDialogState.LOADING,
|
||||
backButtonClose: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class MyApp extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: MaterialApp(
|
||||
@@ -41,7 +41,8 @@ class MyApp extends ConsumerWidget {
|
||||
onGenerateRoute: (setting) {
|
||||
return Routes.generateRoute(setting);
|
||||
},
|
||||
home: ref.read<UserInfoViewModel>(userInfoProvider).userInfoBean != null ? const HomePage() : LoginPage(),
|
||||
// home: ref.read<UserInfoViewModel>(userInfoProvider).userInfoBean != null ? const HomePage() : LoginPage(),
|
||||
home: HomePage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class _HomePageState extends State<HomePage> {
|
||||
onTap: () {
|
||||
ref.read(themeProvider).changeTheme();
|
||||
},
|
||||
child: Center(child: Text("改变主题")),
|
||||
child: const Center(child: Text("改变主题")),
|
||||
);
|
||||
}),
|
||||
],
|
||||
|
||||
@@ -16,7 +16,6 @@ class LoginPage extends StatefulWidget {
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final TextEditingController _userNameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
HideCallback? _hideCallback;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -24,21 +23,9 @@ class _LoginPageState extends State<LoginPage> {
|
||||
body: Consumer(builder: (context, ref, child) {
|
||||
var model = ref.watch<LoginViewModel>(loginProvider);
|
||||
|
||||
if (model.isLoading) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
_hideCallback ??= loadingDialog(context, text: "登录中...");
|
||||
});
|
||||
} else {
|
||||
if (_hideCallback != null) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
_hideCallback!();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (model.loginSuccess) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||
Navigator.of(context).pushNamed(Routes.route_HomePage);
|
||||
Navigator.of(context).popAndPushNamed(Routes.route_HomePage);
|
||||
});
|
||||
}
|
||||
return SizedBox(
|
||||
@@ -130,16 +117,19 @@ class _LoginPageState extends State<LoginPage> {
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 30,
|
||||
child: CupertinoButton(
|
||||
color: (_userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty)
|
||||
color: (_userNameController.text.isNotEmpty && _passwordController.text.isNotEmpty && !model.isLoading)
|
||||
? Theme.of(context).primaryColor
|
||||
: Theme.of(context).primaryColor.withOpacity(0.3),
|
||||
child: const Text(
|
||||
"登录",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
child: model.isLoading
|
||||
? const CupertinoActivityIndicator()
|
||||
: const Text(
|
||||
"登录",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (model.isLoading) return;
|
||||
Utils.hideKeyBoard(context);
|
||||
model.login(_userNameController.text, _passwordController.text);
|
||||
}),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:qinglong_app/base/base_state_widget.dart';
|
||||
import 'package:qinglong_app/module/task/task_viewmodel.dart';
|
||||
|
||||
@@ -15,13 +17,24 @@ class _TaskPageState extends State<TaskPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return BaseStateWidget<TaskViewModel>(
|
||||
builder: (context, model, child) {
|
||||
return ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(model.list[index]),
|
||||
);
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
return Future.delayed(Duration(seconds: 1), () {});
|
||||
},
|
||||
itemCount: model.list.length,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 15,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
return TaskItemCell();
|
||||
},
|
||||
itemCount: model.list.length,
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return SizedBox(
|
||||
height: 10,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
model: taskProvider,
|
||||
@@ -31,3 +44,94 @@ class _TaskPageState extends State<TaskPage> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TaskItemCell extends StatelessWidget {
|
||||
const TaskItemCell({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Slidable(
|
||||
key: const ValueKey(0),
|
||||
startActionPane: ActionPane(
|
||||
motion: const ScrollMotion(),
|
||||
extentRatio: 0.3,
|
||||
dragDismissible: false,
|
||||
children: [
|
||||
SlidableAction(
|
||||
flex: 1,
|
||||
icon: CupertinoIcons.memories,
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFF0F77FE),
|
||||
onPressed: (BuildContext context) {},
|
||||
),
|
||||
SlidableAction(
|
||||
flex: 1,
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
icon: CupertinoIcons.clock_fill,
|
||||
onPressed: (BuildContext context) {},
|
||||
),
|
||||
],
|
||||
),
|
||||
endActionPane: ActionPane(
|
||||
motion: ScrollMotion(),
|
||||
extentRatio: 0.15,
|
||||
children: [
|
||||
SlidableAction(
|
||||
backgroundColor: Colors.cyan,
|
||||
flex: 1,
|
||||
onPressed: (_) {},
|
||||
foregroundColor: Colors.white,
|
||||
icon: CupertinoIcons.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: const [
|
||||
Text(
|
||||
"东东农场",
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
height: 15,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Text("2020/12/12 12:23"),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
const Text(
|
||||
"12/12/12",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,13 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_slidable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_slidable
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
||||
@@ -16,6 +16,7 @@ dependencies:
|
||||
shared_preferences: ^2.0.12
|
||||
synchronized: ^3.0.0
|
||||
back_button_interceptor: ^5.0.2
|
||||
flutter_slidable: ^1.2.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user