How can I create a scrollable page using flutter where the children don't exceed the maxWidth of a parent container? - flutter-web

Problem
I have tried SingleChildListView and ListView widgets but the children end up spanning full width. I need the widgets to not exceed a maxWidth of 850px. Using a container with a width:850 or a BoxContraints(maxWidth:850) does not apply to the children inside the list view.
Desired Outcome
The form should be centered on the page but the scrollbar should be as far right as possible. If the user's mouse is on the form or in the white space to the left/right of the form, the user should retain the ability to scroll up/down.
SFUScaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Container(
constraints:
BoxConstraints(maxWidth: ThemeManager.getTheme().maxWidth),
child: Scrollbar(
isAlwaysShown: true,
controller: _scrollbar,
child: SingleChildScrollView(
controller: _scrollbar,
padding: EdgeInsets.all(15),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SFUSizedBox(height: 5),
Text(
"Secure File Upload Form",
style: ThemeManager.getTheme().formTitleStyle,
),
SFUSizedBox(height: 5),
Text(
"Quickly upload and send documents directly to the ${ThemeManager.getTheme().clientName} team",
style: ThemeManager.getTheme().formSubtitleStyle,
),
SFUSizedBox(height: 5),
Divider(),
SFUSizedBox(height: 5),
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Visibility(
visible: state.hasErrors,
child: FittedBox(
child: Row(
children: [
Icon(
LineIcons.exclamationCircle,
color: ThemeManager.getTheme().errorColor,
size: 30,
),
Text(
"Your form was not sent. Please correct the issues below and try again.",
style: ThemeManager.getTheme().errorStyle,
),
],
),
),
);
}),
Text(
"Tell us who you are",
style: ThemeManager.getTheme().formSectionTitleStyle,
),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
isLargeScreen
? _BuildNameLayout(direction: Axis.horizontal)
: _BuildNameLayout(direction: Axis.vertical),
SFUSizedBox(height: 5),
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Container(
width: isLargeScreen
? ThemeManager.getTheme().px2pt(400)
: ThemeManager.getTheme().px2pt(600),
child: PXFormField(
label: "Member ID:",
optional: true,
initalValue: state.formFields["member_id"] ?? "",
onChanged: (value) {
context
.read<FormCubit>()
.updateFormField('member_id', value);
},
),
);
},
),
SizedBox(height: ThemeManager.getTheme().px2pt(20)),
Divider(),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
Text(
"Share your contact details",
style: ThemeManager.getTheme().formSectionTitleStyle,
),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Container(
width: isLargeScreen
? ThemeManager.getTheme().px2pt(400)
: ThemeManager.getTheme().px2pt(600),
child: PXFormField(
initalValue: state.formFields["email"] ?? "",
label: "Email: *",
optional: false,
onChanged: (value) {
context
.read<FormCubit>()
.updateFormField('email', value);
},
validator: (value) {
if (!FieldValidator.validateEmail(value)) {
return "Please provide a valid email address.";
} else if (state.formErrors
.containsKey("email")) {
return state.formErrors['email'];
}
return null;
}),
);
},
),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Container(
width: isLargeScreen
? ThemeManager.getTheme().px2pt(400)
: ThemeManager.getTheme().px2pt(600),
child: PXFormField(
initalValue:
state.formFields["phone_number"] ?? "",
label: "Phone Number:",
optional: true,
onChanged: (value) {
context
.read<FormCubit>()
.updateFormField('phone_number', value);
},
),
);
},
),
SizedBox(height: ThemeManager.getTheme().px2pt(20)),
Divider(
thickness: 1.0,
),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
Text(
"Select the files that you would like to send",
style: ThemeManager.getTheme().formSectionTitleStyle,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Text(
state.formErrors['files'] != null
? state.formErrors['files'].toString()
: "",
style: ThemeManager.getTheme().errorStyle,
);
},
),
],
),
Text(
"Upload Your Files: *",
style: ThemeManager.getTheme().formLabelStyle,
),
SizedBox(
height: ThemeManager.getTheme().px2pt(15),
),
UploadFilesComponent(),
Container(
child: BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return Column(
children: new List.generate(
state.files.length,
(index) => FileCard(
//Add Progress value here for styling....
file: state.files[index],
fileIndex: index),
),
);
},
),
),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
Divider(),
SizedBox(height: ThemeManager.getTheme().px2pt(10)),
Text(
"Provide any background or instructions for the files you're sending",
style: ThemeManager.getTheme().formSectionTitleStyle),
SFUSizedBox(height: 20),
RichText(
text: TextSpan(
text: "Additional Information:",
style: ThemeManager.getTheme().formLabelStyle,
children: <TextSpan>[
TextSpan(
text: " (optional)",
style: ThemeManager.getTheme()
.formOptionalLabelStyle,
)
]),
),
SFUSizedBox(height: 30),
BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return TextFormField(
keyboardType: TextInputType.multiline,
maxLines: null,
minLines: 4,
onChanged: (value) {
context.read<FormCubit>().updateFormField(
'additional_information', value);
},
);
},
),
SFUSizedBox(height: 30),
Center(
child: Container(
width: ThemeManager.getTheme().px2pt(300),
height: ThemeManager.getTheme().px2pt(50),
child: BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return DarkOutlinedButton(
buttonText: "Send Your Files",
onpressed: () {
context.read<FormCubit>().validateForm();
_formKey.currentState!.validate();
if (!state.hasErrors) {
Navigator.pushNamedAndRemoveUntil(context,
"/submission-details", (_) => false);
}
},
);
},
),
),
),
SFUSizedBox(height: 30),
Divider(),
SFUSizedBox(height: 30),
Center(
child: Image.asset("images/powered_by_pensionx.png")),
Center(
child: TextButton(
onPressed: () async {
await showDialog(
context: context,
builder: (_) => ReportProblemModal(),
);
},
child: Text(
"Report a Problem",
style: TextStyle(
color: Theme.of(context).primaryColor),
),
),
)
],
),
),
),
),
),
),
),
);
class SFUSizedBox extends StatelessWidget {
final double height;
const SFUSizedBox({
required this.height,
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(height: ThemeManager.getTheme().px2pt(height));
}
}
class _BuildNameLayout extends StatelessWidget {
final Axis direction;
_BuildNameLayout({required this.direction});
#override
Widget build(BuildContext context) {
List<Widget> content = [
Expanded(
flex: this.direction == Axis.horizontal ? 3 : 0,
child: BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return PXFormField(
initalValue: state.formFields["first_name"] ?? "",
label: "First Name: *",
optional: false,
validator: (value) {
if (state.formErrors.containsKey("first_name")) {
return state.formErrors['first_name'];
}
return null;
},
onChanged: (value) {
context.read<FormCubit>().updateFormField('first_name', value);
},
);
},
),
),
SizedBox(width: 10),
Expanded(
flex: this.direction == Axis.horizontal ? 2 : 0,
child: BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return PXFormField(
initalValue: state.formFields["middle_initial"] ?? "",
label: "Middle Initial:",
optional: false,
onChanged: (value) {
context
.read<FormCubit>()
.updateFormField('middle_initial', value);
},
);
},
),
),
SizedBox(width: 10),
Expanded(
flex: this.direction == Axis.horizontal ? 3 : 0,
child: BlocBuilder<FormCubit, FormCubitState>(
builder: (context, state) {
return PXFormField(
initalValue: state.formFields["last_name"] ?? "",
label: "Last Name: *",
optional: false,
onChanged: (value) {
context.read<FormCubit>().updateFormField('last_name', value);
},
validator: (value) {
if (state.formErrors.containsKey("last_name")) {
return state.formErrors['last_name'];
}
return null;
},
);
},
),
),
];
if (this.direction == Axis.horizontal) {
return Container(
width: ThemeManager.getTheme().maxWidth,
child: Row(children: content));
}
if (this.direction == Axis.vertical) {
return Column(
mainAxisSize: MainAxisSize.min,
children: content,
);
}
// This shoudln't ever happen.
throw new Exception(
'Direction must be set to Axis.horizontal or Axis.vertical');
}
}
The image above has the following problems:
The white space to the left/right doesn't allow the user to scroll
The scroll bar needs to be as far to right as possible.
The form appears to be embedded into the page but I want it to feel like an entire page.

Related

Flutter; List obs does not refresh new elements on default tab controller tabs

Hello i am learning the state using the getX methods. When the app loads i am adding the categories in the list but the issue is not updating. can anybody look whats my wrong?
Restaurant Ui Button Page:
HomeController con = Get.put(HomeController());
Widget _cardRestoran(BuildContext context, Restaurants restaurant) {
return GestureDetector(
onTap: () {
con.restoranProducts(context, restaurant);
},
child: Column(
children: [
Container(
margin: EdgeInsets.only(top: 15, left: 20, right: 20),
child: ListTile(
title: Text('${restaurant.name ?? ''}' ,),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 5),
Text(
' Şehir: ${restaurant.il ?? ''} - İlçe: ${restaurant.ilce ?? ''}' ,
maxLines: 2,
style: TextStyle(
fontSize: 13
),
),
SizedBox(height: 15),
],
),
trailing: Container(
height: 70,
width: 60,
// padding: EdgeInsets.all(2),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: FadeInImage(
image: restaurant.image != null
? NetworkImage(restaurant.image ?? '')
: AssetImage('assets/img/no-image.png') as ImageProvider,
fit: BoxFit.cover,
fadeInDuration: Duration(milliseconds: 50),
placeholder: AssetImage('assets/img/no-image.png'),
),
),
),
),
),
Divider(height: 1, color: Colors.grey[300], indent: 37, endIndent: 37,)
],
),
);
}
Home Controller
class HomeController extends GetxController{
void restoranProducts(BuildContext context, Restaurants restaurants) async{
await showMaterialModalBottomSheet(
context: context,
useRootNavigator: true,
builder: (context) => RestoranProducts(restaurants: restaurants),
);
}
}
Restaurant Category Controller :
class ClientRestoranProductListController extends GetxController{
String res_id;
List<Category> categories = <Category>[].obs;
ClientRestoranProductListController(#required this.res_id){
getCategories();
}
void getCategories() async {
var result = await categoriesProvider.restaurantCategory("${this.res_id}");
categories.clear();
categories.addAll(result);
}
}
I also tried seperate but it still didnt work.
Restoran Products Category List UI page:
class RestoranProducts extends StatefulWidget {
final Restaurants? restaurants;
const RestoranProducts({Key? key, required this.restaurants}) : super(key: key);
#override
State<RestoranProducts> createState() => _RestoranProductsState();
}
class _RestoranProductsState extends State<RestoranProducts> {
Widget build(BuildContext context) {
String restoranSahibi = "${widget.restaurants?.user_id}";
ClientRestoranProductListController con = Get.put(ClientRestoranProductListController(restoranSahibi));
return Obx(() => DefaultTabController(
length: con.categories.length,
child: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => setState((){
})),
drawer: HomeNavigator(),
appBar: PreferredSize(
preferredSize: Size.fromHeight(110),
child:AppBar(
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors:
[
Colors.amber,
Colors.black,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
)
),
margin: EdgeInsets.only(top: 15),
alignment: Alignment.topCenter,
child: Wrap(
direction: Axis.horizontal,
children: [
_textFieldSearch(context),
_iconShoppingBag()
],
),
),
centerTitle: true,
iconTheme: IconThemeData(color: Colors.white),
bottom: TabBar(
isScrollable: true,
indicatorColor: Colors.white,
labelColor: Colors.black,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.tab,
indicator: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
color: Colors.white
),
tabs: List<Widget>.generate(con.categories.length, (index) {
return Tab(
child: Text(con.categories[index].name ?? ''),
);
}),
),
) ,
),
body: TabBarView(
key: Key(Random().nextDouble().toString()),
children: con.categories.map((Category category) {
return FutureBuilder(
future: con.getProducts(category.id ?? '1', con.productName.value),
builder: (context, AsyncSnapshot<List<Product>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.length > 0) {
return ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (_, index) {
return _cardProduct(context, snapshot.data![index]);
}
);
}
else {
return NoDataWidget(text: 'No category');
}
}
else {
return NoDataWidget(text: 'No category');
}
}
);
}).toList(),
)
),
));
}
}
i tried seperate ways but it did not work.

Flutter Duplicate Global Key detected on widget tree

I have this issue when implementing flutter's showcaseview despite following its official documentation. The errors I get have to do with a duplicate global state and here's a sample if my code:
final GlobalKey _timeline_filter = GlobalKey();
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Future.delayed(const Duration(milliseconds: 400), () {
print("showcasing..");
ShowCaseWidget.of(context).startShowCase([_timeline_filter]);
});
});
}
Build method Code:
#override
Widget build(BuildContext context) {
return Material(
child: Container(
child: ListView(
controller: scroll_controller,
shrinkWrap: true,
children: <Widget>[
Container(
child: Column(
children: [
Container(
margin: EdgeInsets.only(
left: 83.5.w,
),
child: SizedBox(
width: 10.w,
child: FloatingActionButton(
elevation: 0.4.h,
backgroundColor: Colors.white,
foregroundColor: Colors.black,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FilterTags()));
},
child: Showcase(
key: _timeline_filter,
description: "tap to filter by category",
child: Icon(FontAwesomeIcons.filter, size: 11.sp)),
),
)),
],
)),
buildTimelinePosts(),
],
),
),
);
}

Does my style of coding make the Emulator slow?

I am working with Android Studio it runs really smooth. After some time of update. The app was really slow at getting data from the backend (testing backend with PostMan still fast) also execute other tasks. I wonder if our style of coding slow down the app. Have you ever experienced this ? Does the bad coding style has a huge effect on Emulator performance. If yes, could you please suggest a good way of coding that allows the app in Android Studio run faster.
Thank you so much.
Edit: Here is my code
import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart' hide Image;
import 'package:flutter/material.dart' hide Image;
import 'package:flutter/widgets.dart';
import 'package:goweefrontend/SizeConfig.dart';
import 'package:goweefrontend/View/Detail/DetailJourney.dart';
import 'package:goweefrontend/View/Map/TestMap.dart';
import 'package:goweefrontend/Model/LoggedUser.dart';
import 'package:goweefrontend/View/CustomBottomNavBar/CustomBottomNavBar.dart';
import 'package:goweefrontend/View/UserPage/CustomCalendar.dart';
import 'package:goweefrontend/View/UserPage/JoinRequest.dart';
import 'package:goweefrontend/View/UserPage/UserPageService.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:goweefrontend/View/LoginFunction/LoginComponent/LoginScreen.dart';
import '../../Constants.dart';
import 'package:http/http.dart' as http;
import '../../Model/Journey.dart';
class UserPage extends StatefulWidget {
static String routeName = "/userPage";
#override
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
CalendarFormat format = CalendarFormat.twoWeeks;
DateTime focusedDay = DateTime.now();
DateTime selectedDay = DateTime.now();
bool upcomingIsVisible = false;
bool draftIsVisible = false;
bool passedIsVisible = false;
TextEditingController _lastNameController = TextEditingController();
TextEditingController _firstNameController = TextEditingController();
TextEditingController _ageController = TextEditingController();
TextEditingController _phoneNumberController = TextEditingController();
String _firstName;
String _lastName;
int _age;
String _phoneNumber;
String _imageURL;
List<Journey> journeyList = [];
Future _future;
Future loadUser() async {
String jsonString = await storage.read(key: "jwt");
final jsonResponse = json.decode(jsonString);
loggedUser = new LoggedUser.fromJson(jsonResponse);
getProfile();
}
//http APIs
editProfile(
String lastName, String firstName, String age, String phoneNumber) async {
await UserPageService().editProfile(lastName, firstName, age, phoneNumber);
}
getProfile() async {
var res = await http.get(
Uri.parse("$baseUrl/users/${loggedUser.user.userId}"),
headers: {
'Content_Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ${loggedUser.token}',
'Connection': 'Keep-Alive'
},
);
var data = jsonDecode(res.body);
loggedUser.user.firstName = data["firstName"];
loggedUser.user.lastName = data["lastName"];
loggedUser.user.age = data["age"];
loggedUser.user.phoneNumber = data["phoneNumber"];
loggedUser.user.userAvatar.imageLink = data["userAvatar"]["imageLink"];
setState(() {
_firstName = data["firstName"];
_lastName = data["lastName"];
_age = data["age"];
_phoneNumber = data["phoneNumber"];
_imageURL = data["userAvatar"]["imageLink"];
});
}
getJourneyByUserId() async {
setState(() {
journeyList = [];
});
var res = await http.get(
Uri.parse("$baseUrl/journeys/userid=${loggedUser.user.userId}"),
headers: {
'Content_Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ${loggedUser.token}',
'Connection': 'Keep-Alive'
},
);
var data = jsonDecode(res.body);
List idList = [];
for (var i in data) {
idList.add(i["journeyId"]);
}
for (var i in idList) {
var res = await http.get(
Uri.parse("$baseUrl/journeys/$i"),
);
var data = jsonDecode(res.body);
Journey userJourney = new Journey.fromJson(data);
setState(() {
journeyList.add(userJourney);
});
}
return journeyList;
}
logOut() async {
await UserPageService().logOut();
setState(() {
rangeList.clear();
journeyList.clear();
});
}
Future functionForBuilder() async {
return await getJourneyByUserId();
}
//function to print Journey Card
Widget printCard(Journey journey, IconData flexIcon, page, visible) {
return Visibility(
visible: visible,
child: Column(
children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 5, 0, 5),
child: Container(
height: getHeight(0.1),
padding: EdgeInsets.fromLTRB(5, 10, 0, 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
offset: Offset(0, 8),
blurRadius: 5,
color: Colors.grey[300]),
]),
child: Row(
children: [
Padding(
//show journey image
padding: EdgeInsets.all(3),
child: CircleAvatar(
backgroundImage: NetworkImage(journey
.images[0].imageLink !=
null
? journey.images[0].imageLink
: "assets/images/Travel-WordPress-Themes.jpg.webp"),
radius: 20,
),
),
SizedBox(width: getWidth(0.02)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Container(
width: getWidth(0.32),
child: AutoSizeText(
"${journey.departure} - ${journey.destination}",
style: TextStyle(color: Colors.black),
overflow: TextOverflow.ellipsis,
),
),
],
),
],
),
SizedBox(width: getWidth(0.05)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Container(
width: getWidth(0.27),
child: AutoSizeText(
"${journey.startDate.day}/${journey.startDate.month} - "
"${journey.endDate.day}/${journey.endDate.month}/${journey.endDate.year}",
style:
TextStyle(color: Colors.grey, fontSize: 13),
maxLines: 1,
),
),
],
),
],
),
SizedBox(width: getWidth(0.05)),
Column(
children: [
Container(
width: getWidth(0.1),
child: TextButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => page));
},
child: FittedBox(
child: Icon(
flexIcon,
color: Colors.black,
),
),
),
)
],
)
],
),
),
)
],
),
);
}
//function to show dialog User Profile Card
showDialogFunc1(context) {
return showDialog(
context: context,
builder: (context) {
return Stack(alignment: Alignment.bottomCenter, children: [
Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 270),
height: getHeight(0.4),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(30.0)),
child: Padding(
padding: EdgeInsets.fromLTRB(20, 30, 0, 10),
child: Row(children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
printInfo("NAME", "$_lastName $_firstName"),
printInfo("AGE", "$_age"),
printInfo("PHONE", "$_phoneNumber"),
Center(
child: Container(
height: getHeight(0.05),
decoration: kBoxDecorationView,
child: TextButton(
onPressed: () {
showDialogFunc2(context);
},
child: Text(
"Edit Profile",
style: TextStyle(color: Colors.white),
),
),
),
)
]),
flex: 5,
),
Expanded(
child: Column(
children: [
Padding(
padding: EdgeInsets.fromLTRB(10, 0, 40, 0),
child: Column(
children: [
CircleAvatar(
radius: 35,
backgroundImage: NetworkImage(
loggedUser.user.userAvatar.imageLink),
),
SizedBox(height: 15),
FittedBox(
child: Text(
"${loggedUser.user.email}",
style: TextStyle(
fontSize: 15,
color: Colors.black,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
decoration: TextDecoration.none),
),
)
],
),
)
],
),
flex: 5,
)
]))),
]);
});
}
//print User Information
printInfo(info1, info2) {
return FittedBox(
child: Row(
children: [
Text(
info1 + " : " + info2,
style: TextStyle(
decoration: TextDecoration.none,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
);
}
Widget loopPrintUpComeTrip() {
int counter = 0;
List<Widget> list = [];
for (var i in journeyList) {
if (i.status == "Upcoming") {
counter += 1;
if (counter == 1) {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), true));
} else {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), upcomingIsVisible));
}
}
}
if (counter == 0) {
list.add(Text("No Upcoming Trip to show"));
}
return Column(children: list);
}
Widget loopPrintInProgressTrip() {
int counter = 0;
List<Widget> list = [];
for (var i in journeyList) {
if (i.status == "In progress") {
counter += 1;
if (counter == 1) {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), true));
} else {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), draftIsVisible));
}
}
}
if (counter == 0) {
list.add(Text("No In Progress Trip to show"));
}
return Column(children: list);
}
Widget loopPrintFinishedTrip() {
int counter = 0;
List<Widget> list = [];
for (var i in journeyList) {
if (i.status == "Finished") {
counter += 1;
if (counter == 1) {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), true));
} else {
list.add(printCard(i, Icons.arrow_forward_ios,
DetailsJourneyScreen(journey: i), passedIsVisible));
}
}
}
if (counter == 0) {
list.add(Text(
"No Finished Trip to show",
style: TextStyle(color: Colors.grey),
));
}
return Column(children: list);
}
//print edit form
printFormField(info, controller) {
return Container(
height: getHeight(0.06),
child: TextButton(
onPressed: () {},
child: TextField(
controller: controller,
style: TextStyle(fontSize: 15),
decoration: InputDecoration(
hintText: "New $info",
contentPadding: EdgeInsets.fromLTRB(15, 5, 0, 5),
isDense: true,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0),
borderSide: BorderSide(color: kTextColor),
gapPadding: 0,
),
),
),
),
);
}
//show dialog edit profile
showDialogFunc2(context) {
return showDialog(
context: context,
builder: (context) {
return Stack(alignment: Alignment.bottomCenter, children: [
Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 270),
height: getHeight(0.4),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(30.0)),
child: Padding(
padding: EdgeInsets.fromLTRB(20, 30, 0, 10),
child: Row(children: [
Expanded(
child: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
//mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
printFormField("Last Name", _lastNameController),
printFormField(
"First Name", _firstNameController),
printFormField("Age", _ageController),
printFormField(
"Phone Number", _phoneNumberController),
SizedBox(height: getHeight(0.01)),
Center(
child: Container(
height: getHeight(0.05),
decoration: kBoxDecorationView,
child: TextButton(
onPressed: () async {
await editProfile(
_lastNameController.text,
_firstNameController.text,
_ageController.text,
_phoneNumberController.text);
_lastNameController.clear();
_firstNameController.clear();
_ageController.clear();
_phoneNumberController.clear();
Navigator.pop(context);
Navigator.pop(context);
setState(() {
getProfile();
});
},
child: Text(
"Save",
style: TextStyle(color: Colors.white),
),
),
))
]),
flex: 6,
),
Expanded(
child: Column(
children: [
Padding(
padding: EdgeInsets.fromLTRB(10, 0, 40, 0),
child: Column(
children: [
CircleAvatar(
radius: 35,
backgroundImage: NetworkImage(
loggedUser.user.userAvatar.imageLink),
),
SizedBox(height: 10),
Text(
"Upload Image",
style: TextStyle(
fontSize: 10,
color: Colors.black,
fontWeight: FontWeight.bold,
letterSpacing: 1.0,
decoration: TextDecoration.none),
)
],
),
)
],
),
flex: 4,
)
]))),
]);
});
}
#override
void initState() {
super.initState();
loadUser();
_future = getJourneyByUserId();
}
//screen
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: kColorPalette4,
appBar: AppBar(
title: Text(
"User Profile",
style: TextStyle(color: kColorPalette4),
),
centerTitle: true,
backgroundColor: kBackgroundColor,
elevation: 0.0,
titleSpacing: 1.0,
),
body: Container(
child: FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
Text("Loading...")
]),
);
} else {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(10, 5, 10, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Center(
//user avatar
child: TextButton(
onPressed: () {
showDialogFunc1(context);
getProfile();
},
child: CircleAvatar(
backgroundImage: NetworkImage(_imageURL != null
? _imageURL
: "https://www.pngitem.com/pimgs/m/256-2560208_person-icon-black-png-transparent-png.png"),
radius: 50,
),
)),
SizedBox(height: 5),
CustomCalendar(),
Text("Trip Requests",
style: TextStyle(
color: kBackgroundColor,
letterSpacing: 1.0,
fontWeight: FontWeight.bold,
fontSize: 15)),
SizedBox(height: 10),
JoinRequest(),
SizedBox(height: 10),
Row(
children: [
Container(
width: getWidth(0.35),
child: AutoSizeText(
"Upcoming Trips",
style: TextStyle(
color: kColorUpComing,
letterSpacing: 1.0,
fontWeight: FontWeight.bold,
fontSize: 15),
maxLines: 1,
),
),
Padding(
padding: EdgeInsets.fromLTRB(15, 0, 0, 0),
child: Container(
height: getHeight(0.05),
decoration: kBoxDecorationView,
child: TextButton(
child: Text(
"View All",
style: TextStyle(color: kColorPalette4),
),
onPressed: () {
setState(() {
upcomingIsVisible = !upcomingIsVisible;
});
},
),
),
)
],
),
//upcoming trip card
SizedBox(height: 5),
loopPrintUpComeTrip(),
//Calendar Field
SizedBox(height: 5),
Row(
children: [
Container(
width: getWidth(0.35),
child: AutoSizeText(
"Finished Trips",
style: TextStyle(
color: kColorFinished,
letterSpacing: 1.0,
fontWeight: FontWeight.bold,
fontSize: 15),
maxLines: 1,
),
),
Padding(
padding: EdgeInsets.fromLTRB(15, 0, 0, 0),
child: Container(
height: getHeight(0.05),
decoration: kBoxDecorationView,
child: TextButton(
child: Text(
"View All",
style: TextStyle(color: kColorPalette4),
),
onPressed: () {
setState(() {
passedIsVisible = !passedIsVisible;
});
},
),
),
)
],
),
SizedBox(height: 5),
loopPrintFinishedTrip(),
SizedBox(height: 5),
Row(
children: [
Container(
width: getWidth(0.35),
child: AutoSizeText(
"In Progress Trips",
style: TextStyle(
color: kColorInProgress,
letterSpacing: 1.0,
fontWeight: FontWeight.bold,
fontSize: 15),
maxLines: 1,
),
),
Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Container(
height: getHeight(0.05),
decoration: kBoxDecorationView,
child: TextButton(
child: Text(
"View All",
style: TextStyle(color: kColorPalette4),
),
onPressed: () => setState(
() => draftIsVisible = !draftIsVisible),
),
),
)
],
),
SizedBox(height: 5),
loopPrintInProgressTrip(),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: getHeight(0.055),
decoration: kBoxDecorationView,
alignment: Alignment.center,
child: TextButton(
onPressed: () async {
await logOut();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
LoginScreen()));
},
child: FittedBox(
child: Row(
children: [
Icon(
Icons.logout,
color: kColorPalette4,
size: 20,
),
AutoSizeText(
"Log Out",
style: TextStyle(
color: kColorPalette4,
),
),
],
),
)),
)
],
),
SizedBox(
height: getHeight(0.01),
)
],
),
),
);
}
},
),
));
}
}
Usually when i'm dealing with retrieving and sending data to the database I create a new thread to do the job of transferring data, if you are transferring with the main thread it's not recommended to do that the program could crash.
There is a way to see the performance of the app:
Profile your app performance
Another reason to be lagging could be:
Style of coding won't slow your program down. However, an inefficient
algorithm will. – Learning Mathematics 8 hours ago
another reason could be the version of the Android you are using to operate in the app some View object has specific limitations depending of the version of the Android.

Flutter Error Message Bottom overloaded by 45 pixels

I want to create a login screen using Flutter.
This is my code so far:
Future showInformationDialog(BuildContext context) {
TextEditingController name = TextEditingController();
TextEditingController deadline = TextEditingController();
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Form(
child: Column(
children: <Widget>[
TextFormField(
controller: name,
maxLength: 40,
textAlign: TextAlign.left,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: InputDecoration(
labelText: 'Name der Klausur: ',
border: OutlineInputBorder(),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Gib den Namen der Klausur ein!';
}
return null;
},
),
SizedBox(height: 20),
TextFormField(
controller: deadline,
maxLength: 8,
textAlign: TextAlign.left,
keyboardType: TextInputType.datetime,
autocorrect: false,
decoration: InputDecoration(
labelText: 'Deadline: ',
border: OutlineInputBorder(),
),
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Gib das Datum der Klausur ein!';
}
return null;
},
),
SizedBox(height: 20),
DropDownFormField(
titleText: 'Priorität',
hintText: 'Bitte auswählen',
value: '',
dataSource: [
{
"display": "Niedrig",
"value": "Niedrig",
},
{
"display": "Mittel",
"value": "Mittel",
},
{
"display": "Hoch",
"value": "Hoch",
},
],
textField: 'display',
valueField: 'value',
),
SizedBox(height: 20),
],
),
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(name.text),
);
}
);
},
child: Text('Save'),
color: Colors.blue,
),
FlatButton(
onPressed: () {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(deadline.text),
);
}
);
},
child: Text('Save'),
color: Colors.blue,
),
],
);
});
}
When the keyboard opens, it collides with the textfields -> I get an error:
Bottom overflowed by 49 pixels.
What could be the issue?
I have tried everything but I got stuck here.
SingleChildScrollView or resizeToAvoidBottomPadding: false didnt help me. Maybe I don't know how to use them correctly.
For any help I would be happy.
Is it me, or can't I find the code for your login screen? The error is thrown because there isn't enough place for your widget on the screen. Are you using a ListView or a Column? With a ListView you can scroll so if there isn't enough room for the content the user can scroll down to see what isn't on the screen.

Flutter layout issue about Flexible

I am developing a flutter app, but it show error when I run the app.
I don't understand what is the problem. I think I mix up the logic of how the widget expand in layout.
Please kindly help to solve this issue.
error message:
flutter: The following assertion was thrown during performResize():
flutter: Vertical viewport was given unbounded height.
Viewports expand in the scrolling direction to fill their container.In this case, a vertical
viewport was given an unlimited amount of vertical space in which to expand. This situation
typically happens when a scrollable widget is nested inside another scrollable widget.
Here with my code:
body: Container(
child: Flexible(
child: FirebaseAnimatedList(
query: databaseReference,
itemBuilder: (_, DataSnapshot snapshot,
Animation<double> animation,
int index) {
return new Card(
color: Colors.black38,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ListTile(
leading: IconButton(
icon: Icon(Icons.format_list_bulleted),
color: Colors.blueAccent,
splashColor: Colors.greenAccent,
onPressed: () {
// Perform some action
debugPrint('button ok');
},
),
title: Text(shopList[index].shopName),
subtitle: Text(shopList[index].address),
),
Container(
child: Flexible(
child: Form(
key: formShopKey,
child: ListView(
children: <Widget>[
ListTile(
leading: Icon(
Icons.money_off,
color: Colors.white,
),
title: TextFormField(
maxLength: 100,
initialValue: "",
maxLines: 3,
//onSaved: (val) => booking.seafoodRequest = val,
//validator: (val) => val == "" ? val : null,
decoration: new InputDecoration(
),
),
),
],
),
),
),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: new ButtonBar(
children: <Widget>[
new FlatButton(
child: const Text('BUY TICKETS'),
onPressed: () {
/* ... */
},
),
new FlatButton(
child: const Text('LISTEN'),
onPressed: () {
/* ... */
},
),
],
),
),
],
),
);
},
),
),
);
[1]: https://i.stack.imgur.com/5vAsv.png
[2]: https://i.stack.imgur.com/LuZEl.png
I had to fill in a few gaps but the below should build for you. I also swapped FirebaseAnimatedList with a regular AnimatedList to get it to build. You can compare and adjust the layout.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: AnimatedList(
initialItemCount: 10,
itemBuilder: (BuildContext context, int index,
Animation<double> animation) {
return new Card(
color: Colors.black38,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ListTile(
leading: IconButton(
icon: Icon(Icons.format_list_bulleted),
color: Colors.blueAccent,
splashColor: Colors.greenAccent,
onPressed: () {
// Perform some action
debugPrint('button ok');
},
),
title: Text('Name'),
subtitle: Text('Address'),
),
Container(
constraints: BoxConstraints(
minHeight: 100.0,
maxHeight: 200.0,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Form(
child: ListView(
children: <Widget>[
ListTile(
leading: Icon(
Icons.money_off,
color: Colors.white,
),
title: TextFormField(
maxLength: 100,
initialValue: "",
maxLines: 3,
//onSaved: (val) => booking.seafoodRequest = val,
//validator: (val) => val == "" ? val : null,
decoration: new InputDecoration(),
),
),
],
),
),
),
],
),
),
ButtonTheme.bar(
// make buttons use the appropriate styles for cards
child: new ButtonBar(
children: <Widget>[
new FlatButton(
child: const Text('BUY TICKETS'),
onPressed: () {
/* ... */
},
),
new FlatButton(
child: const Text('LISTEN'),
onPressed: () {
/* ... */
},
),
],
),
),
],
),
);
},
),
),
],
),
);
}
}

Resources