使用优化代码显示开放时间的颤振方法



我已经设法编译了下面的代码,但知道我可以使用更好的方法显示开放时间。我相信它可以使用未来的建设者,但我还没有经验。下面的代码加载项目,然后去查找开放时间。任何人都可以帮助优化这段代码,使其显示在第一个实例。我认为下面的代码有性能问题。

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:rapideats/global/global.dart';
import '../mainScreens/menus_screen.dart';
import '../models/sellers.dart';
class SellersDesignWidget extends StatefulWidget {
Sellers? model;
BuildContext? context;
SellersDesignWidget({this.model,this.context});
String status = "";
@override
State<SellersDesignWidget> createState() => _SellersDesignWidgetState();
}
class _SellersDesignWidgetState extends State<SellersDesignWidget> {
var status = "Closed";
getOpeningHours() async
{
var date = DateTime.now();
var from = "";
var to = "";
var TodaysDate = DateFormat('EEEE').format(date).substring(0,3).toLowerCase();
// prints mon,tue etc.
QuerySnapshot oh = await FirebaseFirestore.instance.collection("openingHours")
.where("sellerUID", isEqualTo:widget.model!.sellerUID!)
.get();
if(oh.docs.isNotEmpty)
{
for (int i=0; i < oh.docs.length; i++)
{
from = oh.docs[i][TodaysDate+"From"].toString();
to = oh.docs[i][TodaysDate+"To"].toString();
}
if(from == "00:00" && to == "00:00")
{
setState(() {
status = "Closed";
} );
}else
{
setState(() {
status = "Open Now: " + TodaysDate.toTitleCase() + " " + from + " - " + to + "Hrs";
} );
}
}
}
void initState(){
super.initState();
getOpeningHours();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child : Padding(
padding:  const EdgeInsets.all(6.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(widget.model!.sellerAvatarUrl!,
height: 150,
width: 150,
fit:BoxFit.cover,
),
),
const SizedBox(width: 10.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Text(
widget.model!.sellerName!.toTitleCase(),
style: const TextStyle(
color:Colors.black,
fontSize: 24,
fontFamily:"Acme",
),
),
),
const SizedBox(
width: 10,
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Text(
status,
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child:
status == "Closed"
? const Text(
"",
)
: ElevatedButton(
child: const Text("Order Now"),
style: ElevatedButton.styleFrom(
backgroundColor:Colors.blueAccent,
),
onPressed: ()
{
Navigator.push(context, MaterialPageRoute(builder:(c)=> MenusScreen(model:widget.model)));
},
)
),
]
),
],
),
),
],
),
),
);
}
}

我建议使用状态管理包以更简单、更清晰的方式处理UI状态。例如,你可以使用Bloc或Provider (There's more packages)

但是作为你问题的答案,并使用FutureBuilder来处理你的状态来优化你的UI性能,你可以使用这个代码


import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart';
import 'package:rapideats/global/global.dart';
import '../mainScreens/menus_screen.dart';
import '../models/sellers.dart';
/// We Changed it to StatelessWidget as we don't need to rebuild the whole screen again
class SellersDesignWidget extends StatelessWidget {
final Sellers? model;
SellersDesignWidget({this.model});
/// We will use the same function with some modification to get the data and return the value to the FutureBuilder
Future<String> getOpeningHours() async
{
String status = "Closed";
DateTime date = DateTime.now();
String from = "";
String to = "";
String todaysDate = DateFormat('EEEE').format(date).substring(0, 3).toLowerCase();
// prints mon,tue etc.
QuerySnapshot oh = await FirebaseFirestore.instance.collection("openingHours")
.where("sellerUID", isEqualTo: model!.sellerUID!)
.get();
if (oh.docs.isNotEmpty) {
for (int i = 0; i < oh.docs.length; i++) {
from = oh.docs[i][todaysDate + "From"].toString();
to = oh.docs[i][todaysDate + "To"].toString();
}
if (from == "00:00" && to == "00:00") {
status = "Closed";
} else {
status = "Open Now: " + todaysDate.toTitleCase() + " " + from + " - " + to + "Hrs";
}
}
return status;
}
@override
Widget build(BuildContext context) {
/// As most of your UI doesn't depend on the data from Firebase so it can be shown directly
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(model!.sellerAvatarUrl!,
height: 150,
width: 150,
fit: BoxFit.cover,
),
),
const SizedBox(width: 10.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Text(
model!.sellerName!.toTitleCase(),
style: const TextStyle(
color: Colors.black,
fontSize: 24,
fontFamily: "Acme",
),
),
),
const SizedBox(
width: 10,
),
],
),
const SizedBox(
height: 20,
),
/// For the part needs the remote data we wrap it in future builder
FutureBuilder(
future: getOpeningHours(),
builder: (ctx, AsyncSnapshot<String?> status) {
/// When data is loading(status == null) we display a progress indicator and prevent the user from performing any actions
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
status.data == null ?
//Change SizedBox Size if needed
SizedBox(
width: 30, child: CircularProgressIndicator(),)
: Text(
status.data!,
style: TextStyle(
color: Colors.grey,
fontSize: 14,
),
),
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child:
status.data == "Closed"
? const Text(
"",
)
: ElevatedButton(
child: status.data == null ?
//Change SizedBox Size if needed
SizedBox(
width: 30, child: CircularProgressIndicator(),) : Text("Order Now"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueAccent,
),
onPressed: () {
if (status.data != null) {
Navigator.push(context,
MaterialPageRoute(builder: (c) => MenusScreen(model: model)));
}
},
)
),
]
),
],
);
}),
],
),
),
],
),
),
);
}
}

最干净的方法是:
1 -您展示第一个油漆并给出开放时间块的条件。如果小时数已经被获取,显示它们,否则,显示一个进度指示器或者一个正在加载的文本或者任何一种向用户显示正在加载的东西的指示。
2-然后,在init状态下,不要忘记在调用函数时将havefetch_false设置为false,并在调用fetch函数结束时将其设置为true。你还需要通过给它一些默认时间或'error'文本来处理可能的错误。
正如Hesham Erfan所提到的,如果你有一个重UI的设计,你应该使用状态管理解决方案和无状态小部件,因为它将提高性能。我建议:
1 -getx
2 -provider小项目(快速编码,还包括导航器,无上下文toast,零食栏,屏幕宽度和高度等)非常好的状态管理器(非常流行的好文档,也很容易学习),和
3 -bloc对于企业(它有很多锅炉板,但周围的结构非常相似)。您必须将初始化状态逻辑移动到您实现的状态管理解决方案中。

最新更新